Branch: Tag:

2003-03-13

2003-03-13 14:55:22 by Niels Möller <nisse@lysator.liu.se>

New file, with hash glue.

Rev: src/post_modules/Nettle/hash.cmod:1.1

1: + /* hash.cmod -*- c -*- */    -  + #include "global.h" + RCSID("$Id: hash.cmod,v 1.1 2003/03/13 14:55:22 nisse Exp $"); + #include "interpret.h" + #include "svalue.h" +  + /* For this_object() */ + #include "object.h" + #include "module_support.h" +  + #include "nettle_config.h" +  + #ifdef HAVE_LIBNETTLE +  + #include "nettle.h" +  + #include <nettle/md5.h> + #include <nettle/sha.h> + #include <nettle/nettle-meta.h> +  + #include <assert.h> + #include <stdio.h> + #include <stdarg.h> +  + #if 0 + static void + werror(const char *format, ...) + { +  va_list args; +  +  va_start(args, format); +  vfprintf(stderr, format, args); +  va_end(args); + } + #else + #define werror(x) + #endif +  + PIKECLASS nettle_hash + { +  CVAR const struct nettle_hash *meta; +  +  PIKEFUN string name() +  { +  if (!THIS->meta) +  Pike_error("nettle_hash not properly initialized."); +  +  push_string(make_shared_string(THIS->meta->name)); +  } +  +  PIKEFUN int digest_size() +  { +  if (!THIS->meta) +  Pike_error("nettle_hash not properly initialized."); +  +  push_int(THIS->meta->digest_size); +  } +  +  PIKEFUN int block_size() +  { +  if (!THIS->meta) +  Pike_error("nettle_hash not properly initialized."); +  +  push_int(THIS->meta->block_size); +  } +  INIT +  { +  werror("nettle_hash->INIT\n"); +  THIS->meta = NULL; +  } + } +  + #define GET_META(o) \ + ( ((struct nettle_hash_struct *) get_storage((o), nettle_hash_program)) \ +  ->meta) +  + /* The algorithm objects have to be implemented in pike. */ +  + PIKECLASS hash_instance + { +  INHERIT nettle_hash; +  CVAR void *ctx; +  +  /* FIXME: Create should copy state from the other object, if +  * provided. */ +  +  PIKEFUN object update(string data) +  { +  const struct nettle_hash *meta = GET_META(this_object()); +  +  if (!THIS->ctx || !meta) +  Pike_error("hash_state not properly initialized."); +  +  NO_WIDE_STRING(data); +  meta->update(THIS->ctx, data->len, data->str); +  +  push_object(this_object()); +  } +  +  PIKEFUN string digest(int|void arg) +  { +  const struct nettle_hash *meta; +  struct pike_string *digest; +  unsigned length; +  +  if (! THIS->ctx) +  Pike_error("hash_state not properly initialized."); +  +  meta = GET_META(this_object()); +  assert(meta); +  +  if (!arg) +  length = meta->digest_size; +  else +  { +  if (arg->type != PIKE_T_INT) +  Pike_error("Bad argument type"); +  if (arg->u.integer <= 0) +  Pike_error("Invalid argument, must be positive.\n"); +  if (arg->u.integer > meta->digest_size) +  Pike_error("Unsupported digest length"); +  +  length = arg->u.integer; +  } +  +  digest = begin_shared_string(length); +  meta->digest(THIS->ctx, length, digest->str); +  push_string(end_shared_string(digest)); +  } +  +  INIT +  { +  werror("hash_instance->INIT\n"); +  THIS->ctx = NULL; +  } +  EXIT +  { +  werror("hash_instance->EXIT\n"); +  if (THIS->ctx) +  { +  const struct nettle_hash *meta = GET_META(this_object()); +  assert(meta); +  memset(THIS->ctx, 0, meta->context_size); +  } +  } + } +  + /*! @class nettle_md5 +  *! Internal mixin class, intended to be multiply inherited +  *! together with nettle_hash. */ +  + PIKECLASS nettle_md5 + { +  INIT +  { +  struct nettle_hash_struct *nettle_hash +  = (struct nettle_hash_struct *) get_storage(this_object(), +  nettle_hash_program); +  +  werror("nettle_md5->INIT\n"); +  +  if (nettle_hash || !nettle_hash->meta) +  nettle_hash->meta = &nettle_md5; +  else +  /* Can't call Pike_error here. +  * Pike_error("Can't initialize this object.\n"); */ +  werror("nettle_md5->INIT failed\n"); +  } + } +  + PIKECLASS md5_state + { +  INHERIT nettle_md5; +  INHERIT hash_instance; +  CVAR struct md5_ctx md5; +  +  INIT +  { +  struct hash_instance_struct *instance +  = (struct hash_instance_struct *) get_storage(this_object(), +  hash_instance_program); +  werror("md5_state->INIT\n"); +  +  assert(instance); +  +  md5_init(&THIS->md5); +  instance->ctx = &THIS->md5; +  } + } +  + /*! @class nettle_sha1 +  *! Internal mixin class, intended to be multiply inherited +  *! together with nettle_hash. */ +  + PIKECLASS nettle_sha1 + { +  INIT +  { +  struct nettle_hash_struct *nettle_hash +  = (struct nettle_hash_struct *) get_storage(this_object(), +  nettle_hash_program); +  +  werror("nettle_sha1->INIT\n"); +  +  if (nettle_hash || !nettle_hash->meta) +  nettle_hash->meta = &nettle_sha1; +  else +  /* Can't call Pike_error here. +  * Pike_error("Can't initialize this object.\n"); */ +  werror("nettle_sha1->INIT failed\n"); +  } + } +  + PIKECLASS sha1_state + { +  INHERIT nettle_sha1; +  INHERIT hash_instance; +  CVAR struct sha1_ctx sha1; +  +  INIT +  { +  struct hash_instance_struct *instance +  = (struct hash_instance_struct *) get_storage(this_object(), +  hash_instance_program); +  werror("sha1_state->INIT\n"); +  +  assert(instance); +  +  sha1_init(&THIS->sha1); +  instance->ctx = &THIS->sha1; +  } + } +  +  + void + hash_init(void) + { +  werror("Nettle, hash init\n"); +  INIT; + } +  + void + hash_exit(void) + { +  werror("Nettle, hash exit\n"); +  EXIT; + } +  + #endif /* HAVE_LIBNETTLE */   Newline at end of file added.