SKEYID derivation based on libstrongswan
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 5 May 2009 12:28:02 +0000 (14:28 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 5 May 2009 12:28:31 +0000 (14:28 +0200)
22 files changed:
configure.in
src/pluto/alg_info.c
src/pluto/cookie.c
src/pluto/cookie.h
src/pluto/crl.c
src/pluto/crypto.c
src/pluto/crypto.h
src/pluto/demux.c
src/pluto/ike_alg.c
src/pluto/ipsec_doi.c
src/pluto/modecfg.c
src/pluto/nat_traversal.c
src/pluto/pem.c
src/pluto/pgp.c
src/pluto/pkcs1.c
src/pluto/plutomain.c
src/pluto/spdb.c
src/pluto/state.c
src/pluto/vendor.c
src/pluto/vendor.h
src/pluto/x509.c
src/pluto/x509.h

index 47a7b8e..f9d7fb8 100644 (file)
@@ -951,15 +951,18 @@ if test x$des = xtrue; then
 fi
 if test x$sha1 = xtrue; then
        libstrongswan_plugins=${libstrongswan_plugins}" sha1"
+        pluto_plugins=${pluto_plugins}" sha1"
 fi
 if test x$sha2 = xtrue; then
        libstrongswan_plugins=${libstrongswan_plugins}" sha2"
+        pluto_plugins=${pluto_plugins}" sha2"
 fi
 if test x$md4 = xtrue; then
        libstrongswan_plugins=${libstrongswan_plugins}" md4"
 fi
 if test x$md5 = xtrue; then
        libstrongswan_plugins=${libstrongswan_plugins}" md5"
+        pluto_plugins=${pluto_plugins}" md5"
 fi
 if test x$fips_prf = xtrue; then
        libstrongswan_plugins=${libstrongswan_plugins}" fips-prf"
@@ -979,6 +982,7 @@ if test x$xcbc = xtrue; then
 fi
 if test x$hmac = xtrue; then
        libstrongswan_plugins=${libstrongswan_plugins}" hmac"
+        pluto_plugins=${pluto_plugins}" hmac"
 fi
 if test x$mysql = xtrue; then
        libstrongswan_plugins=${libstrongswan_plugins}" mysql"
index a81d641..bd0c73f 100644 (file)
@@ -33,8 +33,6 @@
 #include "defs.h"
 #include "log.h"
 #include "whack.h"
-#include "sha1.h"
-#include "md5.h"
 #include "crypto.h"
 #include "kernel_alg.h"
 #include "ike_alg.h"
index 7caa19b..39fe747 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "constants.h"
 #include "defs.h"
-#include "sha1.h"
 #include "cookie.h"
 
 const u_char zero_cookie[COOKIE_SIZE];  /* guaranteed 0 */
@@ -35,11 +34,10 @@ const u_char zero_cookie[COOKIE_SIZE];  /* guaranteed 0 */
  * First argument is true if we're to create an Initiator cookie.
  * Length SHOULD be a multiple of sizeof(u_int32_t).
  */
-void get_cookie(bool initiator, u_int8_t *cookie, int length,
-                               const ip_address *addr)
+void get_cookie(bool initiator, u_int8_t *cookie, int length, ip_address *addr)
 {
-       u_char buffer[SHA1_DIGEST_SIZE];
-       SHA1_CTX ctx;
+       hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+       u_char buffer[HASH_SIZE_SHA1];
 
        do {
                if (initiator)
@@ -52,20 +50,23 @@ void get_cookie(bool initiator, u_int8_t *cookie, int length,
                }
                else  /* Responder cookie */
                {
-                       /* This looks as good as any way */
-                       size_t addr_length;
+                       chunk_t addr_chunk, secret_chunk, counter_chunk;
+                       size_t addr_len;
                        static u_int32_t counter = 0;
-                       unsigned char addr_buff[
+                       unsigned char addr_buf[
                                sizeof(union {struct in_addr A; struct in6_addr B;})];
 
-                       addr_length = addrbytesof(addr, addr_buff, sizeof(addr_buff));
-                       SHA1Init(&ctx);
-                       SHA1Update(&ctx, addr_buff, addr_length);
-                       SHA1Update(&ctx, secret_of_the_day, sizeof(secret_of_the_day));
+                       addr_len = addrbytesof(addr, addr_buf, sizeof(addr_buf));
+                       addr_chunk = chunk_create(addr_buf, addr_len);
+                       secret_chunk = chunk_create(secret_of_the_day, HASH_SIZE_SHA1);
                        counter++;
-                       SHA1Update(&ctx, (const void *) &counter, sizeof(counter));
-                       SHA1Final(buffer, &ctx);
+                       counter_chunk = chunk_create((void *) &counter, sizeof(counter));
+                       hasher->get_hash(hasher, addr_chunk, NULL);
+                       hasher->get_hash(hasher, secret_chunk, NULL);
+                       hasher->get_hash(hasher, counter_chunk, buffer);
                        memcpy(cookie, buffer, length);
                }
        } while (is_zero_cookie(cookie));   /* probably never loops */
+
+       hasher->destroy(hasher);
 }
index 7a1b8fd..809d664 100644 (file)
@@ -16,7 +16,7 @@
 
 extern const u_char zero_cookie[COOKIE_SIZE];   /* guaranteed 0 */
 
-extern void get_cookie(bool initiator, u_int8_t *cookie, int length
-       , const ip_address *addr);
+extern void get_cookie(bool initiator, u_int8_t *cookie, int length,
+                                          ip_address *addr);
 
 #define is_zero_cookie(cookie) all_zero((cookie), COOKIE_SIZE)
index 321e98a..b8cdb43 100644 (file)
@@ -28,6 +28,7 @@
 #include <asn1/asn1.h>
 #include <asn1/asn1_parser.h>
 #include <asn1/oid.h>
+#include <crypto/hashers/hasher.h>
 
 #include "constants.h"
 #include "defs.h"
@@ -39,7 +40,7 @@
 #include "keys.h"
 #include "whack.h"
 #include "fetch.h"
-#include "sha1.h"
+
 
 /* chained lists of X.509 crls */
 
@@ -292,19 +293,26 @@ bool insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl)
                 */
                if (cache_crl && strncasecmp(crl_uri.ptr, "file", 4) != 0)
                {
-                       char path[BUF_LEN];
-                       char buf[BUF_LEN];
-                       char digest_buf[SHA1_DIGEST_SIZE];
-                       chunk_t subjectKeyID = { digest_buf, SHA1_DIGEST_SIZE };
-
+                       char path[BUF_LEN], buf[BUF_LEN];
+                       char digest_buf[HASH_SIZE_SHA1];
+                       chunk_t subjectKeyID = chunk_from_buf(digest_buf);
+                       bool has_keyID;
+                       
                        if (issuer_cert->subjectKeyID.ptr == NULL)
-                               compute_subjectKeyID(issuer_cert, subjectKeyID);
+                       {
+                               has_keyID = compute_subjectKeyID(issuer_cert, subjectKeyID);
+                       }
                        else
+                       {
                                subjectKeyID = issuer_cert->subjectKeyID;
-
-                       datatot(subjectKeyID.ptr, subjectKeyID.len, 16, buf, BUF_LEN);
-                       snprintf(path, BUF_LEN, "%s/%s.crl", CRL_PATH, buf);
-                       chunk_write(crl->certificateList, path, "crl",  0022, TRUE);
+                               has_keyID = TRUE;
+                       }
+                       if (has_keyID)
+                       {
+                               datatot(subjectKeyID.ptr, subjectKeyID.len, 16, buf, BUF_LEN);
+                               snprintf(path, BUF_LEN, "%s/%s.crl", CRL_PATH, buf);
+                               chunk_write(crl->certificateList, path, "crl",  0022, TRUE);
+                       }
                }
 
                /* is the fetched crl valid? */
index 8f9e2ac..6a885b8 100644 (file)
@@ -28,9 +28,7 @@
 #include "defs.h"
 #include "state.h"
 #include "log.h"
-#include "md5.h"
-#include "sha1.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
+#include "crypto.h"
 #include "alg_info.h"
 #include "ike_alg.h"
 
@@ -451,8 +449,7 @@ static struct hash_desc crypto_hasher_sha1 =
                hash_final: (void (*)(u_char *, void *)) SHA1Final
 };
 
