Nmap Development mailing list archives

Re: [RFC] Lua bindings for OpenSSL md5 and sha1 hash functions


From: "Philip Pickering" <pgpickering () gmail com>
Date: Sun, 3 Aug 2008 16:51:28 +0200

Hi!

I just added hash to NSE in the SVN. It does roughly the
same, having hash.md5 and hash.sha1 to get hex strings
and hash.md5bin and hash.sha1bin to get their binary
equivalents.

It binds to the md5 and sha1 functions which have been
added to nbase recently, so they are independent of
having openssl on your machine.

Regarding adding bin2hex to binlib (which has by now been
merged into svn, too): the same behavior can be achieved
using
_, hexstring = bin.unpack("H" .. #binstring, binstring)


cheers,
Philip


2008/8/3 Sven Klemm <sven () c3d2 de>:
Thomas Buchanan wrote:

Matthew Boyle wrote:

i think it would be better to have separate functions for the raw digest
output, rather than using the boolean field.  digest_{md5,sha1}_raw(),
perhaps?


I have no strong preference either way.  The library I used had it with
the optional boolean flag, and I noticed the LuaCrypto library you mentioned
also did it that way.  One question that comes to mind if it's split into
separate functions is do you still have the hex output as the short function
name, or do you have digest_{md5,sha1}_hex()?

Or, would you prefer to have the API that LuaCrypto has, where there is
only a single function for digests, and the hash algorithm to be used is
passed in as an argument?  Then you would have digest(algo, string, raw) or
perhaps digest(algo, string) and digest_raw(algo, string).


I enhanced and updated the patch a bit.

I changed the digest functions to always return binary data and added a
bin2hex function to format binary data into a hex string. Implementing it
this way leads to the least code duplication in the wrapper, but maybe it's
a good idea to add convenience functions that directly return hex-encoded
strings.

I think the bin2hex function might be a good candidate for moving into the
new bin library.

I also added a function for converting binary coded bignums to decimal
strings and functions to get random bytes from openssl.

Cheers,
Sven

--
Sven Klemm
http://cthulhu.c3d2.de/~sven/


Index: nselib-bin/Makefile.in
===================================================================
--- nselib-bin/Makefile.in      (revision 9309)
+++ nselib-bin/Makefile.in      (working copy)
@@ -12,15 +12,20 @@
 LIBTOOL= ./libtool
 LTFLAGS = --tag=CC --silent

-all: bit.so
+all: bit.so openssl.so

 bit.so: bit.c @LIBTOOL_DEPS@
       $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) @LUAINCLUDE@ $(CFLAGS) -c
bit.c
       $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -avoid-version -module -rpath
/usr/local/lib -o bit.la bit.lo
       mv .libs/bit.so bit.so

+openssl.so: openssl.c @LIBTOOL_DEPS@
+       $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) @LUAINCLUDE@ $(CFLAGS) -c
openssl.c
+       $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -avoid-version -module
-rpath /usr/local/lib -o openssl.la openssl.lo
+       mv .libs/openssl.so openssl.so
+
 clean:
-       rm -f bit.so *.la *.lo
+       rm -f bit.so openssl.so *.la *.lo
       rm -rf .libs

 distclean: clean
