diff options
author | Nikos Mavrogiannopoulos <nmav@crystal.(none)> | 2008-05-17 19:58:29 +0300 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@crystal.(none)> | 2008-05-17 19:58:29 +0300 |
commit | 1539fa9db4cb3cd193c236d535009449117adbb6 (patch) | |
tree | 24839593de5c15cffd4cf8b6523f01a8e0dab18d | |
parent | 77c732aa46fb8c868e38b55519738c0ce2173e56 (diff) | |
download | gnutls-1539fa9db4cb3cd193c236d535009449117adbb6.tar.gz |
converted hash functions to gnutls functions.
-rw-r--r-- | lib/opencdk/Makefile.am | 2 | ||||
-rw-r--r-- | lib/opencdk/armor.c | 4 | ||||
-rw-r--r-- | lib/opencdk/dummy.c | 2 | ||||
-rw-r--r-- | lib/opencdk/filters.h | 8 | ||||
-rw-r--r-- | lib/opencdk/hash.c | 18 | ||||
-rw-r--r-- | lib/opencdk/kbnode.c | 2 | ||||
-rw-r--r-- | lib/opencdk/literal.c | 4 | ||||
-rw-r--r-- | lib/opencdk/main.c | 6 | ||||
-rw-r--r-- | lib/opencdk/main.h | 20 | ||||
-rw-r--r-- | lib/opencdk/misc.c | 12 | ||||
-rw-r--r-- | lib/opencdk/opencdk.h | 9 | ||||
-rw-r--r-- | lib/opencdk/pubkey.c | 116 | ||||
-rw-r--r-- | lib/opencdk/seskey.c | 640 | ||||
-rw-r--r-- | lib/opencdk/sig-check.c | 99 | ||||
-rw-r--r-- | lib/opencdk/stream.c | 2 | ||||
-rw-r--r-- | lib/opencdk/verify.c | 32 |
16 files changed, 495 insertions, 481 deletions
diff --git a/lib/opencdk/Makefile.am b/lib/opencdk/Makefile.am index a612c101bb..ae04f7c184 100644 --- a/lib/opencdk/Makefile.am +++ b/lib/opencdk/Makefile.am @@ -20,7 +20,7 @@ # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA -INCLUDES = -I$(top_srcdir)/lib \ +INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/includes \ -I$(top_srcdir)/lgl -I$(top_builddir)/lgl noinst_LTLIBRARIES = libminiopencdk.la diff --git a/lib/opencdk/armor.c b/lib/opencdk/armor.c index 2a81542dfe..dc64dec87d 100644 --- a/lib/opencdk/armor.c +++ b/lib/opencdk/armor.c @@ -320,8 +320,8 @@ armor_encode (void *opaque, FILE *in, FILE *out) if (!afx) return CDK_Inv_Value; - if (afx->idx < 0 || afx->idx > DIM (armor_begin) || - afx->idx2 < 0 || afx->idx2 > DIM (armor_end)) + if (afx->idx < 0 || afx->idx > (int)DIM (armor_begin) || + afx->idx2 < 0 || afx->idx2 > (int)DIM (armor_end)) return CDK_Inv_Value; _cdk_log_debug ("armor filter: encode\n"); diff --git a/lib/opencdk/dummy.c b/lib/opencdk/dummy.c index e21e927d43..4fd2596cc3 100644 --- a/lib/opencdk/dummy.c +++ b/lib/opencdk/dummy.c @@ -9,7 +9,7 @@ cdk_error_t _cdk_proc_packets (cdk_ctx_t hd, cdk_stream_t inp, cdk_stream_t data, const char *output, cdk_stream_t outstream, - gcry_md_hd_t md) + digest_hd_st* md) { return 0; } diff --git a/lib/opencdk/filters.h b/lib/opencdk/filters.h index ebbb4afb27..229bbe91e3 100644 --- a/lib/opencdk/filters.h +++ b/lib/opencdk/filters.h @@ -32,7 +32,7 @@ enum { typedef struct { gcry_cipher_hd_t hd; - gcry_md_hd_t mdc; + digest_hd_st mdc; int mdc_method; cdk_dek_t dek; u32 datalen; @@ -46,7 +46,8 @@ typedef struct { typedef struct { int digest_algo; - gcry_md_hd_t md; + digest_hd_st md; + int md_initialized; } md_filter_t; typedef struct { @@ -61,7 +62,8 @@ typedef struct { cdk_lit_format_t mode; char *orig_filename; /* This original name of the input file. */ char *filename; - gcry_md_hd_t md; + digest_hd_st md; + int md_initialized; struct { size_t on; off_t size; diff --git a/lib/opencdk/hash.c b/lib/opencdk/hash.c index 4a18b8600e..a5c5dc05a8 100644 --- a/lib/opencdk/hash.c +++ b/lib/opencdk/hash.c @@ -37,7 +37,7 @@ hash_encode (void *opaque, FILE *in, FILE *out) { md_filter_t *mfx = opaque; byte buf[BUFSIZE]; - gcry_error_t err; + int err; int nread; if (!mfx) @@ -45,11 +45,13 @@ hash_encode (void *opaque, FILE *in, FILE *out) _cdk_log_debug ("hash filter: encode algo=%d\n", mfx->digest_algo); - if (!mfx->md) + if (!mfx->md_initialized) { - err = gcry_md_open (&mfx->md, mfx->digest_algo, 0); - if (err) - return map_gcry_error (err); + err = _gnutls_hash_init (&mfx->md, mfx->digest_algo); + if (err < 0) + return map_gnutls_error (err); + + mfx->md_initialized = 1; } while (!feof (in)) @@ -57,7 +59,7 @@ hash_encode (void *opaque, FILE *in, FILE *out) nread = fread (buf, 1, BUFSIZE, in); if (!nread) break; - gcry_md_write (mfx->md, buf, nread); + _gnutls_hash (&mfx->md, buf, nread); } wipemem (buf, sizeof (buf)); @@ -75,8 +77,8 @@ _cdk_filter_hash (void *opaque, int ctl, FILE *in, FILE *out) if (mfx) { _cdk_log_debug ("free hash filter\n"); - gcry_md_close (mfx->md); - mfx->md = NULL; + _gnutls_hash_deinit (&mfx->md, NULL); + mfx->md_initialized = 0; return 0; } } diff --git a/lib/opencdk/kbnode.c b/lib/opencdk/kbnode.c index 9502d75a69..5ba928444a 100644 --- a/lib/opencdk/kbnode.c +++ b/lib/opencdk/kbnode.c @@ -559,7 +559,7 @@ cdk_kbnode_write_to_mem (cdk_kbnode_t node, byte *buf, size_t *r_nbytes) * is extracted from it. **/ cdk_error_t -cdk_kbnode_hash (cdk_kbnode_t node, gcry_md_hd_t md, int is_v4, +cdk_kbnode_hash (cdk_kbnode_t node, digest_hd_st* md, int is_v4, cdk_packet_type_t pkttype, int flags) { cdk_packet_t pkt; diff --git a/lib/opencdk/literal.c b/lib/opencdk/literal.c index d94bc3a8a3..7a0a43453b 100644 --- a/lib/opencdk/literal.c +++ b/lib/opencdk/literal.c @@ -131,8 +131,8 @@ literal_decode (void *opaque, FILE *in, FILE *out) rc = CDK_File_Error; break; } - if (pfx->md) - gcry_md_write (pfx->md, buf, nread); + if (pfx->md_initialized) + _gnutls_hash (&pfx->md, buf, nread); cdk_stream_write (so, buf, nread); pt->len -= nread; if (pfx->blkmode.on) diff --git a/lib/opencdk/main.c b/lib/opencdk/main.c index 68c5c94e18..f810026162 100644 --- a/lib/opencdk/main.c +++ b/lib/opencdk/main.c @@ -42,7 +42,7 @@ Even if AES and SHA-256 are not 'MUST' in the latest OpenPGP draft, AES seems to be a good choice. */ #define DEFAULT_CIPHER_ALGO GCRY_CIPHER_AES -#define DEFAULT_DIGEST_ALGO GCRY_MD_SHA256 +#define DEFAULT_DIGEST_ALGO GNUTLS_DIG_SHA256 /** * cdk_strerror: @@ -118,7 +118,7 @@ handle_set_digest (cdk_ctx_t hd, int digest) { if (!hd) return; - if (gcry_md_test_algo (digest)) + if (_gnutls_hash_get_algo_len (digest) <= 0) digest = DEFAULT_DIGEST_ALGO; hd->digest_algo = digest; } @@ -131,7 +131,7 @@ handle_set_s2k (cdk_ctx_t hd, int mode, int digest, int cipher) return; if (gcry_cipher_test_algo (cipher)) cipher = DEFAULT_CIPHER_ALGO; - if (gcry_md_test_algo (digest)) + if (_gnutls_hash_get_algo_len (digest) <= 0) digest = DEFAULT_DIGEST_ALGO; if (mode != CDK_S2K_SIMPLE && mode != CDK_S2K_SALTED && diff --git a/lib/opencdk/main.h b/lib/opencdk/main.h index 5671be23b4..b94fcc1ef6 100644 --- a/lib/opencdk/main.h +++ b/lib/opencdk/main.h @@ -27,10 +27,6 @@ #include <gcrypt.h> #include "types.h" -#include <gnutls_mem.h> -#include <gnutls/gnutls.h> -#include <gnutls_errors.h> - #define _cdk_log_debug _gnutls_debug_log #define _cdk_log_info _gnutls_x509_log #define _cdk_get_log_level() _gnutls_log_level @@ -42,6 +38,10 @@ #define cdk_strdup gnutls_strdup #define cdk_salloc gnutls_secure_calloc +#define map_gnutls_error _cdk_map_gnutls_error + +cdk_error_t map_gnutls_error(int err); + /* The general size of a buffer for the variou modules. */ #define BUFSIZE 8192 @@ -110,7 +110,7 @@ cdk_error_t _cdk_map_gcry_error (gcry_error_t err); cdk_error_t _cdk_proc_packets (cdk_ctx_t hd, cdk_stream_t inp, cdk_stream_t data, const char *output, cdk_stream_t outstream, - gcry_md_hd_t md); + digest_hd_st*md); cdk_error_t _cdk_pkt_write2 (cdk_stream_t out, int pkttype, void *pktctx); /*-- pubkey.c --*/ @@ -127,10 +127,10 @@ void _cdk_pkt_detach_free (cdk_packet_t pkt, int *r_pkttype, void **ctx); /*-- sig-check.c --*/ cdk_error_t _cdk_sig_check (cdk_pkt_pubkey_t pk, cdk_pkt_signature_t sig, - gcry_md_hd_t digest, int * r_expired); -cdk_error_t _cdk_hash_sig_data (cdk_pkt_signature_t sig, gcry_md_hd_t hd); -cdk_error_t _cdk_hash_userid (cdk_pkt_userid_t uid, int sig_version, gcry_md_hd_t md); -cdk_error_t _cdk_hash_pubkey (cdk_pkt_pubkey_t pk, gcry_md_hd_t md, + digest_hd_st*digest, int * r_expired); +cdk_error_t _cdk_hash_sig_data (cdk_pkt_signature_t sig, digest_hd_st*hd); +cdk_error_t _cdk_hash_userid (cdk_pkt_userid_t uid, int sig_version, digest_hd_st*md); +cdk_error_t _cdk_hash_pubkey (cdk_pkt_pubkey_t pk, digest_hd_st *md, int use_fpr); cdk_error_t _cdk_pk_check_sig (cdk_keydb_hd_t hd, cdk_kbnode_t knode, @@ -161,7 +161,7 @@ int _cdk_sig_hash_for (cdk_pkt_pubkey_t pk); void _cdk_trim_string (char * s, int canon); cdk_error_t _cdk_sig_create (cdk_pkt_pubkey_t pk, cdk_pkt_signature_t sig); cdk_error_t _cdk_sig_complete (cdk_pkt_signature_t sig, cdk_pkt_seckey_t sk, - gcry_md_hd_t hd); + digest_hd_st *hd); /*-- stream.c --*/ void _cdk_stream_set_compress_algo (cdk_stream_t s, int algo); diff --git a/lib/opencdk/misc.c b/lib/opencdk/misc.c index 97302475a7..fbe1a34fbd 100644 --- a/lib/opencdk/misc.c +++ b/lib/opencdk/misc.c @@ -174,6 +174,18 @@ _cdk_map_gcry_error (gcry_error_t err) return (cdk_error_t)err; } +cdk_error_t +_cdk_map_gnutls_error (int err) +{ + switch (err) + { + case 0: return CDK_Success; + case GNUTLS_E_INVALID_REQUEST: return CDK_Inv_Value; + default: + return CDK_General_Error; + } +} + /* Remove all trailing white spaces from the string. */ void diff --git a/lib/opencdk/opencdk.h b/lib/opencdk/opencdk.h index dded5f20f1..4e798f51f9 100644 --- a/lib/opencdk/opencdk.h +++ b/lib/opencdk/opencdk.h @@ -28,6 +28,11 @@ #include <stddef.h> /* for size_t */ #include <stdarg.h> #include <gcrypt.h> +#include <gnutls_int.h> +#include <gnutls_mem.h> +#include <gnutls/gnutls.h> +#include <gnutls_errors.h> +#include <gnutls_hash_int.h> /* The OpenCDK version as a string. */ #define OPENCDK_VERSION "0.6.6" @@ -1004,7 +1009,7 @@ cdk_kbnode_t cdk_kbnode_find (cdk_kbnode_t node, cdk_packet_type_t pkttype); cdk_kbnode_t cdk_kbnode_find_prev (cdk_kbnode_t root, cdk_kbnode_t node, cdk_packet_type_t pkttype); cdk_kbnode_t cdk_kbnode_find_next (cdk_kbnode_t node, cdk_packet_type_t pkttype); -cdk_error_t cdk_kbnode_hash (cdk_kbnode_t node, gcry_md_hd_t md, int is_v4, +cdk_error_t cdk_kbnode_hash (cdk_kbnode_t node, digest_hd_st* md, int is_v4, cdk_packet_type_t pkttype, int flags); /* Check each signature in the key node and return a summary of the @@ -1038,7 +1043,7 @@ cdk_error_t cdk_sklist_build (cdk_keylist_t * ret_skl, int unlock, unsigned int use); void cdk_sklist_release (cdk_keylist_t skl); cdk_error_t cdk_sklist_write (cdk_keylist_t skl, cdk_stream_t outp, - gcry_md_hd_t mdctx, + digest_hd_st* mdctx, int sigclass, int sigver); cdk_error_t cdk_sklist_write_onepass (cdk_keylist_t skl, cdk_stream_t outp, int sigclass, int mdalgo); diff --git a/lib/opencdk/pubkey.c b/lib/opencdk/pubkey.c index 58d5c2fb25..8d4b5a906d 100644 --- a/lib/opencdk/pubkey.c +++ b/lib/opencdk/pubkey.c @@ -142,7 +142,7 @@ digest_to_sexp (gcry_sexp_t *r_md_sexp, int digest_algo, return CDK_Inv_Value; if (!mdlen) - mdlen = gcry_md_get_algo_dlen (digest_algo); + mdlen = _gnutls_hash_get_algo_len (digest_algo); if (!mdlen) return CDK_Inv_Algo; @@ -761,7 +761,7 @@ cdk_sk_unprotect (cdk_pkt_seckey_t sk, const char *pw) with the key as used by the Klima/Rosa attack */ sk->csum = 0; chksum = 1; - dlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1); + dlen = _gnutls_hash_get_algo_len (GNUTLS_DIG_SHA1); if (ndata < dlen) { cdk_free (data); @@ -770,9 +770,19 @@ cdk_sk_unprotect (cdk_pkt_seckey_t sk, const char *pw) else { byte mdcheck[20]; + digest_hd_st md; + int err; - gcry_md_hash_buffer (GCRY_MD_SHA1, - mdcheck, data, ndata-dlen); + err = _gnutls_hash_init( &md, GNUTLS_DIG_SHA1); + if (err < 0) + { + cdk_free (data); + return CDK_Inv_Packet; + } + + _gnutls_hash( &md, data, ndata-dlen); + _gnutls_hash_deinit( &md, mdcheck); + if (!memcmp (mdcheck, data + ndata - dlen, dlen)) chksum = 0; /* Digest does match */ } @@ -842,10 +852,11 @@ cdk_sk_protect (cdk_pkt_seckey_t sk, const char *pw) gcry_cipher_hd_t hd = NULL; cdk_dek_t dek = NULL; cdk_s2k_t s2k; + digest_hd_st md; byte *p = NULL, buf[MAX_MPI_BYTES+2]; size_t enclen = 0, nskey, i, nbytes; - size_t dlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1); - gcry_error_t err; + size_t dlen = _gnutls_hash_get_algo_len (GNUTLS_DIG_SHA1); + int err; cdk_error_t rc; nskey = cdk_pk_get_nskey (sk->pubkey_algo); @@ -915,8 +926,17 @@ cdk_sk_protect (cdk_pkt_seckey_t sk, const char *pw) sk->protect.sha1chk = 1; sk->is_protected = 1; sk->csum = 0; - - gcry_md_hash_buffer (GCRY_MD_SHA1, buf, p, enclen-dlen); + + err = _gnutls_hash_init( &md, GNUTLS_DIG_SHA1); + if (err < 0) + { + rc = map_gnutls_error(err); + goto leave; + } + + _gnutls_hash( &md, p, enclen-dlen); + _gnutls_hash_deinit( &md, buf); + memcpy (p + enclen - dlen, buf, dlen); gcry_cipher_encrypt (hd, p, enclen, NULL, 0); @@ -944,64 +964,6 @@ cdk_pk_from_secret_key (cdk_pkt_seckey_t sk, cdk_pubkey_t *ret_pk) } -#if 0 /* FIXME: Code is not finished yet. */ -cdk_error_t -cdk_pk_revoke_cert_create (cdk_pkt_seckey_t sk, int code, const char *inf, - char **ret_revcert) -{ - gcry_md_hd_t md; - cdk_subpkt_t node; - cdk_pkt_signature_t sig; - char *p = NULL, *dat; - gcry_error_t err; - cdk_error_t rc = 0; - size_t n; - - if (!sk || !ret_revcert) - return CDK_Inv_Value; - if(code < 0 || code > 3) - return CDK_Inv_Value; - - sig = cdk_calloc (1, sizeof *sig); - if (!sig) - return CDK_Out_Of_Core; - _cdk_sig_create (sk->pk, sig); - n = 1; - if (inf) - { - n += strlen (p); - p = cdk_utf8_encode (inf); - } - dat = cdk_calloc (1, n+1); - if (!dat) - { - _cdk_free_signature (sig); - return CDK_Out_Of_Core; - } - dat[0] = code; - if (inf) - memcpy (dat+1, p, strlen (p)); - cdk_free (p); - - node = cdk_subpkt_new (n); - if (node) - { - cdk_subpkt_init (node, CDK_SIGSUBPKT_REVOC_REASON, dat, n); - cdk_subpkt_add (sig->hashed, node); - } - cdk_free (dat); - - err = gcry_md_open (&md, GCRY_MD_SHA1, 0); - if (err) - rc = map_gcry_error (err); - else - _cdk_hash_pubkey (sk->pk, md, 0); - _cdk_free_signature (sig); - - return rc; -} -#endif - int _cdk_sk_get_csum (cdk_pkt_seckey_t sk) { @@ -1029,26 +991,24 @@ _cdk_sk_get_csum (cdk_pkt_seckey_t sk) cdk_error_t cdk_pk_get_fingerprint (cdk_pubkey_t pk, byte *fpr) { - gcry_md_hd_t hd; + digest_hd_st hd; int md_algo; int dlen = 0; - gcry_error_t err; + int err; if (!pk || !fpr) return CDK_Inv_Value; if (pk->version < 4 && is_RSA (pk->pubkey_algo)) - md_algo = GCRY_MD_MD5; /* special */ + md_algo = GNUTLS_DIG_MD5; /* special */ else - md_algo = GCRY_MD_SHA1; - dlen = gcry_md_get_algo_dlen (md_algo); - err = gcry_md_open (&hd, md_algo, 0); - if (err) - return map_gcry_error (err); - _cdk_hash_pubkey (pk, hd, 1); - gcry_md_final (hd); - memcpy (fpr, gcry_md_read (hd, md_algo), dlen); - gcry_md_close (hd); + md_algo = GNUTLS_DIG_SHA1; + dlen = _gnutls_hash_get_algo_len (md_algo); + err = _gnutls_hash_init (&hd, md_algo); + if (err < 0) + return map_gnutls_error (err); + _cdk_hash_pubkey (pk, &hd, 1); + _gnutls_hash_deinit( &hd, fpr); if (dlen == 16) memset (fpr + 16, 0, 4); return 0; diff --git a/lib/opencdk/seskey.c b/lib/opencdk/seskey.c index 94bef3223c..a5317bb127 100644 --- a/lib/opencdk/seskey.c +++ b/lib/opencdk/seskey.c @@ -40,8 +40,8 @@ * PAD consists of FF bytes. */ static cdk_error_t -do_encode_md (byte **r_frame, size_t *r_flen, const byte *md, int algo, - size_t len, unsigned nbits, const byte *asn, size_t asnlen) +do_encode_md(byte ** r_frame, size_t * r_flen, const byte * md, int algo, + size_t len, unsigned nbits, const byte * asn, size_t asnlen) { byte *frame = NULL; size_t nframe = (nbits + 7) / 8; @@ -50,33 +50,31 @@ do_encode_md (byte **r_frame, size_t *r_flen, const byte *md, int algo, if (!asn || !md || !r_frame || !r_flen) return CDK_Inv_Value; - + if (len + asnlen + 4 > nframe) return CDK_General_Error; - - frame = cdk_calloc (1, nframe); + + frame = cdk_calloc(1, nframe); if (!frame) return CDK_Out_Of_Core; frame[n++] = 0; frame[n++] = 1; i = nframe - len - asnlen - 3; - if (i < 0) - { - cdk_free (frame); - return CDK_Inv_Value; - } - memset (frame + n, 0xFF, i); + if (i < 0) { + cdk_free(frame); + return CDK_Inv_Value; + } + memset(frame + n, 0xFF, i); n += i; frame[n++] = 0; - memcpy (frame + n, asn, asnlen); + memcpy(frame + n, asn, asnlen); n += asnlen; - memcpy (frame + n, md, len); + memcpy(frame + n, md, len); n += len; - if (n != nframe) - { - cdk_free (frame); - return CDK_Inv_Value; - } + if (n != nframe) { + cdk_free(frame); + return CDK_Inv_Value; + } *r_frame = frame; *r_flen = n; return 0; @@ -104,7 +102,7 @@ do_encode_md (byte **r_frame, size_t *r_flen, const byte *md, int algo, * into a multiprecision integer. **/ cdk_error_t -cdk_dek_encode_pkcs1 (cdk_dek_t dek, size_t nbits, gcry_mpi_t *r_enc) +cdk_dek_encode_pkcs1(cdk_dek_t dek, size_t nbits, gcry_mpi_t * r_enc) { gcry_mpi_t a = NULL; gcry_error_t err; @@ -113,59 +111,56 @@ cdk_dek_encode_pkcs1 (cdk_dek_t dek, size_t nbits, gcry_mpi_t *r_enc) size_t nframe; size_t i; u16 chksum; - + if (!r_enc || !dek) return CDK_Inv_Value; - + *r_enc = NULL; chksum = 0; - for (i = 0; i < (size_t)dek->keylen; i++) + for (i = 0; i < (size_t) dek->keylen; i++) chksum += dek->key[i]; nframe = (nbits + 7) / 8; - frame = cdk_salloc (nframe + 1, 1); + frame = cdk_salloc(nframe + 1, 1); if (!frame) return CDK_Out_Of_Core; n = 0; frame[n++] = 0x00; frame[n++] = 0x02; i = nframe - 6 - dek->keylen; - p = gcry_random_bytes (i, GCRY_STRONG_RANDOM); + p = gcry_random_bytes(i, GCRY_STRONG_RANDOM); /* Replace zero bytes by new values */ - for (;;) - { - size_t j, k; - byte *pp; - - /* count the zero bytes */ - for (j = k = 0; j < i; j++) - { - if (!p[j]) - k++; - } - if (!k) - break; /* No zeroes remain. */ - k += k / 128; /* better get some more */ - pp = gcry_random_bytes (k, GCRY_STRONG_RANDOM); - for (j = 0; j < i && k; j++) - { - if (!p[j]) - p[j] = pp[--k]; - } - cdk_free (pp); + for (;;) { + size_t j, k; + byte *pp; + + /* count the zero bytes */ + for (j = k = 0; j < i; j++) { + if (!p[j]) + k++; } - memcpy (frame + n, p, i); - cdk_free (p); + if (!k) + break; /* No zeroes remain. */ + k += k / 128; /* better get some more */ + pp = gcry_random_bytes(k, GCRY_STRONG_RANDOM); + for (j = 0; j < i && k; j++) { + if (!p[j]) + p[j] = pp[--k]; + } + cdk_free(pp); + } + memcpy(frame + n, p, i); + cdk_free(p); n += i; frame[n++] = 0; frame[n++] = dek->algo; - memcpy (frame + n, dek->key, dek->keylen); + memcpy(frame + n, dek->key, dek->keylen); n += dek->keylen; frame[n++] = chksum >> 8; frame[n++] = chksum; - err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, nframe, &nframe); - cdk_free (frame); + err = gcry_mpi_scan(&a, GCRYMPI_FMT_USG, frame, nframe, &nframe); + cdk_free(frame); if (err) - return map_gcry_error (err); + return map_gcry_error(err); *r_enc = a; return 0; } @@ -179,27 +174,26 @@ cdk_dek_encode_pkcs1 (cdk_dek_t dek, size_t nbits, gcry_mpi_t *r_enc) * Decode the given multi precision integer in pkcs#1 and * store it into the DEK object. **/ -cdk_error_t -cdk_dek_decode_pkcs1 (cdk_dek_t *ret_dek, gcry_mpi_t esk) +cdk_error_t cdk_dek_decode_pkcs1(cdk_dek_t * ret_dek, gcry_mpi_t esk) { cdk_dek_t dek; - byte frame[MAX_MPI_BYTES+2+1]; + byte frame[MAX_MPI_BYTES + 2 + 1]; size_t nframe, n; u16 csum, csum2; gcry_error_t err; - + if (!ret_dek || !esk) return CDK_Inv_Value; - - *ret_dek = NULL; /* reset */ - nframe = DIM (frame)-1; - err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, esk); + + *ret_dek = NULL; /* reset */ + nframe = DIM(frame) - 1; + err = gcry_mpi_print(GCRYMPI_FMT_USG, frame, nframe, &nframe, esk); if (err) - return map_gcry_error (err); - dek = cdk_salloc (sizeof *dek, 1); + return map_gcry_error(err); + dek = cdk_salloc(sizeof *dek, 1); if (!dek) return CDK_Out_Of_Core; - + /* Now get the DEK (data encryption key) from the frame * * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) @@ -212,111 +206,166 @@ cdk_dek_decode_pkcs1 (cdk_dek_t *ret_dek, gcry_mpi_t esk) * CSUM */ n = 0; - if (frame[n] != 2) - { - cdk_free (dek); - return CDK_Inv_Mode; - } - for (n++; n < nframe && frame[n]; n++) - ; + if (frame[n] != 2) { + cdk_free(dek); + return CDK_Inv_Mode; + } + for (n++; n < nframe && frame[n]; n++); n++; dek->keylen = nframe - (n + 1) - 2; dek->algo = frame[n++]; - if (dek->keylen != gcry_cipher_get_algo_keylen (dek->algo)) - { - _cdk_log_debug ("pkcs1 decode: invalid cipher keylen %d\n", dek->keylen); - cdk_free (dek); - return CDK_Inv_Algo; - } - csum = frame[nframe-2] << 8; - csum |= frame[nframe-1]; - memcpy (dek->key, frame + n, dek->keylen); + if (dek->keylen != gcry_cipher_get_algo_keylen(dek->algo)) { + _cdk_log_debug("pkcs1 decode: invalid cipher keylen %d\n", + dek->keylen); + cdk_free(dek); + return CDK_Inv_Algo; + } + csum = frame[nframe - 2] << 8; + csum |= frame[nframe - 1]; + memcpy(dek->key, frame + n, dek->keylen); csum2 = 0; for (n = 0; n < dek->keylen; n++) csum2 += dek->key[n]; - if (csum != csum2) - { - _cdk_log_debug ("pkcs decode: checksum does not match\n"); - cdk_free (dek); - return CDK_Chksum_Error; - } + if (csum != csum2) { + _cdk_log_debug("pkcs decode: checksum does not match\n"); + cdk_free(dek); + return CDK_Chksum_Error; + } *ret_dek = dek; return 0; } +static const byte md5_asn[18] = /* Object ID is 1.2.840.113549.2.5 */ +{ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 +}; + +static const byte sha1_asn[15] = /* Object ID is 1.3.14.3.2.26 */ +{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, + 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 +}; + +static const byte sha224_asn[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */ +{ 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, + 0x1C +}; + +static const byte sha256_asn[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */ +{ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, + 0x00, 0x04, 0x20 +}; + +static const byte sha512_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */ +{ + 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, + 0x00, 0x04, 0x40 +}; + +static const byte sha384_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */ +{ + 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, + 0x00, 0x04, 0x30 +}; + +static const byte rmd160_asn[15] = /* Object ID is 1.3.36.3.2.1 */ +{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, + 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 +}; + +static int _gnutls_get_digest_oid(gnutls_digest_algorithm_t algo, const byte** data) +{ + switch (algo) { + case GNUTLS_DIG_MD5: + *data = md5_asn; + return sizeof(md5_asn); + case GNUTLS_DIG_SHA1: + *data = sha1_asn; + return sizeof(sha1_asn); + case GNUTLS_DIG_RMD160: + *data = rmd160_asn; + return sizeof(rmd160_asn); + case GNUTLS_DIG_SHA256: + *data = sha256_asn; + return sizeof(sha256_asn); + case GNUTLS_DIG_SHA384: + *data = sha384_asn; + return sizeof(sha384_asn); + case GNUTLS_DIG_SHA512: + *data = sha512_asn; + return sizeof(sha512_asn); + case GNUTLS_DIG_SHA224: + *data = sha224_asn; + return sizeof(sha224_asn); + default: + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } +} + /* Encode the given digest into a pkcs#1 compatible format. */ cdk_error_t -_cdk_digest_encode_pkcs1 (byte **r_md, size_t *r_mdlen, int pk_algo, - const byte *md, int digest_algo, unsigned nbits) +_cdk_digest_encode_pkcs1(byte ** r_md, size_t * r_mdlen, int pk_algo, + const byte * md, int digest_algo, unsigned nbits) { gcry_error_t err; size_t dlen; if (!md || !r_md || !r_mdlen) return CDK_Inv_Value; - - dlen = gcry_md_get_algo_dlen (digest_algo); - if (!dlen) + + dlen = _gnutls_hash_get_algo_len(digest_algo); + if (dlen <= 0) return CDK_Inv_Algo; - if (is_DSA (pk_algo)) /* DSS does not use a special encoding. */ - { - *r_md = cdk_malloc (dlen + 1); - if (!*r_md) - return CDK_Out_Of_Core; - *r_mdlen = dlen; - memcpy (*r_md, md, dlen); - return 0; - } - else - { - byte *asn; - size_t asnlen; - cdk_error_t rc; - - err = gcry_md_get_asnoid (digest_algo, NULL, &asnlen); - if (err) - return map_gcry_error (err); - asn = cdk_malloc (asnlen + 1); - if (!asn) - return CDK_Out_Of_Core; - err = gcry_md_get_asnoid (digest_algo, asn, &asnlen); - if (err) - { - cdk_free (asn); - return map_gcry_error (err); - } - rc = do_encode_md (r_md, r_mdlen, md, digest_algo, dlen, - nbits, asn, asnlen); - cdk_free (asn); - return rc; - } + if (is_DSA(pk_algo)) { /* DSS does not use a special encoding. */ + *r_md = cdk_malloc(dlen + 1); + if (!*r_md) + return CDK_Out_Of_Core; + *r_mdlen = dlen; + memcpy(*r_md, md, dlen); + return 0; + } else { + const byte *asn; + int asnlen; + cdk_error_t rc; + + asnlen = _gnutls_get_digest_oid( digest_algo, &asn); + if (asnlen < 0) + return asnlen; + + rc = do_encode_md(r_md, r_mdlen, md, digest_algo, dlen, + nbits, asn, asnlen); + return rc; + } return 0; } /* FIXME: The prompt should be provided in a more generic way. Like: (keyid, algorithm, [user-id]) */ -static char* -passphrase_prompt (cdk_pkt_seckey_t sk) +static char *passphrase_prompt(cdk_pkt_seckey_t sk) { - u32 keyid = cdk_pk_get_keyid (sk->pk, NULL); - int bits = cdk_pk_get_nbits (sk->pk), pk_algo = sk->pubkey_algo; + u32 keyid = cdk_pk_get_keyid(sk->pk, NULL); + int bits = cdk_pk_get_nbits(sk->pk), pk_algo = sk->pubkey_algo; const char *algo = "???", *fmt; char *p; - - if (is_RSA (pk_algo)) + + if (is_RSA(pk_algo)) algo = "RSA"; - else if (is_ELG (pk_algo)) + else if (is_ELG(pk_algo)) algo = "ELG"; - else if (is_DSA (pk_algo)) + else if (is_DSA(pk_algo)) algo = "DSA"; - + fmt = "%d-bit %s key, ID %08lX\nEnter Passphrase: "; - p = cdk_calloc (1, 64 + strlen (fmt) + strlen (algo) + 1); + p = cdk_calloc(1, 64 + strlen(fmt) + strlen(algo) + 1); if (!p) return NULL; - sprintf (p, fmt, bits, algo, keyid); + sprintf(p, fmt, bits, algo, keyid); return p; } @@ -324,25 +373,24 @@ passphrase_prompt (cdk_pkt_seckey_t sk) /* Try to unprotect the secret key, if needed, automatically. The passphrase callback is used to get the passphrase directly from the user. */ -cdk_error_t -_cdk_sk_unprotect_auto (cdk_ctx_t hd, cdk_pkt_seckey_t sk) +cdk_error_t _cdk_sk_unprotect_auto(cdk_ctx_t hd, cdk_pkt_seckey_t sk) { char *pw, *p; cdk_error_t rc; - + if (!sk->is_protected) return 0; - - p = passphrase_prompt (sk); - pw = _cdk_passphrase_get (hd, p); - cdk_free (p); + + p = passphrase_prompt(sk); + pw = _cdk_passphrase_get(hd, p); + cdk_free(p); if (!pw) return CDK_No_Passphrase; - - rc = cdk_sk_unprotect (sk, pw); - wipemem (pw, strlen (pw)); - cdk_free (pw); + rc = cdk_sk_unprotect(sk, pw); + + wipemem(pw, strlen(pw)); + cdk_free(pw); return rc; } @@ -357,8 +405,8 @@ _cdk_sk_unprotect_auto (cdk_ctx_t hd, cdk_pkt_seckey_t sk) * Try to extract the DEK from the public key encrypted packet. **/ cdk_error_t -cdk_dek_extract (cdk_dek_t *ret_dek, cdk_ctx_t hd, - cdk_pkt_pubkey_enc_t enc, cdk_pkt_seckey_t sk) +cdk_dek_extract(cdk_dek_t * ret_dek, cdk_ctx_t hd, + cdk_pkt_pubkey_enc_t enc, cdk_pkt_seckey_t sk) { gcry_mpi_t skey = NULL; cdk_dek_t dek; @@ -366,26 +414,24 @@ cdk_dek_extract (cdk_dek_t *ret_dek, cdk_ctx_t hd, if (!enc || !sk || !ret_dek) return CDK_Inv_Value; - - /* FIXME: it is not very elegant that we need the session handle here. */ - if (sk->is_protected) - { - rc = _cdk_sk_unprotect_auto (hd, sk); - if (rc) - return rc; - } - - rc = cdk_pk_decrypt (sk, enc, &skey); + + /* FIXME: it is not very elegant that we need the session handle here. */ + if (sk->is_protected) { + rc = _cdk_sk_unprotect_auto(hd, sk); + if (rc) + return rc; + } + + rc = cdk_pk_decrypt(sk, enc, &skey); if (rc) return rc; - - rc = cdk_dek_decode_pkcs1 (&dek, skey); - gcry_mpi_release (skey); - if (rc) - { - cdk_dek_free (dek); - dek = NULL; - } + + rc = cdk_dek_decode_pkcs1(&dek, skey); + gcry_mpi_release(skey); + if (rc) { + cdk_dek_free(dek); + dek = NULL; + } *ret_dek = dek; return rc; } @@ -397,15 +443,14 @@ cdk_dek_extract (cdk_dek_t *ret_dek, cdk_ctx_t hd, * * Create a new DEK object. **/ -cdk_error_t -cdk_dek_new (cdk_dek_t *r_dek) +cdk_error_t cdk_dek_new(cdk_dek_t * r_dek) { cdk_dek_t dek; - + if (!r_dek) return CDK_Inv_Value; *r_dek = NULL; - dek = cdk_salloc (sizeof *dek, 1); + dek = cdk_salloc(sizeof *dek, 1); if (!dek) return CDK_Out_Of_Core; *r_dek = dek; @@ -420,28 +465,26 @@ cdk_dek_new (cdk_dek_t *r_dek) * * Set the cipher for the given DEK object. **/ -cdk_error_t -cdk_dek_set_cipher (cdk_dek_t dek, int algo) +cdk_error_t cdk_dek_set_cipher(cdk_dek_t dek, int algo) { if (!dek) return CDK_Inv_Value; - + if (!algo) - algo = GCRY_CIPHER_AES128; - if (gcry_cipher_test_algo (algo)) + algo = GCRY_CIPHER_AES128; + if (gcry_cipher_test_algo(algo)) return CDK_Inv_Algo; dek->algo = algo; - dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); + dek->keylen = gcry_cipher_get_algo_keylen(dek->algo); return 0; } -cdk_error_t -cdk_dek_get_cipher (cdk_dek_t dek, int *r_algo) +cdk_error_t cdk_dek_get_cipher(cdk_dek_t dek, int *r_algo) { if (!dek || !r_algo) return CDK_Inv_Value; - - + + *r_algo = dek->algo; return 0; } @@ -457,45 +500,41 @@ cdk_dek_get_cipher (cdk_dek_t dek, int *r_algo) * If @key and @keylen is NULL (0) a random key will be generated. * In any case, cdk_dek_set_cipher must be called first. **/ -cdk_error_t -cdk_dek_set_key (cdk_dek_t dek, const byte *key, size_t keylen) +cdk_error_t cdk_dek_set_key(cdk_dek_t dek, const byte * key, size_t keylen) { gcry_cipher_hd_t hd; size_t i; - + if (!dek) - return CDK_Inv_Value; + return CDK_Inv_Value; /* The given key must be compatible with the symmetric cipher algorithm set before. */ if (keylen > 0 && keylen != dek->keylen) return CDK_Inv_Mode; - - if (!key && !keylen) - { - gcry_error_t err; - - /* Used to generate a random session key. The extra code is used - to detect weak keys, if they are possible at all. */ - err = gcry_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_ENABLE_SYNC); - if (err) - return map_gcry_error (err); - gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM); - for (i = 0; i < 8; i++) - { - if (!gcry_cipher_setkey (hd, dek->key, dek->keylen)) - { - gcry_cipher_close (hd); - return 0; - } - gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM); - } - gcry_cipher_close (hd); - return CDK_Weak_Key; + + if (!key && !keylen) { + gcry_error_t err; + + /* Used to generate a random session key. The extra code is used + to detect weak keys, if they are possible at all. */ + err = gcry_cipher_open(&hd, dek->algo, GCRY_CIPHER_MODE_CFB, + GCRY_CIPHER_ENABLE_SYNC); + if (err) + return map_gcry_error(err); + gcry_randomize(dek->key, dek->keylen, GCRY_STRONG_RANDOM); + for (i = 0; i < 8; i++) { + if (!gcry_cipher_setkey(hd, dek->key, dek->keylen)) { + gcry_cipher_close(hd); + return 0; + } + gcry_randomize(dek->key, dek->keylen, GCRY_STRONG_RANDOM); } - - memcpy (dek->key, key, dek->keylen); + gcry_cipher_close(hd); + return CDK_Weak_Key; + } + + memcpy(dek->key, key, dek->keylen); return 0; } @@ -507,114 +546,109 @@ cdk_dek_set_key (cdk_dek_t dek, const byte *key, size_t keylen) * * Enable or disable the MDC flag for the given DEK object. **/ -void -cdk_dek_set_mdc_flag (cdk_dek_t dek, int val) +void cdk_dek_set_mdc_flag(cdk_dek_t dek, int val) { if (dek) dek->use_mdc = val; } -int -cdk_dek_get_mdc_flag (cdk_dek_t dek) +int cdk_dek_get_mdc_flag(cdk_dek_t dek) { if (!dek) return 0; return dek->use_mdc; } - + /** * cdk_dek_free: * @dek: the DEK object * * Release the DEK object. **/ -void -cdk_dek_free (cdk_dek_t dek) +void cdk_dek_free(cdk_dek_t dek) { if (!dek) return; - + /* Make sure sentensive data is overwritten. */ - wipemem (dek->key, sizeof (dek->key)); - cdk_free (dek); + wipemem(dek->key, sizeof(dek->key)); + cdk_free(dek); } /* Hash the passphrase to produce the a DEK. If create is set, a random salt will be generated. */ static cdk_error_t -hash_passphrase (cdk_dek_t dek, const char *pw, cdk_s2k_t s2k, int create) +hash_passphrase(cdk_dek_t dek, const char *pw, cdk_s2k_t s2k, int create) { - gcry_md_hd_t md; - byte zero[1] = {0x00}; + digest_hd_st md; + byte zero[1] = { 0x00 }; int pass, i; int used = 0, pwlen; - gcry_error_t err; - + int err; + if (!dek || !pw || !s2k) return CDK_Inv_Value; - + if (!s2k->hash_algo) s2k->hash_algo = GCRY_MD_SHA1; - pwlen = strlen (pw); - - dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); - err = gcry_md_open (&md, s2k->hash_algo, 0); - if (err) - return map_gcry_error (err); - - for (pass = 0; used < dek->keylen; pass++) - { - if (pass) - { - gcry_md_reset (md); - for (i = 0; i < pass; i++) /* preset the hash context */ - gcry_md_write (md, zero, 1); - } - if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED) - { - int len2 = pwlen + 8; - u32 count = len2; - if (create && !pass) - { - gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM); - if (s2k->mode == 3) - s2k->count = 96; /* 65536 iterations */ - } - if (s2k->mode == 3) - { - count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6); - if (count < len2) - count = len2; - } - /* a little bit complicated because we need a ulong for count */ - while (count > len2) - { /* maybe iterated+salted */ - gcry_md_write (md, s2k->salt, 8); - gcry_md_write (md, pw, pwlen); - count -= len2; - } - if (count < 8) - gcry_md_write (md, s2k->salt, count); - else - { - gcry_md_write (md, s2k->salt, 8); - count -= 8; - gcry_md_write (md, pw, count); - } - } - else - gcry_md_write (md, pw, pwlen); - gcry_md_final (md); - i = gcry_md_get_algo_dlen (s2k->hash_algo); - if (i > dek->keylen - used) - i = dek->keylen - used; - memcpy (dek->key + used, gcry_md_read (md, s2k->hash_algo), i); - used += i; + pwlen = strlen(pw); + + dek->keylen = gcry_cipher_get_algo_keylen(dek->algo); + err = _gnutls_hash_init(&md, s2k->hash_algo); + if (err < 0) + return map_gcry_error(err); + + for (pass = 0; used < dek->keylen; pass++) { + if (pass) { + _gnutls_hash_deinit(&md, NULL); + _gnutls_hash_init(&md, s2k->hash_algo); + for (i = 0; i < pass; i++) /* preset the hash context */ + _gnutls_hash(&md, zero, 1); } - gcry_md_close (md); + if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED) { + int len2 = pwlen + 8; + u32 count = len2; + if (create && !pass) { + gcry_randomize(s2k->salt, 8, GCRY_STRONG_RANDOM); + if (s2k->mode == 3) + s2k->count = 96; /* 65536 iterations */ + } + if (s2k->mode == 3) { + count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6); + if (count < len2) + count = len2; + } + /* a little bit complicated because we need a ulong for count */ + while (count > len2) { /* maybe iterated+salted */ + _gnutls_hash(&md, s2k->salt, 8); + _gnutls_hash(&md, pw, pwlen); + count -= len2; + } + if (count < 8) + _gnutls_hash(&md, s2k->salt, count); + else { + _gnutls_hash(&md, s2k->salt, 8); + count -= 8; + _gnutls_hash(&md, pw, count); + } + } else + _gnutls_hash(&md, pw, pwlen); + + i = _gnutls_hash_get_algo_len(s2k->hash_algo); + if (i > dek->keylen - used) { + i = dek->keylen - used; + char digest[i]; + + _gnutls_hash_deinit(&md, digest); + memcpy(dek->key + used, digest, i); + } else { + _gnutls_hash_deinit(&md, dek->key + used); + } + used += i; + } return 0; } @@ -630,27 +664,26 @@ hash_passphrase (cdk_dek_t dek, const char *pw, cdk_s2k_t s2k, int create) * Transform a passphrase into a DEK object. */ cdk_error_t -cdk_dek_from_passphrase (cdk_dek_t *ret_dek, int cipher_algo, cdk_s2k_t s2k, - int rndsalt, const char *pw) +cdk_dek_from_passphrase(cdk_dek_t * ret_dek, int cipher_algo, + cdk_s2k_t s2k, int rndsalt, const char *pw) { cdk_dek_t dek; cdk_error_t rc; - + if (!ret_dek) return CDK_Inv_Value; - + *ret_dek = NULL; - rc = cdk_dek_new (&dek); + rc = cdk_dek_new(&dek); if (rc) return rc; - rc = cdk_dek_set_cipher (dek, cipher_algo); + rc = cdk_dek_set_cipher(dek, cipher_algo); if (!rc) - rc = hash_passphrase (dek, pw, s2k, rndsalt); - if (rc) - { - cdk_dek_free (dek); - return rc; - } + rc = hash_passphrase(dek, pw, s2k, rndsalt); + if (rc) { + cdk_dek_free(dek); + return rc; + } *ret_dek = dek; return 0; @@ -668,7 +701,8 @@ cdk_dek_from_passphrase (cdk_dek_t *ret_dek, int cipher_algo, cdk_s2k_t s2k, * The @salt parameter must be always 8 octets. **/ cdk_error_t -cdk_s2k_new (cdk_s2k_t *ret_s2k, int mode, int digest_algo, const byte *salt) +cdk_s2k_new(cdk_s2k_t * ret_s2k, int mode, int digest_algo, + const byte * salt) { cdk_s2k_t s2k; @@ -677,17 +711,17 @@ cdk_s2k_new (cdk_s2k_t *ret_s2k, int mode, int digest_algo, const byte *salt) if (mode != 0x00 && mode != 0x01 && mode != 0x03) return CDK_Inv_Mode; - - if (gcry_md_test_algo (digest_algo)) + + if (_gnutls_hash_get_algo_len(digest_algo) <= 0) return CDK_Inv_Algo; - - s2k = cdk_calloc (1, sizeof *s2k); + + s2k = cdk_calloc(1, sizeof *s2k); if (!s2k) return CDK_Out_Of_Core; s2k->mode = mode; s2k->hash_algo = digest_algo; if (salt) - memcpy (s2k->salt, salt, 8); + memcpy(s2k->salt, salt, 8); *ret_s2k = s2k; return 0; } @@ -699,25 +733,23 @@ cdk_s2k_new (cdk_s2k_t *ret_s2k, int mode, int digest_algo, const byte *salt) * * Release the given S2K object. **/ -void -cdk_s2k_free (cdk_s2k_t s2k) +void cdk_s2k_free(cdk_s2k_t s2k) { - cdk_free (s2k); + cdk_free(s2k); } /* Make a copy of the source s2k into R_DST. */ -cdk_error_t -_cdk_s2k_copy (cdk_s2k_t *r_dst, cdk_s2k_t src) +cdk_error_t _cdk_s2k_copy(cdk_s2k_t * r_dst, cdk_s2k_t src) { cdk_s2k_t dst; cdk_error_t err; - - err = cdk_s2k_new (&dst, src->mode, src->hash_algo, src->salt); + + err = cdk_s2k_new(&dst, src->mode, src->hash_algo, src->salt); if (err) return err; dst->count = src->count; *r_dst = dst; - + return 0; } diff --git a/lib/opencdk/sig-check.c b/lib/opencdk/sig-check.c index 42268b433c..e5ac5af164 100644 --- a/lib/opencdk/sig-check.c +++ b/lib/opencdk/sig-check.c @@ -37,7 +37,7 @@ /* Hash all multi precision integers of the key PK with the given message digest context MD. */ static int -hash_mpibuf (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) +hash_mpibuf (cdk_pubkey_t pk, digest_hd_st* md, int usefpr) { byte buf[MAX_MPI_BYTES]; /* FIXME: do not use hardcoded length. */ size_t nbytes; @@ -55,9 +55,9 @@ hash_mpibuf (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) if (err) return map_gcry_error (err); if (!usefpr || pk->version == 4) - gcry_md_write (md, buf, nbytes); + _gnutls_hash( md, buf, nbytes); else /* without the prefix. */ - gcry_md_write (md, buf + 2, nbytes - 2); + _gnutls_hash( md, buf+2, nbytes - 2); } return 0; } @@ -67,7 +67,7 @@ hash_mpibuf (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) MD. The @usefpr param is only valid for version 3 keys because of the different way to calculate the fingerprint. */ cdk_error_t -_cdk_hash_pubkey (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) +_cdk_hash_pubkey (cdk_pubkey_t pk, digest_hd_st* md, int usefpr) { byte buf[12]; size_t i, n, npkey; @@ -106,7 +106,7 @@ _cdk_hash_pubkey (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) buf[i++] = a; } buf[i++] = pk->pubkey_algo; - gcry_md_write (md, buf, i); + _gnutls_hash( md, buf, i); return hash_mpibuf (pk, md, 0); } @@ -114,7 +114,7 @@ _cdk_hash_pubkey (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) /* Hash the user ID @uid with the given message digest @md. Use openpgp mode if @is_v4 is 1. */ cdk_error_t -_cdk_hash_userid (cdk_pkt_userid_t uid, int is_v4, gcry_md_hd_t md) +_cdk_hash_userid (cdk_pkt_userid_t uid, int is_v4, digest_hd_st* md) { const byte *data; byte buf[5]; @@ -125,7 +125,7 @@ _cdk_hash_userid (cdk_pkt_userid_t uid, int is_v4, gcry_md_hd_t md) if (!is_v4) { - gcry_md_write (md, (byte*)uid->name, uid->len); + _gnutls_hash (md, (byte*)uid->name, uid->len); return 0; } @@ -136,8 +136,8 @@ _cdk_hash_userid (cdk_pkt_userid_t uid, int is_v4, gcry_md_hd_t md) buf[2] = dlen >> 16; buf[3] = dlen >> 8; buf[4] = dlen >> 0; - gcry_md_write (md, buf, 5); - gcry_md_write (md, data, dlen); + _gnutls_hash (md, buf, 5); + _gnutls_hash (md, data, dlen); return 0; } @@ -145,55 +145,59 @@ _cdk_hash_userid (cdk_pkt_userid_t uid, int is_v4, gcry_md_hd_t md) /* Hash all parts of the signature which are needed to derive the correct message digest to verify the sig. */ cdk_error_t -_cdk_hash_sig_data (cdk_pkt_signature_t sig, gcry_md_hd_t md) +_cdk_hash_sig_data (cdk_pkt_signature_t sig, digest_hd_st* md) { byte buf[4]; + byte tmp; if (!sig || !md) return CDK_Inv_Value; if (sig->version == 4) - gcry_md_putc (md, sig->version); - gcry_md_putc (md, sig->sig_class); + _gnutls_hash(md, &sig->version, 1); + + _gnutls_hash(md, &sig->sig_class, 1); if (sig->version < 4) { buf[0] = sig->timestamp >> 24; buf[1] = sig->timestamp >> 16; buf[2] = sig->timestamp >> 8; buf[3] = sig->timestamp >> 0; - gcry_md_write (md, buf, 4); + _gnutls_hash( md, buf, 4); } else { size_t n; - - gcry_md_putc (md, sig->pubkey_algo); - gcry_md_putc (md, sig->digest_algo); + + _gnutls_hash( md, &sig->pubkey_algo, 1); + _gnutls_hash( md, &sig->digest_algo, 1); if (sig->hashed != NULL) { byte *p = _cdk_subpkt_get_array (sig->hashed, 0, &n); assert (p != NULL); buf[0] = n >> 8; buf[1] = n >> 0; - gcry_md_write (md, buf, 2); - gcry_md_write (md, p, n); + _gnutls_hash(md, buf, 2); + _gnutls_hash(md, p, n); cdk_free (p); sig->hashed_size = n; n = sig->hashed_size + 6; } else { - gcry_md_putc (md, 0x00); - gcry_md_putc (md, 0x00); + tmp = 0x00; + _gnutls_hash (md, &tmp, 1); + _gnutls_hash (md, &tmp, 1); n = 6; } - gcry_md_putc (md, sig->version); - gcry_md_putc (md, 0xFF); + _gnutls_hash(md, &sig->version, 1); + tmp = 0xff; + _gnutls_hash(md, &tmp, 1); buf[0] = n >> 24; buf[1] = n >> 16; buf[2] = n >> 8; buf[3] = n >> 0; - gcry_md_write (md, buf, 4); + _gnutls_hash(md, buf, 4); } return 0; } @@ -222,11 +226,11 @@ cache_sig_result (cdk_pkt_signature_t sig, int res) Use the digest handle @digest. */ cdk_error_t _cdk_sig_check (cdk_pubkey_t pk, cdk_pkt_signature_t sig, - gcry_md_hd_t digest, int *r_expired) + digest_hd_st* digest, int *r_expired) { cdk_error_t rc; byte md[MAX_DIGEST_LEN]; - time_t cur_time = (u32)time (NULL); + time_t cur_time = (u32)time (NULL); if (!pk || !sig || !digest) return CDK_Inv_Value; @@ -243,9 +247,7 @@ _cdk_sig_check (cdk_pubkey_t pk, cdk_pkt_signature_t sig, *r_expired = 1; _cdk_hash_sig_data (sig, digest); - gcry_md_final (digest); - memcpy (md, gcry_md_read (digest, sig->digest_algo), - gcry_md_get_algo_dlen (sig->digest_algo)); + _gnutls_hash_output( digest, md); if (md[0] != sig->digest_start[0] || md[1] != sig->digest_start[1]) @@ -263,8 +265,8 @@ cdk_error_t _cdk_pk_check_sig (cdk_keydb_hd_t keydb, cdk_kbnode_t knode, cdk_kbnode_t snode, int *is_selfsig) { - gcry_md_hd_t md; - gcry_error_t err; + digest_hd_st md; + int err; cdk_pubkey_t pk; cdk_pkt_signature_t sig; cdk_kbnode_t node; @@ -282,15 +284,15 @@ _cdk_pk_check_sig (cdk_keydb_hd_t keydb, pk = knode->pkt->pkt.public_key; sig = snode->pkt->pkt.signature; - err = gcry_md_open (&md, sig->digest_algo, 0); - if (err) - return map_gcry_error (err); + err = _gnutls_hash_init(&md, sig->digest_algo); + if (err < 0) + return map_gnutls_error (err); is_expired = 0; if (sig->sig_class == 0x20) { /* key revocation */ - cdk_kbnode_hash (knode, md, 0, 0, 0); - rc = _cdk_sig_check (pk, sig, md, &is_expired); + cdk_kbnode_hash (knode, &md, 0, 0, 0); + rc = _cdk_sig_check (pk, sig, &md, &is_expired); } else if (sig->sig_class == 0x28) { /* subkey revocation */ @@ -300,9 +302,9 @@ _cdk_pk_check_sig (cdk_keydb_hd_t keydb, rc = CDK_Error_No_Key; goto fail; } - cdk_kbnode_hash (knode, md, 0, 0, 0); - cdk_kbnode_hash (node, md, 0, 0, 0); - rc = _cdk_sig_check (pk, sig, md, &is_expired); + cdk_kbnode_hash (knode, &md, 0, 0, 0); + cdk_kbnode_hash (node, &md, 0, 0, 0); + rc = _cdk_sig_check (pk, sig, &md, &is_expired); } else if (sig->sig_class == 0x18 || sig->sig_class == 0x19) { /* primary/secondary key binding */ @@ -312,14 +314,14 @@ _cdk_pk_check_sig (cdk_keydb_hd_t keydb, rc = CDK_Error_No_Key; goto fail; } - cdk_kbnode_hash (knode, md, 0, 0, 0); - cdk_kbnode_hash (node, md, 0, 0, 0); - rc = _cdk_sig_check (pk, sig, md, &is_expired); + cdk_kbnode_hash (knode, &md, 0, 0, 0); + cdk_kbnode_hash (node, &md, 0, 0, 0); + rc = _cdk_sig_check (pk, sig, &md, &is_expired); } else if (sig->sig_class == 0x1F) { /* direct key signature */ - cdk_kbnode_hash (knode, md, 0, 0, 0); - rc = _cdk_sig_check (pk, sig, md, &is_expired); + cdk_kbnode_hash (knode, &md, 0, 0, 0); + rc = _cdk_sig_check (pk, sig, &md, &is_expired); } else { /* all other classes */ @@ -329,26 +331,25 @@ _cdk_pk_check_sig (cdk_keydb_hd_t keydb, rc = CDK_Error_No_Key; goto fail; } - cdk_kbnode_hash (knode, md, 0, 0, 0); - cdk_kbnode_hash (node, md, sig->version==4, 0, 0); + cdk_kbnode_hash (knode, &md, 0, 0, 0); + cdk_kbnode_hash (node, &md, sig->version==4, 0, 0); if (pk->keyid[0] == sig->keyid[0] && pk->keyid[1] == sig->keyid[1]) { - rc = _cdk_sig_check (pk, sig, md, &is_expired); + rc = _cdk_sig_check (pk, sig, &md, &is_expired); if (is_selfsig) *is_selfsig = 1; } else if (keydb != NULL) { cdk_pubkey_t sig_pk; - rc = cdk_keydb_get_pk (keydb, sig->keyid, &sig_pk); if (!rc) - rc = _cdk_sig_check (sig_pk, sig, md, &is_expired); + rc = _cdk_sig_check (sig_pk, sig, &md, &is_expired); cdk_pk_release (sig_pk); } } fail: - gcry_md_close (md); + _gnutls_hash_deinit( &md, NULL); return rc; } diff --git a/lib/opencdk/stream.c b/lib/opencdk/stream.c index 7e95924aed..9be9469d5f 100644 --- a/lib/opencdk/stream.c +++ b/lib/opencdk/stream.c @@ -821,7 +821,7 @@ _cdk_stream_get_opaque (cdk_stream_t s, int fid) for (f = s->filters; f; f = f->next) { - if (f->type == fid) + if ((int)f->type == fid) return f->opaque; } return NULL; diff --git a/lib/opencdk/verify.c b/lib/opencdk/verify.c index c141da8dc6..fa4d813267 100644 --- a/lib/opencdk/verify.c +++ b/lib/opencdk/verify.c @@ -40,12 +40,12 @@ struct { const char *name; int algo; } digest_table[] = { - {"MD5", GCRY_MD_MD5}, - {"SHA1", GCRY_MD_SHA1}, - {"RIPEMD160", GCRY_MD_RMD160}, - {"SHA256", GCRY_MD_SHA256}, - {"SHA384", GCRY_MD_SHA384}, - {"SHA512", GCRY_MD_SHA512}, + {"MD5", GNUTLS_DIG_MD5}, + {"SHA1", GNUTLS_DIG_SHA1}, + {"RIPEMD160", GNUTLS_DIG_RMD160}, + {"SHA256", GNUTLS_DIG_SHA256}, + {"SHA384", GNUTLS_DIG_SHA384}, + {"SHA512", GNUTLS_DIG_SHA512}, {NULL, 0} }; @@ -161,12 +161,12 @@ static cdk_error_t file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) { cdk_stream_t inp = NULL, out = NULL, tmp = NULL; - gcry_md_hd_t md = NULL; + digest_hd_st md; char buf[512], chk[512]; const char *s; int i, is_signed = 0, nbytes; int digest_algo = 0; - gcry_error_t err; + int err; cdk_error_t rc; if (output) @@ -223,7 +223,7 @@ file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) } } - if (digest_algo && gcry_md_test_algo (digest_algo)) + if (digest_algo && _gnutls_hash_get_algo_len(digest_algo) <= 0) { rc = CDK_Inv_Algo; goto leave; @@ -232,10 +232,10 @@ file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) if (!digest_algo) digest_algo = GCRY_MD_MD5; - err = gcry_md_open (&md, digest_algo, 0); - if (err) + err = _gnutls_hash_init (&md, digest_algo); + if (err < 0) { - rc = map_gcry_error (err); + rc = map_gnutls_error (err); goto leave; } @@ -254,7 +254,7 @@ file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) if (strlen (buf) == 0 && i == 0) continue; /* skip last '\n' */ _cdk_trim_string (buf, i == 0? 0 : 1); - gcry_md_write (md, buf, strlen (buf)); + _gnutls_hash (&md, buf, strlen (buf)); } if (!strncmp (buf, "- ", 2)) /* FIXME: handle it recursive. */ memmove (buf, buf + 2, nbytes - 2); @@ -280,7 +280,7 @@ file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) nbytes = _cdk_stream_gets (inp, buf, DIM (buf)-1); if (!nbytes || nbytes == -1) break; - if (nbytes < (DIM (buf) -3)) + if (nbytes < (int)(DIM (buf) -3)) { buf[nbytes-1] = '\n'; buf[nbytes] = '\0'; @@ -295,10 +295,10 @@ file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) cdk_stream_read (tmp, NULL, 0); /* the digest handle will be closed there. */ - rc = _cdk_proc_packets (hd, tmp, NULL, NULL, NULL, md); + rc = _cdk_proc_packets (hd, tmp, NULL, NULL, NULL, &md); leave: - gcry_md_close (md); + _gnutls_hash_deinit (&md, NULL); cdk_stream_close (out); cdk_stream_close (tmp); cdk_stream_close (inp); |