-void
-init_crypto(void)
+void init_crypto(void)
 {
        if (mpz_init_set_str(&groupgenerator, MODP_GENERATOR, 10) != 0
        || mpz_init_set_str(&modp1024_modulus, MODP1024_MODULUS, 16) != 0
@@ -471,8 +468,7 @@ init_crypto(void)
        ike_alg_test();
 }
 
-void
-free_crypto(void)
+void free_crypto(void)
 {
        mpz_clear(&groupgenerator);
        mpz_clear(&modp1024_modulus);
@@ -503,8 +499,7 @@ const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE] = {
 #   undef BYTES
 };
 
-const struct oakley_group_desc *
-lookup_group(u_int16_t group)
+const struct oakley_group_desc *lookup_group(u_int16_t group)
 {
        int i;
 
@@ -541,8 +536,8 @@ do_des(bool enc, void *buf, size_t buf_len, struct state *st)
 /* encrypt or decrypt part of an IKE message using 3DES
  * See RFC 2409 "IKE" Appendix B
  */
-static void
-do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
+static void do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key,
+                                       size_t key_size, u_int8_t *iv, bool enc)
 {
        des_key_schedule ks[3];
 
@@ -557,8 +552,8 @@ do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t
 }
 
 /* hash and prf routines */
-void
-crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t size, struct state *st)
+void crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf,
+                                               size_t size, struct state *st)
 {
        passert(st->st_new_iv_len >= e->enc_blocksize);
        st->st_new_iv_len = e->enc_blocksize;       /* truncate */
@@ -574,10 +569,8 @@ crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t
  * rfc2104.txt specifies how HMAC works.
  */
 
-void
-hmac_init(struct hmac_ctx *ctx,
-       const struct hash_desc *h,
-       const u_char *key, size_t key_len)
+void hmac_init(struct hmac_ctx *ctx, const struct hash_desc *h,
+                          const u_char *key, size_t key_len)
 {
        int k;
 
@@ -610,22 +603,19 @@ hmac_init(struct hmac_ctx *ctx,
        hmac_reinit(ctx);
 }
 
-void
-hmac_reinit(struct hmac_ctx *ctx)
+void hmac_reinit(struct hmac_ctx *ctx)
 {
        ctx->h->hash_init(&ctx->hash_ctx);
        ctx->h->hash_update(&ctx->hash_ctx, ctx->buf1, ctx->h->hash_block_size);
 }
 
-void
-hmac_update(struct hmac_ctx *ctx,
+void hmac_update(struct hmac_ctx *ctx,
        const u_char *data, size_t data_len)
 {
        ctx->h->hash_update(&ctx->hash_ctx, data, data_len);
 }
 
-void
-hmac_final(u_char *output, struct hmac_ctx *ctx)
+void hmac_final(u_char *output, struct hmac_ctx *ctx)
 {
        const struct hash_desc *h = ctx->h;
 
@@ -636,3 +626,41 @@ hmac_final(u_char *output, struct hmac_ctx *ctx)
        h->hash_update(&ctx->hash_ctx, output, h->hash_digest_size);
        h->hash_final(output, &ctx->hash_ctx);
 }
+
+hash_algorithm_t oakley_to_hash_algorithm(int alg)
+{
+       switch (alg)
+       {
+               case OAKLEY_MD5:
+                       return HASH_MD5;
+               case OAKLEY_SHA:
+                       return HASH_SHA1;
+               case OAKLEY_SHA2_256:
+                       return HASH_SHA256;
+               case OAKLEY_SHA2_384:
+                       return HASH_SHA384;
+               case OAKLEY_SHA2_512:
+                       return HASH_SHA512;
+               default:
+                       return HASH_UNKNOWN;
+       }
+}
+
+pseudo_random_function_t oakley_to_prf(int alg)
+{
+       switch (alg)
+       {
+               case OAKLEY_MD5:
+                       return PRF_HMAC_MD5;
+               case OAKLEY_SHA:
+                       return PRF_HMAC_SHA1;
+               case OAKLEY_SHA2_256:
+                       return PRF_HMAC_SHA2_256;
+               case OAKLEY_SHA2_384:
+                       return PRF_HMAC_SHA2_384;
+               case OAKLEY_SHA2_512:
+                       return PRF_HMAC_SHA2_512;
+               default:
+                       return PRF_UNDEFINED;
+       }
+}
index be33cf8..72df70e 100644 (file)
 
 #include <gmp.h>    /* GNU MP library */
 
+#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/prf.h>
+
+#include "md5.h"
+#include "sha1.h"
 #include "libsha2/sha2.h"
 #include "ike_alg.h"
 
@@ -104,4 +109,8 @@ extern void hmac_final(u_char *output, struct hmac_ctx *ctx);
                (ch).ptr = malloc((ch).len); \
                hmac_final((ch).ptr, (ctx)); \
        }
+
+extern hash_algorithm_t oakley_to_hash_algorithm(int alg);
+extern pseudo_random_function_t oakley_to_prf(int alg);
+
 #endif
index 25c722f..fef9b98 100644 (file)
 #include "connections.h"
 #include "state.h"
 #include "packet.h"
-#include "md5.h"
-#include "sha1.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
+#include "crypto.h"
 #include "ike_alg.h"
 #include "log.h"
 #include "demux.h"      /* needs packet.h */
index e48c011..2995e32 100644 (file)
@@ -23,8 +23,6 @@
 
 #include "constants.h"
 #include "defs.h"
-#include "sha1.h"
-#include "md5.h"
 #include "crypto.h"
 
 #include "state.h"
index a9a06cb..11d4645 100644 (file)
@@ -31,6 +31,8 @@
 
 #include <library.h>
 #include <asn1/asn1.h>
+#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/prf.h>
 #include <crypto/rngs/rng.h>
 
 #include "constants.h"
 #include "whack.h"
 #include "fetch.h"
 #include "pkcs7.h"
-
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
+#include "crypto.h"
 #include "vendor.h"
 #include "alg_info.h"
 #include "ike_alg.h"
@@ -1166,12 +1165,22 @@ static bool skeyid_preshared(struct state *st)
        }
        else
        {
-               struct hmac_ctx ctx;
+               pseudo_random_function_t prf_alg;
+               prf_t *prf;
 
-               hmac_init_chunk(&ctx, st->st_oakley.hasher, *pss);
-               hmac_update_chunk(&ctx, st->st_ni);
-               hmac_update_chunk(&ctx, st->st_nr);
-               hmac_final_chunk(st->st_skeyid, "st_skeyid in skeyid_preshared()", &ctx);
+               prf_alg = oakley_to_prf(st->st_oakley.hasher->algo_id);
+               prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+               if (prf == NULL)
+               {
+               loglog(RC_LOG_SERIOUS, "%N not available to compute skeyid",
+                                                               pseudo_random_function_names, prf_alg);
+               return FALSE;
+               }
+               free(st->st_skeyid.ptr);
+               prf->set_key(prf, *pss);
+               prf->allocate_bytes(prf, st->st_ni, NULL);
+               prf->allocate_bytes(prf, st->st_nr, &st->st_skeyid);
+               prf->destroy(prf);
                return TRUE;
        }
 }
@@ -1179,21 +1188,24 @@ static bool skeyid_preshared(struct state *st)
 static bool
 skeyid_digisig(struct state *st)
 {
-       struct hmac_ctx ctx;
        chunk_t nir;
+       pseudo_random_function_t prf_alg;
+       prf_t *prf;
 
-       /* We need to hmac_init with the concatenation of Ni_b and Nr_b,
-        * so we have to build a temporary concatentation.
-        */
-       nir.len = st->st_ni.len + st->st_nr.len;
-       nir.ptr = malloc(nir.len);
-       memcpy(nir.ptr, st->st_ni.ptr, st->st_ni.len);
-       memcpy(nir.ptr+st->st_ni.len, st->st_nr.ptr, st->st_nr.len);
-       hmac_init_chunk(&ctx, st->st_oakley.hasher, nir);
+       prf_alg = oakley_to_prf(st->st_oakley.hasher->algo_id);
+       prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+       if (prf == NULL)
+       {
+               loglog(RC_LOG_SERIOUS, "%N not available to compute skeyid",
+                                                               pseudo_random_function_names, prf_alg);
+               return FALSE;
+       }
+       free(st->st_skeyid.ptr);
+       nir = chunk_cat("cc", st->st_ni, st->st_nr);
+       prf->set_key(prf, nir);
+       prf->allocate_bytes(prf, st->st_shared, &st->st_skeyid);
+       prf->destroy(prf);
        free(nir.ptr);
-
-       hmac_update_chunk(&ctx, st->st_shared);
-       hmac_final_chunk(st->st_skeyid, "st_skeyid in skeyid_digisig()", &ctx);
        return TRUE;
 }
 
@@ -1209,14 +1221,18 @@ static bool generate_skeyids_iv(struct state *st)
                case XAUTHInitPreShared:
                case XAUTHRespPreShared:
                        if (!skeyid_preshared(st))
+                       {
                                return FALSE;
+                       }
                        break;
 
                case OAKLEY_RSA_SIG:
                case XAUTHInitRSA:
                case XAUTHRespRSA:
                        if (!skeyid_digisig(st))
+                       {
                                return FALSE;
+                       }
                        break;
 
                case OAKLEY_DSS_SIG:
@@ -1234,52 +1250,65 @@ static bool generate_skeyids_iv(struct state *st)
 
        /* generate SKEYID_* from SKEYID */
        {
-               struct hmac_ctx ctx;
-
-               hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid);
+               char buf_skeyid_d[] = { 0x00 };
+               char buf_skeyid_a[] = { 0x01 };
+               char buf_skeyid_e[] = { 0x02 };
+               chunk_t seed_skeyid_d = chunk_from_buf(buf_skeyid_d);
+               chunk_t seed_skeyid_a = chunk_from_buf(buf_skeyid_a);
+               chunk_t seed_skeyid_e = chunk_from_buf(buf_skeyid_e);
+               chunk_t icookie = { st->st_icookie, COOKIE_SIZE };
+               chunk_t rcookie = { st->st_rcookie, COOKIE_SIZE };
+               pseudo_random_function_t prf_alg;
+               prf_t *prf;
+
+               prf_alg = oakley_to_prf(st->st_oakley.hasher->algo_id);
+               prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+               prf->set_key(prf, st->st_skeyid);
 
                /* SKEYID_D */
-               hmac_update_chunk(&ctx, st->st_shared);
-               hmac_update(&ctx, st->st_icookie, COOKIE_SIZE);
-               hmac_update(&ctx, st->st_rcookie, COOKIE_SIZE);
-               hmac_update(&ctx, "\0", 1);
-               hmac_final_chunk(st->st_skeyid_d, "st_skeyid_d in generate_skeyids_iv()", &ctx);
+               free(st->st_skeyid_d.ptr);
+               prf->allocate_bytes(prf, st->st_shared, NULL);
+               prf->allocate_bytes(prf, icookie, NULL);
+               prf->allocate_bytes(prf, rcookie, NULL);
+               prf->allocate_bytes(prf, seed_skeyid_d, &st->st_skeyid_d); 
 
                /* SKEYID_A */
-               hmac_reinit(&ctx);
-               hmac_update_chunk(&ctx, st->st_skeyid_d);
-               hmac_update_chunk(&ctx, st->st_shared);
-               hmac_update(&ctx, st->st_icookie, COOKIE_SIZE);
-               hmac_update(&ctx, st->st_rcookie, COOKIE_SIZE);
-               hmac_update(&ctx, "\1", 1);
-               hmac_final_chunk(st->st_skeyid_a, "st_skeyid_a in generate_skeyids_iv()", &ctx);
+               free(st->st_skeyid_a.ptr);
+               prf->allocate_bytes(prf, st->st_skeyid_d, NULL);
+               prf->allocate_bytes(prf, st->st_shared, NULL);
+               prf->allocate_bytes(prf, icookie, NULL);
+               prf->allocate_bytes(prf, rcookie, NULL);
+               prf->allocate_bytes(prf, seed_skeyid_a, &st->st_skeyid_a); 
 
                /* SKEYID_E */
-               hmac_reinit(&ctx);
-               hmac_update_chunk(&ctx, st->st_skeyid_a);
-               hmac_update_chunk(&ctx, st->st_shared);
-               hmac_update(&ctx, st->st_icookie, COOKIE_SIZE);
-               hmac_update(&ctx, st->st_rcookie, COOKIE_SIZE);
-               hmac_update(&ctx, "\2", 1);
-               hmac_final_chunk(st->st_skeyid_e, "st_skeyid_e in generate_skeyids_iv()", &ctx);
+               free(st->st_skeyid_e.ptr);
+               prf->allocate_bytes(prf, st->st_skeyid_a, NULL);
+               prf->allocate_bytes(prf, st->st_shared, NULL);
+               prf->allocate_bytes(prf, icookie, NULL);
+               prf->allocate_bytes(prf, rcookie, NULL);
+               prf->allocate_bytes(prf, seed_skeyid_e, &st->st_skeyid_e); 
+
+               prf->destroy(prf);
        }
 
        /* generate IV */
        {
-               union hash_ctx hash_ctx;
-               const struct hash_desc *h = st->st_oakley.hasher;
+               hash_algorithm_t hash_alg;
+               hasher_t *hasher;
 
-               st->st_new_iv_len = h->hash_digest_size;
+               hash_alg = oakley_to_hash_algorithm(st->st_oakley.hasher->algo_id);
+               hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
+               st->st_new_iv_len = hasher->get_hash_size(hasher);
                passert(st->st_new_iv_len <= sizeof(st->st_new_iv));
 
                DBG(DBG_CRYPT,
                        DBG_dump_chunk("DH_i:", st->st_gi);
                        DBG_dump_chunk("DH_r:", st->st_gr);
                );
-               h->hash_init(&hash_ctx);
-               h->hash_update(&hash_ctx, st->st_gi.ptr, st->st_gi.len);
-               h->hash_update(&hash_ctx, st->st_gr.ptr, st->st_gr.len);
-               h->hash_final(st->st_new_iv, &hash_ctx);
+               
+               hasher->get_hash(hasher, st->st_gi, NULL);
+               hasher->get_hash(hasher, st->st_gr, st->st_new_iv);
+               hasher->destroy(hasher);
        }
 
        /* Oakley Keying Material
index 8a50f50..71c8685 100644 (file)
@@ -33,8 +33,6 @@
 #include "timer.h"
 #include "ipsec_doi.h"
 #include "log.h"
-#include "md5.h"
-#include "sha1.h"
 #include "crypto.h"
 #include "modecfg.h"
 #include "whack.h"
index 0f16cf0..24d70e5 100644 (file)
@@ -40,8 +40,6 @@
 #include "whack.h"
 #include "timer.h"
 #include "cookie.h"
-#include "sha1.h"
-#include "md5.h"
 #include "crypto.h"
 #include "vendor.h"
 #include "ike_alg.h"
index 99dda53..98287c2 100644 (file)
 #include <sys/types.h>
 
 #include <freeswan.h>
+
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
 #define HEADER_DES_LOCL_H   /* stupid trick to force prototype decl in <des.h> */
 #include <libdes/des.h>
 
 #include "constants.h"
 #include "defs.h"
 #include "log.h"
-#include "md5.h"
 #include "whack.h"
 #include "pem.h"
 
-/*
- * check the presence of a pattern in a character string
+/**
+ * Check the presence of a pattern in a character string
  */
-static bool
-present(const char* pattern, chunk_t* ch)
+static bool present(const char* pattern, chunk_t* ch)
 {
        u_int pattern_len = strlen(pattern);
 
@@ -52,29 +54,33 @@ present(const char* pattern, chunk_t* ch)
        return FALSE;
 }
 
-/*
- * compare string with chunk
+/**
+ * Compare string with chunk
  */
-static bool
-match(const char *pattern, const chunk_t *ch)
+static bool match(const char *pattern, const chunk_t *ch)
 {
        return ch->len == strlen(pattern) && strneq(pattern, ch->ptr, ch->len);
 }
 
-/*
- * find a boundary of the form -----tag name-----
+/**
+ * Find a boundary of the form -----tag name-----
  */
-static bool
-find_boundary(const char* tag, chunk_t *line)
+static bool find_boundary(const char* tag, chunk_t *line)
 {
        chunk_t name = chunk_empty;
 
        if (!present("-----", line))
+       {
                return FALSE;
+       }
        if (!present(tag, line))
+       {
                return FALSE;
+       }
        if (*line->ptr != ' ')
+       {
                return FALSE;
+       }
        line->ptr++;  line->len--;
 
        /* extract name */
@@ -94,11 +100,10 @@ find_boundary(const char* tag, chunk_t *line)
        return FALSE;
 }
 
-/*
- * eat whitespace
+/**
+ * Eat whitespace
  */
-static void
-eat_whitespace(chunk_t *src)
+static void eat_whitespace(chunk_t *src)
 {
        while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
        {
@@ -106,11 +111,10 @@ eat_whitespace(chunk_t *src)
        }
 }
 
-/*
- * extracts a token ending with a given termination symbol
+/**
+ * Extracts a token ending with a given termination symbol
  */
-static bool
-extract_token(chunk_t *token, char termination, chunk_t *src)
+static bool extract_token(chunk_t *token, char termination, chunk_t *src)
 {
        u_char *eot = memchr(src->ptr, termination, src->len);
 
@@ -118,7 +122,9 @@ extract_token(chunk_t *token, char termination, chunk_t *src)
        *token = chunk_empty;
 
        if (eot == NULL) /* termination symbol not found */
+       {
                return FALSE;
+       }
 
        /* extract token */
        token->ptr = src->ptr;
@@ -131,11 +137,10 @@ extract_token(chunk_t *token, char termination, chunk_t *src)
    return TRUE;
 }
 
-/*
- * extracts a name: value pair from the PEM header
+/**
+ * Extracts a name: value pair from the PEM header
  */
-static bool
-extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
+static bool extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
 {
        DBG(DBG_PARSING,
                DBG_log("  %.*s", (int)line->len, line->ptr);
@@ -143,8 +148,9 @@ extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
 
        /* extract name */
        if (!extract_token(name,':', line))
+       {
                return FALSE;
-
+       }
        eat_whitespace(line);
 
        /* extract value */
@@ -152,19 +158,21 @@ extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
        return TRUE;
 }
 
-/*
- *  fetches a new line terminated by \n or \r\n
+/**
+ * Fetches a new line terminated by \n or \r\n
  */
-static bool
-fetchline(chunk_t *src, chunk_t *line)
+static bool fetchline(chunk_t *src, chunk_t *line)
 {
        if (src->len == 0) /* end of src reached */
+       {
                return FALSE;
-
+       }
        if (extract_token(line, '\n', src))
        {
                if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
+               {
                        line->len--;  /* remove optional \r */
+               }       
        }
        else /*last line ends without newline */
        {
@@ -175,35 +183,39 @@ fetchline(chunk_t *src, chunk_t *line)
        return TRUE;
 }
 
-/*
- * decrypts a DES-EDE-CBC encrypted data block
+/**
+ * Decrypts a DES-EDE-CBC encrypted data block
  */
-static bool
-pem_decrypt_3des(chunk_t *blob, chunk_t *iv, const char *passphrase)
+static bool pem_decrypt_3des(chunk_t *blob, chunk_t *iv, char *passphrase)
 {
-       MD5_CTX context;
-       u_char digest[MD5_DIGEST_SIZE];
        u_char des_iv[DES_CBC_BLOCK_SIZE];
        u_char key[24];
        des_cblock *deskey = (des_cblock *)key;
        des_key_schedule ks[3];
        u_char padding, *last_padding_pos, *first_padding_pos;
+       hasher_t *hasher;
+       chunk_t digest;
+       chunk_t passphrase_chunk = { passphrase, strlen(passphrase) };
 
        /* Convert passphrase to 3des key */
-       MD5Init(&context);
-       MD5Update(&context, passphrase, strlen(passphrase));
-       MD5Update(&context, iv->ptr, iv->len);
-       MD5Final(digest, &context);
+       hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
+       if (hasher == NULL)
+       {
+               plog("  passphrase could not be hashed, no MD5 hasher available");              
+               return FALSE;
+       }       
+       hasher->allocate_hash(hasher, passphrase_chunk, NULL);
+       hasher->allocate_hash(hasher, *iv, &digest);
 
-       memcpy(key, digest, MD5_DIGEST_SIZE);
+       memcpy(key, digest.ptr, digest.len);
 
-       MD5Init(&context);
-       MD5Update(&context, digest, MD5_DIGEST_SIZE);
-       MD5Update(&context, passphrase, strlen(passphrase));
-       MD5Update(&context, iv->ptr, iv->len);
-       MD5Final(digest, &context);
+       hasher->get_hash(hasher, digest, NULL);
+       hasher->get_hash(hasher, passphrase_chunk, NULL);
+       hasher->get_hash(hasher, *iv, digest.ptr);
+       hasher->destroy(hasher);
 
-       memcpy(key + MD5_DIGEST_SIZE, digest, 24 - MD5_DIGEST_SIZE);
+       memcpy(key + digest.len, digest.ptr, 24 - digest.len);
+       free(digest.ptr);
 
        (void) des_set_key(&deskey[0], ks[0]);
        (void) des_set_key(&deskey[1], ks[1]);
@@ -224,7 +236,9 @@ pem_decrypt_3des(chunk_t *blob, chunk_t *iv, const char *passphrase)
        while (--last_padding_pos > first_padding_pos)
        {
                if (*last_padding_pos != padding)
+               {
                        return FALSE;
+               }
        }
 
        /* remove padding */
@@ -232,21 +246,24 @@ pem_decrypt_3des(chunk_t *blob, chunk_t *iv, const char *passphrase)
        return TRUE;
 }
 
-/*
- * optionally prompts for a passphrase before decryption
+/**
+ * Optionally prompts for a passphrase before decryption
  * currently we support DES-EDE3-CBC, only
  */
-static err_t
-pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass, const char* label)
+static err_t pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass,
+                                                const char* label)
 {
        DBG(DBG_CRYPT,
                DBG_log("  decrypting file using 'DES-EDE3-CBC'");
        )
        if (iv->len != DES_CBC_BLOCK_SIZE)
+       {
                return "size of DES-EDE3-CBC IV is not 8 bytes";
-
+       }
        if (pass == NULL)
+       {
                return "no passphrase available";
+       }
 
        /* do we prompt for the passphrase? */
        if (pass->prompt && pass->fd != NULL_FD)
@@ -262,8 +279,9 @@ pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass, const char* label)
                        int n;
 
                        if (i > 0)
-                       whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
-
+                       {
+                               whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
+                       }
                        n = read(pass->fd, pass->secret, PROMPT_PASS_LEN);
 
                        if (n == -1)
@@ -303,9 +321,13 @@ pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass, const char* label)
        else
        {
                if (pem_decrypt_3des(blob, iv, pass->secret))
+               {
                        return NULL;
+               }
                else
+               {
                        return "invalid passphrase";
+               }
        }
 }
 
@@ -314,8 +336,7 @@ pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass, const char* label)
  *  RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
  *  RFC 934 Message Encapsulation, January 1985
  */
-err_t
-pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
+err_t pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
 {
        typedef enum {
                PEM_PRE    = 0,
@@ -381,10 +402,13 @@ pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
 
                                /* we are looking for a name: value pair */
                                if (!extract_parameter(&name, &value, &line))
+                               {
                                        continue;
-
+                               }
                                if (match("Proc-Type", &name) && *value.ptr == '4')
-                                               encrypted = TRUE;
+                               {
+                                       encrypted = TRUE;
+                               }
                                else if (match("DEK-Info", &name))
                                {
                                        const char *ugh = NULL;
@@ -392,18 +416,22 @@ pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
                                        chunk_t dek;
 
                                        if (!extract_token(&dek, ',', &value))
+                                       {
                                                dek = value;
+                                       }
 
                                        /* we support DES-EDE3-CBC encrypted files, only */
                                        if (!match("DES-EDE3-CBC", &dek))
+                                       {
                                                return "we support DES-EDE3-CBC encrypted files, only";
-
+                                       }
                                        eat_whitespace(&value);
                                        ugh = ttodata(value.ptr, value.len, 16,
                                                                  iv.ptr, MAX_DIGEST_LEN, &len);
                                        if (ugh)
+                                       {
                                                return "error in IV";
-
+                                       }
                                        iv.len = len;
                                }
                        }
@@ -415,7 +443,9 @@ pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
 
                                /* remove any trailing whitespace */
                                if (!extract_token(&data ,' ', &line))
+                               {
                                        data = line;
+                               }
 
                                /* check for PGP armor checksum */
                                if (*data.ptr == '=')
@@ -451,10 +481,15 @@ pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
        blob->len = dst.len;
 
        if (state != PEM_POST)
+       {
                return "file coded in unknown format, discarded";
-
+       }
        if (encrypted)
+       {
                return pem_decrypt(blob, &iv, pass, label);
+       }
        else
+       {       
                return NULL;
+       }
 }
index 514e39a..999a771 100644 (file)
@@ -19,6 +19,9 @@
 #include <freeswan.h>
 #include <ipsec_policy.h>
 
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
 #include "constants.h"
 #include "defs.h"
 #include "mp_defs.h"
@@ -26,7 +29,6 @@
 #include "id.h"
 #include "pgp.h"
 #include "certs.h"