Index: nselib-bin/openssl.c
===================================================================
--- nselib-bin/openssl.c        (revision 0)
+++ nselib-bin/openssl.c        (revision 0)
@@ -0,0 +1,108 @@
+#include "../nmap_config.h"
+
+#if HAVE_OPENSSL
+
+/* OpenSSL library for lua
+ * adapted from lmd5 library (http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/)
+ * Original code written by Luiz Henrique de Figueiredo
<lhf () tecgraf puc-rio br>
+ * Adapted for NMap by Thomas Buchanan <tbuchanan () thecompassgrp net>
+ * bignum and rand_bytes functions added by Sven Klemm <sven () c3d2 de>
+ */
+
+#include "openssl.h"
+#include <openssl/crypto.h>
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+
+static int l_digest_md5(lua_State *L) /** digest_md5(string s) */
+{
+  unsigned char digest[16];
+  size_t l;
+  const char *s=luaL_checklstring(L,1,&l);
+  MD5_CTX c;
+  MD5_Init(&c);
+  MD5_Update(&c,s,l);
+  MD5_Final(digest,&c);
+
+  lua_pushlstring( L, (char *)digest, sizeof(digest) );
+  return 1;
+}
+
+static int l_digest_sha1(lua_State *L) /** digest_sha1(string s) */
+{
+  unsigned char digest[20];
+  size_t l;
+  const char *s=luaL_checklstring(L,1,&l);
+  SHA_CTX c;
+  SHA1_Init(&c);
+  SHA1_Update(&c,s,l);
+  SHA1_Final(digest,&c);
+
+  lua_pushlstring( L, (char *)digest, sizeof(digest) );
+  return 1;
+}
+
+static int l_bin2hex( lua_State *L ) /** bin2hex( string s ) */
+{
+  size_t len;
+  const unsigned char * s = (unsigned char *) luaL_checklstring( L, 1, &len
);
+  char * result = (char *) malloc( len * 2 + 1 );
+  unsigned int i;
+
+  for ( i = 0; i < len; i++ )
+    sprintf( result + 2 * i, "%02x", s[i] );
+
+  lua_pushlstring( L, result, len * 2 );
+  free( result );
+  return 1;
+}
+
+static int l_bignum_bin2dec( lua_State *L ) /** bignum_bin2dec(string s) */
+{
+  size_t len;
+  const unsigned char * s = (unsigned char *) luaL_checklstring( L, 1, &len
);
+  BIGNUM * num = BN_bin2bn( s, len, NULL );
+  char * result = BN_bn2dec( num );
+  lua_pushstring( L, result );
+  BN_clear_free( num );
+  OPENSSL_free( result );
+  return 1;
+}
+
+static int l_rand_bytes( lua_State *L ) /** rand_bytes( number bytes ) */
+{
+  size_t len = luaL_checkint( L, 1 );
+  unsigned char * result = (unsigned char *) malloc( len );
+  RAND_bytes( result, len );
+  lua_pushlstring( L, (char *) result, len );
+  free( result );
+  return 1;
+}
+
+static int l_rand_pseudo_bytes( lua_State *L ) /** rand_pseudo_bytes(
number bytes ) */
+{
+  size_t len = luaL_checkint( L, 1 );
+  unsigned char * result = (unsigned char *) malloc( len );
+  RAND_pseudo_bytes( result, len );
+  lua_pushlstring( L, (char *) result, len );
+  free( result );
+  return 1;
+}
+
+static const struct luaL_reg openssllib[] = {
+  { "digest_md5", l_digest_md5 },
+  { "digest_sha1", l_digest_sha1 },
+  { "bin2hex", l_bin2hex },
+  { "bignum_bin2dec", l_bignum_bin2dec },
+  { "rand_bytes", l_rand_bytes},
+  { "rand_pseudo_bytes", l_rand_pseudo_bytes},
+  { NULL, NULL }
+};
+
+LUALIB_API int luaopen_openssl(lua_State *L) {
+  luaL_openlib(L, OPENSSLLIBNAME, openssllib, 0);
+  return 1;
+}
+#endif
Index: nselib-bin/openssl.h
===================================================================
--- nselib-bin/openssl.h        (revision 0)
+++ nselib-bin/openssl.h        (revision 0)
@@ -0,0 +1,17 @@
+#include "../nmap_config.h"
+
+#if HAVE_OPENSSL
+
+#ifndef OPENSSLLIB
+#define OPENSSLLIB
+
+#define OPENSSLLIBNAME "openssl"
+
+#include "lua.h"
+#include "lauxlib.h"
+
+LUALIB_API int luaopen_openssl(lua_State *L);
+
+#endif
+
+#endif
Index: scripts/md5test.nse
===================================================================
--- scripts/md5test.nse (revision 0)
+++ scripts/md5test.nse (revision 0)
@@ -0,0 +1,25 @@
+-- simple script to test md5 / sha1 library
+-- by Thomas Buchanan <tbuchanan () thecompassgrp net>
+
+id = "Hash test"
+description = "Test script for md5 / sha1 library"
+categories = {"safe"}
+
+require("stdnse")
+require("shortport")
+require("openssl")
+
+hostrule = function(host)
+  return true
+end
+
+action = function(host, port)
+
+  local output = "MD5 and SHA1 hashes of IP address " .. host.ip
+  output = output .. "\nMD5: " .. openssl.bin2hex(
openssl.digest_md5(host.ip) )
+  output = output .. "\nSHA1: " .. openssl.bin2hex(
openssl.digest_sha1(host.ip) )
+  output = output .. "\nMD5 raw: " .. openssl.digest_md5(host.ip)
+  output = output .. "\nSHA1 raw: " .. openssl.digest_sha1(host.ip)
+  return output
+
+end


_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org


_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org


Current thread: