summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@crystal.(none)>2008-05-17 19:58:29 +0300
committerNikos Mavrogiannopoulos <nmav@crystal.(none)>2008-05-17 19:58:29 +0300
commit1539fa9db4cb3cd193c236d535009449117adbb6 (patch)
tree24839593de5c15cffd4cf8b6523f01a8e0dab18d
parent77c732aa46fb8c868e38b55519738c0ce2173e56 (diff)
downloadgnutls-1539fa9db4cb3cd193c236d535009449117adbb6.tar.gz
converted hash functions to gnutls functions.
-rw-r--r--lib/opencdk/Makefile.am2
-rw-r--r--lib/opencdk/armor.c4
-rw-r--r--lib/opencdk/dummy.c2
-rw-r--r--lib/opencdk/filters.h8
-rw-r--r--lib/opencdk/hash.c18
-rw-r--r--lib/opencdk/kbnode.c2
-rw-r--r--lib/opencdk/literal.c4
-rw-r--r--lib/opencdk/main.c6
-rw-r--r--lib/opencdk/main.h20
-rw-r--r--lib/opencdk/misc.c12
-rw-r--r--lib/opencdk/opencdk.h9
-rw-r--r--lib/opencdk/pubkey.c116
-rw-r--r--lib/opencdk/seskey.c640
-rw-r--r--lib/opencdk/sig-check.c99
-rw-r--r--lib/opencdk/stream.c2
-rw-r--r--lib/opencdk/verify.c32
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);