-#include "md5.h"
 #include "whack.h"
 #include "pkcs1.h"
 #include "keys.h"
@@ -246,12 +248,19 @@ parse_pgp_pubkey_packet(chunk_t *packet, pgpcert_t *cert)
 
                if (version == 3)
                {
+                       hasher_t *hasher;
+
                        /* a V3 fingerprint is the MD5 hash of modulus and public exponent */
-                       MD5_CTX context;
-                       MD5Init(&context);
-                       MD5Update(&context, cert->modulus.ptr, cert->modulus.len);
-                       MD5Update(&context, cert->publicExponent.ptr, cert->publicExponent.len);
-                       MD5Final(cert->fingerprint, &context);
+
+                       hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);     
+                       if (hasher == NULL)
+                       {
+                               plog("  computation of V3 key ID failed, no MD5 hasher is available");
+                               return FALSE;
+                       }
+                       hasher->get_hash(hasher, cert->modulus, NULL);
+                       hasher->get_hash(hasher, cert->publicExponent, cert->fingerprint);
+                       hasher->destroy(hasher);
                }
                else
                {
index ba1c9e4..6f2ab22 100644 (file)
 #include <asn1/asn1_parser.h>
 #include <asn1/oid.h>
 #include <crypto/rngs/rng.h>
+#include <crypto/hashers/hasher.h>
 
 #include "constants.h"
 #include "defs.h"
 #include "mp_defs.h"
 #include "log.h"
 #include "pkcs1.h"
-#include "md2.h"
-#include "md5.h"
-#include "sha1.h"
 
 const struct fld RSA_private_field[] =
 {
@@ -287,84 +285,27 @@ end:
 /**
  *  Compute a digest over a binary blob
  */
-bool compute_digest(chunk_t tbs, int alg, chunk_t *digest)
+bool compute_digest(chunk_t tbs, int oid, chunk_t *digest)
 {
-       switch (alg)
-       {
-       case OID_MD2:
-       case OID_MD2_WITH_RSA:
-               {
-                       MD2_CTX context;
-
-                       MD2Init(&context);
-                       MD2Update(&context, tbs.ptr, tbs.len);
-                       MD2Final(digest->ptr, &context);
-                       digest->len = MD2_DIGEST_SIZE;
-                       return TRUE;
-               }
-        case OID_MD5:
-        case OID_MD5_WITH_RSA:
-               {
-                       MD5_CTX context;
+       hasher_t *hasher;
+       hash_algorithm_t alg = hasher_algorithm_from_oid(oid);
 
-                       MD5Init(&context);
-                       MD5Update(&context, tbs.ptr, tbs.len);
-                       MD5Final(digest->ptr, &context);
-                       digest->len = MD5_DIGEST_SIZE;
-                       return TRUE;
-               }
-        case OID_SHA1:
-        case OID_SHA1_WITH_RSA:
-        case OID_SHA1_WITH_RSA_OIW:
-               {
-                       SHA1_CTX context;
+       if (alg == HASH_UNKNOWN)
+       {
+               digest->len = 0;
+               return FALSE;
+       }
 
-                       SHA1Init(&context);
-                       SHA1Update(&context, tbs.ptr, tbs.len);
-                       SHA1Final(digest->ptr, &context);
-                       digest->len = SHA1_DIGEST_SIZE;
-                       return TRUE;
-               }
-        case OID_SHA256:
-        case OID_SHA256_WITH_RSA:
-               {
-                       sha256_context context;
-
-                       sha256_init(&context);
-                       sha256_write(&context, tbs.ptr, tbs.len);
-                       sha256_final(&context);
-                       memcpy(digest->ptr, context.sha_out, SHA2_256_DIGEST_SIZE);
-                       digest->len = SHA2_256_DIGEST_SIZE;
-                       return TRUE;
-               }
-        case OID_SHA384:
-        case OID_SHA384_WITH_RSA:
-               {
-                       sha512_context context;
-
-                       sha384_init(&context);
-                       sha512_write(&context, tbs.ptr, tbs.len);
-                       sha512_final(&context);
-                       memcpy(digest->ptr, context.sha_out, SHA2_384_DIGEST_SIZE);
-                       digest->len = SHA2_384_DIGEST_SIZE;
-                       return TRUE;
-               }
-        case OID_SHA512:
-        case OID_SHA512_WITH_RSA:
-               {
-                       sha512_context context;
-
-                       sha512_init(&context);
-                       sha512_write(&context, tbs.ptr, tbs.len);
-                       sha512_final(&context);
-                       memcpy(digest->ptr, context.sha_out, SHA2_512_DIGEST_SIZE);
-                       digest->len = SHA2_512_DIGEST_SIZE;
-                       return TRUE;
-               }
-        default:
+       hasher = lib->crypto->create_hasher(lib->crypto, alg);
+       if (hasher == NULL)
+       {
                digest->len = 0;
                return FALSE;
        }
+       digest->len = hasher->get_hash_size(hasher);
+       hasher->get_hash(hasher, tbs, digest->ptr);
+       hasher->destroy(hasher);
+       return TRUE;
 }
 
 /**
index d19a75c..618c09b 100644 (file)
@@ -66,9 +66,7 @@
 #include "crl.h"
 #include "fetch.h"
 #include "xauth.h"
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h"     /* requires sha1.h and md5.h */
+#include "crypto.h"
 #include "nat_traversal.h"
 #include "virtual.h"
 #include "timer.h"
index 3b75c1d..6bcc3f1 100644 (file)
@@ -34,9 +34,7 @@
 #include "log.h"
 #include "spdb.h"
 #include "whack.h"
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
+#include "crypto.h"
 #include "alg_info.h"
 #include "kernel_alg.h"
 #include "ike_alg.h"
index 9374181..b19b2ca 100644 (file)
 #include "whack.h"
 #include "demux.h"      /* needs packet.h */
 #include "ipsec_doi.h"  /* needs demux.h and state.h */
-
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
+#include "crypto.h"
 
 /*
  * Global variables: had to go somewhere, might as well be this file.
index facc953..0fcf186 100644 (file)
 #include <sys/queue.h>
 #include <freeswan.h>
 
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
 #include "constants.h"
 #include "defs.h"
 #include "log.h"
-#include "md5.h"
 #include "connections.h"
 #include "packet.h"
 #include "demux.h"
@@ -90,27 +92,24 @@ struct vid_struct {
                unsigned short flags;
                const char *data;
                const char *descr;
-               char *vid;
-               u_int vid_len;
+               chunk_t vid;
 };
 
 #define DEC_MD5_VID_D(id,str,descr) \
-               { VID_##id, VID_MD5HASH, str, descr, NULL, 0 },
+               { VID_##id, VID_MD5HASH, str, descr, { NULL, 0 } },
 #define DEC_MD5_VID(id,str) \
-               { VID_##id, VID_MD5HASH, str, NULL, NULL, 0 },
-#define DEC_FSWAN_VID(id,str,descr) \
-               { VID_##id, VID_FSWAN_HASH, str, descr, NULL, 0 },
+               { VID_##id, VID_MD5HASH, str, NULL, { NULL, 0 } },
 
 static struct vid_struct _vid_tab[] = {
 
                /* Implementation names */
 
-               { VID_OPENPGP, VID_STRING, "OpenPGP10171", "OpenPGP", NULL, 0 },
+               { VID_OPENPGP, VID_STRING, "OpenPGP10171", "OpenPGP", { NULL, 0 } },
 
                DEC_MD5_VID(KAME_RACOON, "KAME/racoon")
 
                { VID_MS_NT5, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
-                               "MS NT5 ISAKMPOAKLEY", NULL, NULL, 0 },
+                               "MS NT5 ISAKMPOAKLEY", NULL, { NULL, 0 } },
 
                DEC_MD5_VID(SSH_SENTINEL, "SSH Sentinel")
                DEC_MD5_VID(SSH_SENTINEL_1_1, "SSH Sentinel 1.1")
@@ -153,14 +152,13 @@ static struct vid_struct _vid_tab[] = {
 
                /* note: md5('CISCO-UNITY') = 12f5f28c457168a9702d9fe274cc02d4 */
                { VID_CISCO_UNITY, VID_KEEP, NULL, "Cisco-Unity",
-                               "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00",
-                               16 },
+                 { "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00", 16 } },
 
-               { VID_CISCO3K, VID_KEEP | VID_SUBSTRING_MATCH,
-                 NULL, "Cisco VPN 3000 Series" , "\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a\x50", 14},
+               { VID_CISCO3K, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "Cisco VPN 3000 Series" ,
+                 { "\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a\x50", 14 } },
 
                { VID_CISCO_IOS, VID_KEEP | VID_SUBSTRING_MATCH, 
-                 NULL, "Cisco IOS Device", "\x3e\x98\x40\x48", 4},
+                 NULL, "Cisco IOS Device", { "\x3e\x98\x40\x48", 4 } },
 
                /*
                 * Timestep VID seen:
@@ -168,31 +166,25 @@ static struct vid_struct _vid_tab[] = {
                 *     = 'TIMESTEP 1 SGW 1520 315 2.01E013'
                 */
                { VID_TIMESTEP, VID_STRING | VID_SUBSTRING_DUMPASCII, "TIMESTEP",
-                               NULL, NULL, 0 },
+                               NULL, { NULL, 0 } },
 
                /*
                 * Netscreen:
                 * 4865617274426561745f4e6f74696679386b0100  (HeartBeat_Notify + 386b0100)
                 */
                { VID_MISC_HEARTBEAT_NOTIFY, VID_STRING | VID_SUBSTRING_DUMPHEXA,
-                               "HeartBeat_Notify", "HeartBeat Notify", NULL, 0 },
-
+                               "HeartBeat_Notify", "HeartBeat Notify", { NULL, 0 } },
                /*
                 * MacOS X
                 */
                { VID_MACOSX, VID_STRING|VID_SUBSTRING_DUMPHEXA, "Mac OSX 10.x",
-                 "\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62", NULL, 0},
+                 "\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62", { NULL, 0 } },
 
-               /*
-                * Openswan
-                */
-               DEC_FSWAN_VID(OPENSWAN2, "Openswan 2.2.0", "Openswan 2.2.0")
-               
                /* NCP */
                { VID_NCP_SERVER, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Server",
-                       "\xc6\xf5\x7a\xc3\x98\xf4\x93\x20\x81\x45\xb7\x58", 12},
+                       { "\xc6\xf5\x7a\xc3\x98\xf4\x93\x20\x81\x45\xb7\x58", 12 } },
                { VID_NCP_CLIENT, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Client",
-                       "\xeb\x4c\x1b\x78\x8a\xfd\x4a\x9c\xb7\x73\x0a\x68", 12},
+                       { "\xeb\x4c\x1b\x78\x8a\xfd\x4a\x9c\xb7\x73\x0a\x68", 12 } },
 
                /*
                 * Windows Vista (and Windows Server 2008?)
@@ -297,10 +289,10 @@ static struct vid_struct _vid_tab[] = {
                /* misc */
                
                { VID_MISC_XAUTH, VID_KEEP, NULL, "XAUTH",
-                       "\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 },
+                       { "\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 } },
 
                { VID_MISC_DPD, VID_KEEP, NULL, "Dead Peer Detection",
-                       "\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00", 16 },
+                       { "\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00", 16 } },
 
                DEC_MD5_VID(MISC_FRAGMENTATION, "FRAGMENTATION")
                
@@ -310,10 +302,10 @@ static struct vid_struct _vid_tab[] = {
                 * Cisco VPN 3000
                 */
                { VID_MISC_FRAGMENTATION, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
-                       "FRAGMENTATION", NULL, NULL, 0 },
+                       "FRAGMENTATION", NULL, { NULL, 0 } },
 
                /* -- */
-               { 0, 0, NULL, NULL, NULL, 0 }
+               { 0, 0, NULL, NULL, { NULL, 0 } }
 
 };
 
@@ -323,61 +315,23 @@ static int _vid_struct_init = 0;
 
 void init_vendorid(void)
 {
+       hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
        struct vid_struct *vid;
-       MD5_CTX ctx;
-       int i;
 
        for (vid = _vid_tab; vid->id; vid++)
        {
                if (vid->flags & VID_STRING)
                {
                        /** VendorID is a string **/
-                       vid->vid = strdup(vid->data);
-                       vid->vid_len = strlen(vid->data);
+                       vid->vid = chunk_create((u_char *)vid->data, strlen(vid->data));
+                       vid->vid = chunk_clone(vid->vid);
                }
                else if (vid->flags & VID_MD5HASH)
                {
+                       chunk_t vid_data = { (u_char *)vid->data, strlen(vid->data) };
+                       
                        /** VendorID is a string to hash with MD5 **/
-                       char *vidm =  malloc(MD5_DIGEST_SIZE);
-
-                       vid->vid = vidm;
-                       if (vidm)
-                       {
-                               MD5Init(&ctx);
-                               MD5Update(&ctx, (const u_char *)vid->data, strlen(vid->data));
-                               MD5Final(vidm, &ctx);
-                               vid->vid_len = MD5_DIGEST_SIZE;
-                       }
-               }
-               else if (vid->flags & VID_FSWAN_HASH)
-               {
-                       /** FreeS/WAN 2.00+ specific hash **/
-#define FSWAN_VID_SIZE 12
-                       unsigned char hash[MD5_DIGEST_SIZE];
-                       char *vidm =  malloc(FSWAN_VID_SIZE);
-
-                       vid->vid = vidm;
-                       if (vidm)
-                       {
-                               MD5Init(&ctx);
-                               MD5Update(&ctx, (const u_char *)vid->data, strlen(vid->data));
-                               MD5Final(hash, &ctx);
-                               vidm[0] = 'O';
-                               vidm[1] = 'E';
-#if FSWAN_VID_SIZE - 2 <= MD5_DIGEST_SIZE
-                               memcpy(vidm + 2, hash, FSWAN_VID_SIZE - 2);
-#else
-                               memcpy(vidm + 2, hash, MD5_DIGEST_SIZE);
-                               memset(vidm + 2 + MD5_DIGEST_SIZE, '\0',
-                                               FSWAN_VID_SIZE - 2 - MD5_DIGEST_SIZE);
-#endif
-                               for (i = 2; i < FSWAN_VID_SIZE; i++)
-                               {
-                                       vidm[i] &= 0x7f;
-                                       vidm[i] |= 0x40;
-                               }
-                               vid->vid_len = FSWAN_VID_SIZE;
-                       }
+                       hasher->allocate_hash(hasher, vid_data, &vid->vid);
                }
 
                if (vid->descr == NULL)
@@ -386,6 +340,7 @@ void init_vendorid(void)
                        vid->descr = vid->data;
                }
        }
+       hasher->destroy(hasher);
        _vid_struct_init = 1;
 }
 
@@ -397,7 +352,7 @@ void free_vendorid(void)
        {
                if (vid->flags & (VID_STRING | VID_MD5HASH | VID_FSWAN_HASH))
                {
-                       free(vid->vid);
+                       free(vid->vid.ptr);
                }
        }
 }
@@ -462,7 +417,7 @@ static void handle_known_vendorid (struct msg_digest *md, const char *vidstr,
                memset(vid_dump, 0, sizeof(vid_dump));
                snprintf(vid_dump, sizeof(vid_dump), "%s ",
                                 vid->descr ? vid->descr : "");
-               for (i = strlen(vid_dump), j = vid->vid_len;
+               for (i = strlen(vid_dump), j = vid->vid.len;
                         j < len && i < sizeof(vid_dump) - 2;
                         i += 2, j++)
                {
@@ -502,19 +457,19 @@ void handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
         */
        for (pvid = _vid_tab; pvid->id; pvid++)
        {
-               if (pvid->vid && vid && pvid->vid_len && len)
+               if (pvid->vid.ptr && vid && pvid->vid.len && len)
                {
-                       if (pvid->vid_len == len)
+                       if (pvid->vid.len == len)
                        {
-                               if (memeq(pvid->vid, vid, len))
+                               if (memeq(pvid->vid.ptr, vid, len))
                                {
                                        handle_known_vendorid(md, vid, len, pvid);
                                        return;
                                }
                        }
-                       else if ((pvid->vid_len < len) && (pvid->flags & VID_SUBSTRING))
+                       else if ((pvid->vid.len < len) && (pvid->flags & VID_SUBSTRING))
                        {
-                               if (memeq(pvid->vid, vid, pvid->vid_len))
+                               if (memeq(pvid->vid.ptr, vid, pvid->vid.len))
                                {
                                        handle_known_vendorid(md, vid, len, pvid);
                                        return;
@@ -556,13 +511,13 @@ bool out_vendorid (u_int8_t np, pb_stream *outs, enum known_vendorid vid)
 
        if (pvid->id != vid)
                return STF_INTERNAL_ERROR; /* not found */
-       if (!pvid->vid)
+       if (!pvid->vid.ptr)
                return STF_INTERNAL_ERROR; /* not initialized */
 
        DBG(DBG_EMITTING,
                DBG_log("out_vendorid(): sending [%s]", pvid->descr)
        )
        return out_generic_raw(np, &isakmp_vendor_id_desc, outs,
-                               pvid->vid, pvid->vid_len, "V_ID");
+                               pvid->vid.ptr, pvid->vid.len, "V_ID");
 }
 
index 6304c5e..9ea5b7a 100644 (file)
@@ -47,12 +47,11 @@ enum known_vendorid {
   VID_TIMESTEP                  = 28,
   VID_SAFENET                   = 29,
   VID_MACOSX                    = 30,
-  VID_OPENSWAN2                 = 31,
-  VID_NCP_SERVER                = 32,
-  VID_NCP_CLIENT                = 33,
-  VID_VISTA_AUTHIP              = 34,
-  VID_VISTA_AUTHIP2             = 35,
-  VID_VISTA_AUTHIP3             = 36,
+  VID_NCP_SERVER                = 31,
+  VID_NCP_CLIENT                = 32,
+  VID_VISTA_AUTHIP              = 33,
+  VID_VISTA_AUTHIP2             = 34,
+  VID_VISTA_AUTHIP3             = 35,
 
   VID_STRONGSWAN                = 37,
   VID_STRONGSWAN_2_2_0          = 38,
index 2840116..18e26ab 100644 (file)
@@ -29,6 +29,7 @@
 #include <asn1/asn1.h>
 #include <asn1/asn1_parser.h>
 #include <asn1/oid.h>
+#include <crypto/hashers/hasher.h>
 
 #include "constants.h"
 #include "defs.h"
@@ -44,7 +45,6 @@
 #include "whack.h"
 #include "fetch.h"
 #include "ocsp.h"
-#include "sha1.h"
 
 /**
  * Chained lists of X.509 end certificates
@@ -1488,16 +1488,18 @@ void gntoid(struct id *id, const generalName_t *gn)
  * Compute the subjectKeyIdentifier according to section 4.2.1.2 of RFC 3280
  * as the 160 bit SHA-1 hash of the public key
  */
-void compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID)
+bool compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID)
 {
-       SHA1_CTX context;
-
-       SHA1Init(&context);
-       SHA1Update(&context
-                         , cert->subjectPublicKey.ptr
-                         , cert->subjectPublicKey.len);
-       SHA1Final(subjectKeyID.ptr, &context);
-       subjectKeyID.len = SHA1_DIGEST_SIZE;
+       hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+
+       if (hasher == NULL)
+       {
+               plog("  no SHA-1 hasher available to compute subjectKeyID");
+               return FALSE;
+       }
+       hasher->get_hash(hasher, cert->subjectPublicKey, subjectKeyID.ptr);
+       hasher->destroy(hasher);
+       return TRUE;
 }
 
 /**
index 7a46c5c..ec3203d 100644 (file)
@@ -108,7 +108,7 @@ extern int dntoa_or_null(char *dst, size_t dstlen, chunk_t dn
        , const char* null_dn);
 extern err_t atodn(char *src, chunk_t *dn);
 extern void gntoid(struct id *id, const generalName_t *gn);
-extern void compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID);
+extern bool compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID);
 extern void select_x509cert_id(x509cert_t *cert, struct id *end_id);
 extern bool parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert);
 extern time_t parse_time(chunk_t blob, int level0);