Nmap Development mailing list archives

Re: [NSE][PATCH] OpenSSL bindings for NSE


From: Sven Klemm <sven () c3d2 de>
Date: Fri, 19 Sep 2008 09:12:24 +0200

Hi everyone,

here is the latest OpenSSL bindings patch for nmap including support for multiprecision integer arithmetics, message digests, hmac, symmetric encryption, symmetric decryption.
Documentation for the new functions is also included.

Cheers,
Sven

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

Index: Makefile.in
===================================================================
--- Makefile.in (.../nmap)      (revision 10271)
+++ Makefile.in (.../nmap-exp/sven/nse_openssl) (revision 10271)
@@ -66,6 +66,11 @@
 NSE_SRC=nse_main.cc nse_nsock.cc nse_init.cc nse_fs.cc nse_nmaplib.cc nse_debug.cc nse_pcrelib.cc nse_binlib.cc 
nse_hash.cc nse_bit.cc
 NSE_HDRS=nse_main.h nse_nsock.h nse_init.h nse_fs.h nse_nmaplib.h nse_debug.h nse_macros.h nse_pcrelib.h nse_binlib.h 
nse_hash.h nse_bit.h
 NSE_OBJS=nse_main.o nse_nsock.o nse_init.o nse_fs.o nse_nmaplib.o nse_debug.o nse_pcrelib.o nse_binlib.o nse_hash.o 
nse_bit.o
+ifneq (@OPENSSL_LIBS@,)
+NSE_SRC+=nse_openssl.cc
+NSE_HDRS+=nse_openssl.h
+NSE_OBJS+=nse_openssl.o
+endif
 endif
 
 export SRCS = main.cc nmap.cc targets.cc tcpip.cc nmap_error.cc utils.cc idle_scan.cc osscan.cc osscan2.cc output.cc 
scan_engine.cc timing.cc charpool.cc services.cc protocols.cc nmap_rpc.cc portlist.cc NmapOps.cc TargetGroup.cc 
Target.cc FingerPrintResults.cc service_scan.cc NmapOutputTable.cc MACLookup.cc nmap_tty.cc nmap_dns.cc traceroute.cc 
portreasons.cc $(NSE_SRC) @COMPAT_SRCS@
Index: nse_init.cc
===================================================================
--- nse_init.cc (.../nmap)      (revision 10271)
+++ nse_init.cc (.../nmap-exp/sven/nse_openssl) (revision 10271)
@@ -8,6 +8,10 @@
 #include "nse_pcrelib.h"
 #include "nse_bit.h"
 
+#ifdef HAVE_OPENSSL
+#include "nse_openssl.h"
+#endif
+
 #include "nse_binlib.h"
 #include "nse_hash.h"
 
@@ -247,6 +251,9 @@
     {NSE_BINLIBNAME, luaopen_binlib},
     {NSE_HASHLIBNAME, luaopen_hashlib},
     {BITLIBNAME, luaopen_bit}, // bit library
+#ifdef HAVE_OPENSSL
+    {OPENSSLLIBNAME, luaopen_openssl}, // openssl bindings
+#endif
   };
 
   luaL_openlibs(L); // opens all standard libraries
Index: docs/scripting.xml
===================================================================
--- docs/scripting.xml  (.../nmap)      (revision 10271)
+++ docs/scripting.xml  (.../nmap-exp/sven/nse_openssl) (revision 10271)
@@ -1164,6 +1164,226 @@
         <indexterm class="endofrange" startref="nse-pcre-indexterm"/>
     </sect2>
        
+      <sect2 id="nse-openssl">
+        <indexterm class="startofrange" id="nse-openssl-indexterm"><primary><varname>openssl</varname> NSE 
module</primary></indexterm>
+        <indexterm><primary>OpenSSL</primary><secondary>in NSE</secondary></indexterm>
+        <title>OpenSSL NSE bindings</title>
+
+        <para>
+       The <literal>openssl</literal> module provides functions for 
+       dealing with multiprecision integers. The functions reside inside the 
+       <literal>openssl</literal> namespace.
+         </para>
+
+       <variablelist>
+
+           <varlistentry>
+             <term><option>openssl.bignum_num_bits( bignum )</option></term>
+             <listitem>
+               <para>Returns the size of <literal>bignum</literal> in bits.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_num_bytes( bignum )</option></term>
+             <listitem>
+               <para>Returns the size of <literal>bignum</literal> in bytes.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_set_bit( bignum, position )</option></term>
+             <listitem>
+               <para>Sets bit at <literal>position</literal> in <literal>bignum</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_clear_bit( bignum, position )</option></term>
+             <listitem>
+               <para>Clears bit at <literal>position</literal> in <literal>bignum</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_is_bit_set( bignum, position )</option></term>
+             <listitem>
+               <para>Get bit at <literal>position</literal> in <literal>bignum</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_set_negative( bignum, negative )</option></term>
+             <listitem>
+               <para>Set sign of <literal>bignum</literal>. If <literal>negative</literal> is <literal>false</literal> 
the sign becomes positive otherwise it becomes negative.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_is_negative( bignum )</option></term>
+             <listitem>
+               <para>Check sign of <literal>bignum</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_bin2bn( string )</option></term>
+             <listitem>
+               <para>Converts binary encoded <literal>string</literal> into a <literal>bignum</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_dec2bn( string )</option></term>
+             <listitem>
+               <para>Converts decimal encoded <literal>string</literal> into a <literal>bignum</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_hex2bn( string )</option></term>
+             <listitem>
+               <para>Converts hex-encoded <literal>string</literal> into a <literal>bignum</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_bn2bin( bignum )</option></term>
+             <listitem>
+               <para>Converts <literal>bignum</literal> into a binary encoded string.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_bn2dec( bignum )</option></term>
+             <listitem>
+               <para>Converts <literal>bignum</literal> into a decimal encoded string.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_bn2hex( bignum )</option></term>
+             <listitem>
+               <para>Converts <literal>bignum</literal> into a hex-encoded string.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_rand( bits )</option></term>
+             <listitem>
+               <para>Returns random <literal>bignum</literal> with <literal>bits</literal> bit size.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_pseudo_rand( bits )</option></term>
+             <listitem>
+               <para>Returns pseudo random <literal>bignum</literal> with <literal>bits</literal> bit size.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.bignum_mod_exp( a, p, m )</option></term>
+             <listitem>
+               <para>Returns bignum which is the result of <literal>a</literal>^<literal>p</literal> mod 
<literal>m</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.rand_bytes( bytes )</option></term>
+             <listitem>
+               <para>Returns a string of <literal>bytes</literal> length with random data.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.rand_pseudo_bytes( bytes )</option></term>
+             <listitem>
+               <para>Returns a string of <literal>bytes</literal> length with pseudo random data.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.md2( message )</option></term>
+             <listitem>
+               <para>Returns the MD2 digest of <literal>message</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.md4( message )</option></term>
+             <listitem>
+               <para>Returns the MD4 digest of <literal>message</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.md5( message )</option></term>
+             <listitem>
+               <para>Returns the MD5 digest of <literal>message</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.sha1( message )</option></term>
+             <listitem>
+               <para>Returns the SHA1 digest of <literal>message</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.ripemd160( message )</option></term>
+             <listitem>
+               <para>Returns the RIPEMD160 digest of <literal>message</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.digest( algorithm, message )</option></term>
+             <listitem>
+               <para>Returns the digest specified by <literal>algorithm</literal> of <literal>message</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.hmac( algorithm, key, message )</option></term>
+             <listitem>
+               <para></para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.encrypt( algorithm, key, iv, data, padding = false )</option></term>
+             <listitem>
+               <para>Encrypt <literal>data</literal> with the encryption algorithm <literal>algorithm</literal>, 
<literal>key</literal> and the initialization vector <literal>iv</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.decrypt( algorithm, key, iv, data, padding = false )</option></term>
+             <listitem>
+               <para>Decrypt <literal>data</literal> with the encryption algorithm <literal>algorithm</literal>, 
<literal>key</literal> and the initialization vector <literal>iv</literal>.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.supported_ciphers()</option></term>
+             <listitem>
+               <para>Returns a table with the names of the supported cipher algorithms.</para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term><option>openssl.supported_digests()</option></term>
+             <listitem>
+               <para>Returns a table with the names of the supported digest algorithms.</para>
+             </listitem>
+           </varlistentry>
+
+       </variablelist>
+        <indexterm class="endofrange" startref="nse-openssl-indexterm"/>
+    </sect2>
+
        <sect2 id="nse-lib-ipOps">
        <title>IP Operations</title>
         <indexterm><primary><varname>ipOps</varname> NSE module</primary></indexterm>
Index: nse_openssl.h
===================================================================
--- nse_openssl.h       (.../nmap)      (revision 0)
+++ nse_openssl.h       (.../nmap-exp/sven/nse_openssl) (revision 10271)
@@ -0,0 +1,19 @@
+#include "../nmap_config.h"
+
+#if HAVE_OPENSSL
+
+#ifndef OPENSSLLIB
+#define OPENSSLLIB
+
+#define OPENSSLLIBNAME "openssl"
+
+extern "C" {
+#include "lua.h"
+#include "lauxlib.h"
+}
+
+LUALIB_API int luaopen_openssl(lua_State *L);
+
+#endif
+
+#endif

Property changes on: nse_openssl.h
___________________________________________________________________
Added: svn:mergeinfo

Index: nse_openssl.cc
===================================================================
--- nse_openssl.cc      (.../nmap)      (revision 0)
+++ nse_openssl.cc      (.../nmap-exp/sven/nse_openssl) (revision 10271)
@@ -0,0 +1,493 @@
+#include "nmap_config.h"
+
+/* 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/crypto.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/md2.h>
+#include <openssl/md4.h>
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#include <openssl/ripemd.h>
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+
+#include "nse_openssl.h"
+
+typedef struct bignum_data {
+  BIGNUM * bn;
+} bignum_data_t;
+
+static int l_bignum_bin2bn( lua_State *L ) /** bignum_bin2bn( string s ) */
+{
+  size_t len;
+  const unsigned char * s = (unsigned char *) luaL_checklstring( L, 1, &len );
+  BIGNUM * num = BN_new();
+  BN_bin2bn( s, len, num );
+  bignum_data_t * data = (bignum_data_t *) lua_newuserdata( L, sizeof(bignum_data_t));
+  luaL_getmetatable( L, "BIGNUM" );
+  lua_setmetatable( L, -2 );
+  data->bn = num;
+  return 1;
+}
+
+static int l_bignum_dec2bn( lua_State *L ) /** bignum_dec2bn( string s ) */
+{
+  const char * s = luaL_checkstring( L, 1 );
+  BIGNUM * num = BN_new();
+  BN_dec2bn( &num, s );
+  bignum_data_t * data = (bignum_data_t *) lua_newuserdata( L, sizeof(bignum_data_t));
+  luaL_getmetatable( L, "BIGNUM" );
+  lua_setmetatable( L, -2 );
+  data->bn = num;
+  return 1;
+}
+
+static int l_bignum_hex2bn( lua_State *L ) /** bignum_hex2bn( string s ) */
+{
+  const char * s = luaL_checkstring( L, 1 );
+  BIGNUM * num = BN_new();
+  BN_hex2bn( &num, s );
+  bignum_data_t * data = (bignum_data_t *) lua_newuserdata( L, sizeof(bignum_data_t));
+  luaL_getmetatable( L, "BIGNUM" );
+  lua_setmetatable( L, -2 );
+  data->bn = num;
+  return 1;
+}
+
+static int l_bignum_rand( lua_State *L ) /** bignum_rand( number bits ) */
+{
+  size_t bits = luaL_checkint( L, 1 );
+  BIGNUM * num = BN_new();
+  BN_rand( num, bits, -1, 0 );
+  bignum_data_t * data = (bignum_data_t *) lua_newuserdata( L, sizeof(bignum_data_t));
+  luaL_getmetatable( L, "BIGNUM" );
+  lua_setmetatable( L, -2 );
+  data->bn = num;
+  return 1;
+}
+
+static int l_bignum_pseudo_rand( lua_State *L ) /** bignum_pseudo_rand( number bits ) */
+{
+  size_t bits = luaL_checkint( L, 1 );
+  BIGNUM * num = BN_new();
+  BN_pseudo_rand( num, bits, -1, 0 );
+  bignum_data_t * data = (bignum_data_t *) lua_newuserdata( L, sizeof(bignum_data_t));
+  luaL_getmetatable( L, "BIGNUM" );
+  lua_setmetatable( L, -2 );
+  data->bn = num;
+  return 1;
+}
+
+static int l_bignum_mod_exp( lua_State *L ) /** bignum_mod_exp( BIGNUM a, BIGNUM p, BIGNUM m ) */
+{
+  bignum_data_t * a = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  bignum_data_t * p = (bignum_data_t *) luaL_checkudata(L, 2, "BIGNUM");
+  bignum_data_t * m = (bignum_data_t *) luaL_checkudata(L, 3, "BIGNUM");
+  BIGNUM * result = BN_new();
+  BN_CTX * ctx = BN_CTX_new();
+  BN_CTX_init( ctx );
+  BN_mod_exp( result, a->bn, p->bn, m->bn, ctx );
+  BN_CTX_free( ctx );
+  bignum_data_t * data = (bignum_data_t *) lua_newuserdata( L, sizeof(bignum_data_t));
+  luaL_getmetatable( L, "BIGNUM" );
+  lua_setmetatable( L, -2 );
+  data->bn = result;
+  return 1;
+}
+
+static int l_bignum_num_bits( lua_State *L ) /** bignum_num_bits( BIGNUM bn ) */
+{
+  bignum_data_t * userdata = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  lua_pushnumber( L, BN_num_bits( userdata->bn) );
+  return 1;
+}
+
+static int l_bignum_num_bytes( lua_State *L ) /** bignum_num_bytes( BIGNUM bn ) */
+{
+  bignum_data_t * userdata = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  lua_pushnumber( L, BN_num_bytes( userdata->bn) );
+  return 1;
+}
+
+static int l_bignum_set_bit( lua_State *L ) /** bignum_set_bit( BIGNUM bn, number position ) */
+{
+  bignum_data_t * userdata = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  int position = luaL_checkint( L, 2 );
+  BN_set_bit( userdata->bn, position );
+  return 0;
+}
+
+static int l_bignum_clear_bit( lua_State *L ) /** bignum_clear_bit( BIGNUM bn, number position ) */
+{
+  bignum_data_t * userdata = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  int position = luaL_checkint( L, 2 );
+  BN_clear_bit( userdata->bn, position );
+  return 0;
+}
+
+static int l_bignum_is_bit_set( lua_State *L ) /** bignum_set_bit( BIGNUM bn, number position ) */
+{
+  bignum_data_t * userdata = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  int position = luaL_checkint( L, 2 );
+  lua_pushboolean( L, BN_is_bit_set( userdata->bn, position ) );
+  return 1;
+}
+
+static int l_bignum_set_negative( lua_State *L ) /** bignum_set_negative( BIGNUM bn ) */
+{
+  bignum_data_t * userdata = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  int value = lua_toboolean(L, 2);
+  BN_set_negative( userdata->bn, value );
+  return 0;
+}
+
+static int l_bignum_is_negative( lua_State *L ) /** bignum_is_negative( BIGNUM bn ) */
+{
+  bignum_data_t * userdata = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  lua_pushboolean( L, BN_is_negative( userdata->bn) );
+  return 1;
+}
+
+static int l_bignum_bn2bin( lua_State *L ) /** bignum_bn2bin( BIGNUM bn ) */
+{
+  bignum_data_t * userdata = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  unsigned char * result = (unsigned char *) malloc( BN_num_bytes( userdata->bn ) );
+  if (!result) return luaL_error( L, "Couldn't allocate memory.");
+
+  int len = BN_bn2bin( userdata->bn, result );
+  lua_pushlstring( L, (char *) result, len );
+  free( result );
+  return 1;
+}
+
+static int l_bignum_bn2dec( lua_State *L ) /** bignum_bn2dec( BIGNUM bn ) */
+{
+  bignum_data_t * userdata = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  char * result = BN_bn2dec( userdata->bn );
+  lua_pushstring( L, result );
+  OPENSSL_free( result );
+  return 1;
+}
+
+static int l_bignum_bn2hex( lua_State *L ) /** bignum_bn2hex( BIGNUM bn ) */
+{
+  bignum_data_t * userdata = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  char * result = BN_bn2hex( userdata->bn );
+  lua_pushstring( L, result );
+  OPENSSL_free( result );
+  return 1;
+}
+
+static int l_bignum_free( lua_State *L ) /** bignum_free( bignum ) */
+{
+  bignum_data_t * userdata = (bignum_data_t *) luaL_checkudata(L, 1, "BIGNUM");
+  BN_clear_free( userdata->bn );
+  return 0;
+}
+
+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 );
+  if (!result) return luaL_error( L, "Couldn't allocate memory.");
+
+  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 );
+  if (!result) return luaL_error( L, "Couldn't allocate memory.");
+
+  RAND_pseudo_bytes( result, len );
+  lua_pushlstring( L, (char *) result, len );
+  free( result );
+  return 1;
+}
+
+static int l_md2(lua_State *L)     /** md2(string s) */
+{
+  size_t len;
+  const unsigned char *s = (unsigned char *) luaL_checklstring( L, 1, &len );
+  unsigned char digest[16];
+ 
+  lua_pushlstring( L, (char *) MD2( s, len, digest ), 16 );
+  return 1;
+}
+
+static int l_md4(lua_State *L)     /** md4(string s) */
+{
+  size_t len;
+  const unsigned char *s = (unsigned char *) luaL_checklstring( L, 1, &len );
+  unsigned char digest[16];
+ 
+  lua_pushlstring( L, (char *) MD4( s, len, digest ), 16 );
+  return 1;
+}
+
+static int l_md5(lua_State *L)     /** md5(string s) */
+{
+  size_t len;
+  const unsigned char *s = (unsigned char *) luaL_checklstring( L, 1, &len );
+  unsigned char digest[16];
+ 
+  lua_pushlstring( L, (char *) MD5( s, len, digest ), 16 );
+  return 1;
+}
+
+static int l_sha1(lua_State *L)     /** sha1(string s) */
+{
+  size_t len;
+  const unsigned char *s = (unsigned char *) luaL_checklstring( L, 1, &len );
+  unsigned char digest[20];
+ 
+  lua_pushlstring( L, (char *) SHA1( s, len, digest ), 20 );
+  return 1;
+}
+
+static int l_ripemd160(lua_State *L)     /** ripemd160(string s) */
+{
+  size_t len;
+  const unsigned char *s = (unsigned char *) luaL_checklstring( L, 1, &len );
+  unsigned char digest[20];
+ 
+  lua_pushlstring( L, (char *) RIPEMD160( s, len, digest ), 20 );
+  return 1;
+}
+
+static int l_digest(lua_State *L)     /** digest(string algorithm, string message) */
+{
+  size_t msg_len;
+  unsigned int digest_len;
+  const char *algorithm = luaL_checkstring( L, 1 );
+  const unsigned char *msg = (unsigned char *) luaL_checklstring( L, 2, &msg_len );
+  unsigned char digest[EVP_MAX_MD_SIZE];
+  const EVP_MD * evp_md;
+  EVP_MD_CTX mdctx;
+
+  evp_md = EVP_get_digestbyname( algorithm );
+  
+  if (!evp_md) return luaL_error( L, "Unknown digest algorithm: %s", algorithm );
+
+  EVP_MD_CTX_init(&mdctx);
+  if (!(
+      EVP_DigestInit_ex( &mdctx, evp_md, NULL ) &&
+      EVP_DigestUpdate( &mdctx, msg, msg_len ) &&
+      EVP_DigestFinal_ex( &mdctx, digest, &digest_len ))) {
+    EVP_MD_CTX_cleanup( &mdctx );
+    return luaL_error( L, "OpenSSL error" );
+  }
+  EVP_MD_CTX_cleanup( &mdctx );
+
+  lua_pushlstring( L, (char *) digest, digest_len );
+  return 1;
+}
+
+static int l_hmac(lua_State *L)     /** hmac(string algorithm, string key, string message) */
+{
+  size_t key_len, msg_len;
+  unsigned int digest_len;
+  const char *algorithm = luaL_checkstring( L, 1 );
+  const unsigned char *key = (unsigned char *) luaL_checklstring( L, 2, &key_len );
+  const unsigned char *msg = (unsigned char *) luaL_checklstring( L, 3, &msg_len );
+  unsigned char digest[EVP_MAX_MD_SIZE];
+  const EVP_MD * evp_md;
+  evp_md = EVP_get_digestbyname( algorithm );
+  
+  if (!evp_md) return luaL_error( L, "Unknown digest algorithm: %s", algorithm );
+
+  HMAC( evp_md, key, key_len, msg, msg_len, digest, &digest_len );
+ 
+  lua_pushlstring( L, (char *) digest, digest_len );
+  return 1;
+}
+
+struct enumerator_data {
+  lua_State * L;
+  int index;
+};
+
+static void enumerate_algorithms( const OBJ_NAME * name, void * arg )
+{
+  struct enumerator_data* data = (struct enumerator_data *) arg;
+  lua_pushstring( data->L, name->name );
+  lua_rawseti( data->L, -2, data->index );
+  data->index++;
+}
+
+static int l_supported_digests(lua_State *L) /** supported_digests() */
+{
+  enumerator_data data;
+  data.L = L;
+  data.index = 1;
+  
+  lua_newtable( L );
+  OBJ_NAME_do_all_sorted( OBJ_NAME_TYPE_MD_METH,enumerate_algorithms, &data );
+
+  return 1;
+}
+
+static int l_supported_ciphers(lua_State *L) /** supported_ciphers() */
+{
+  enumerator_data data;
+  data.L = L;
+  data.index = 1;
+  
+  lua_newtable( L );
+  OBJ_NAME_do_all_sorted( OBJ_NAME_TYPE_CIPHER_METH,enumerate_algorithms, &data );
+
+  return 1;
+}
+
+static int l_encrypt(lua_State *L) /** encrypt( string algorithm, string key, string iv, string data, bool padding = 
false ) */
+{
+  const char *algorithm = luaL_checkstring( L, 1 );
+  const EVP_CIPHER * evp_cipher = EVP_get_cipherbyname( algorithm );
+  if (!evp_cipher) return luaL_error( L, "Unknown cipher algorithm: %s", algorithm );
+
+  size_t data_len;
+  const unsigned char *key = (unsigned char *) luaL_checkstring( L, 2 );
+  const unsigned char *iv = (unsigned char *) luaL_optstring( L, 3, "" );
+  const unsigned char *data = (unsigned char *) luaL_checklstring( L, 4, &data_len );
+  int padding = lua_toboolean( L, 5 );
+
+  EVP_CIPHER_CTX cipher_ctx;
+  EVP_CIPHER_CTX_init( &cipher_ctx );   
+
+  int out_len, final_len;
+  unsigned char * out = (unsigned char *) malloc( data_len + EVP_MAX_BLOCK_LENGTH );
+  if (!out) return luaL_error( L, "Couldn't allocate memory.");
+
+  if (!(
+      EVP_EncryptInit_ex( &cipher_ctx, evp_cipher, NULL, key, *iv ? iv : NULL ) &&
+      EVP_CIPHER_CTX_set_padding( &cipher_ctx, padding ) &&
+      EVP_EncryptUpdate( &cipher_ctx, out, &out_len, data, data_len ) &&
+      EVP_EncryptFinal_ex( &cipher_ctx, out + out_len, &final_len ) )) {
+    EVP_CIPHER_CTX_cleanup( &cipher_ctx );
+    free( out );
+    return luaL_error( L, "OpenSSL error" );
+  }
+
+  lua_pushlstring( L, (char *) out, out_len + final_len );
+
+  EVP_CIPHER_CTX_cleanup( &cipher_ctx );
+  free( out );
+
+  return 1;
+}
+
+static int l_decrypt(lua_State *L) /** decrypt( string algorithm, string key, string iv, string data, bool padding = 
false ) */
+{
+  const char *algorithm = luaL_checkstring( L, 1 );
+  const EVP_CIPHER * evp_cipher = EVP_get_cipherbyname( algorithm );
+  if (!evp_cipher) return luaL_error( L, "Unknown cipher algorithm: %s", algorithm );
+
+  size_t data_len;
+  const unsigned char *key = (unsigned char *) luaL_checkstring( L, 2 );
+  const unsigned char *iv = (unsigned char *) luaL_optstring( L, 3, "" );
+  const unsigned char *data = (unsigned char *) luaL_checklstring( L, 4, &data_len );
+  int padding = lua_toboolean( L, 5 );
+
+  EVP_CIPHER_CTX cipher_ctx;
+  EVP_CIPHER_CTX_init( &cipher_ctx );   
+
+  int out_len, final_len;
+  unsigned char * out = (unsigned char *) malloc( data_len );
+  if (!out) return luaL_error( L, "Couldn't allocate memory.");
+
+  if (!(
+      EVP_DecryptInit_ex( &cipher_ctx, evp_cipher, NULL, key, *iv ? iv : NULL ) &&
+      EVP_CIPHER_CTX_set_padding( &cipher_ctx, padding ) &&
+      EVP_DecryptUpdate( &cipher_ctx, out, &out_len, data, data_len ) &&
+      EVP_DecryptFinal_ex( &cipher_ctx, out + out_len, &final_len ) )) {
+    EVP_CIPHER_CTX_cleanup( &cipher_ctx );
+    free( out );
+    return luaL_error( L, "OpenSSL error" );
+  }
+
+  lua_pushlstring( L, (char *) out, out_len + final_len );
+
+  EVP_CIPHER_CTX_cleanup( &cipher_ctx );
+  free( out );
+
+  return 1;
+}
+
+
+static const struct luaL_reg bignum_methods[] = {
+  { "num_bits", l_bignum_num_bits },
+  { "num_bytes", l_bignum_num_bytes },
+  { "to_bin", l_bignum_bn2bin },
+  { "to_dec", l_bignum_bn2dec },
+  { "to_hex", l_bignum_bn2hex },
+  { "is_bit_set", l_bignum_is_bit_set },
+  { "set_bit", l_bignum_set_bit },
+  { "clear_bit", l_bignum_clear_bit },
+  { "is_bit_set", l_bignum_is_bit_set },
+  { "set_negative", l_bignum_set_negative },
+  { "is_negative", l_bignum_is_negative },
+  { "__gc", l_bignum_free },
+  { NULL, NULL }
+};
+
+static const struct luaL_reg openssllib[] = {
+  { "bignum_num_bits", l_bignum_num_bits },
+  { "bignum_num_bytes", l_bignum_num_bytes },
+  { "bignum_set_bit", l_bignum_set_bit },
+  { "bignum_clear_bit", l_bignum_clear_bit },
+  { "bignum_is_bit_set", l_bignum_is_bit_set },
+  { "bignum_set_negative", l_bignum_set_negative },
+  { "bignum_is_negative", l_bignum_is_negative },
+  { "bignum_bin2bn", l_bignum_bin2bn },
+  { "bignum_dec2bn", l_bignum_dec2bn },
+  { "bignum_hex2bn", l_bignum_hex2bn },
+  { "bignum_rand", l_bignum_rand },
+  { "bignum_pseudo_rand", l_bignum_pseudo_rand },
+  { "bignum_bn2bin", l_bignum_bn2bin },
+  { "bignum_bn2dec", l_bignum_bn2dec },
+  { "bignum_bn2hex", l_bignum_bn2hex },
+  { "bignum_mod_exp", l_bignum_mod_exp },
+  { "rand_bytes", l_rand_bytes },
+  { "rand_pseudo_bytes", l_rand_pseudo_bytes },
+  { "md2", l_md2 },
+  { "md4", l_md4 },
+  { "md5", l_md5 },
+  { "sha1", l_sha1 },
+  { "ripemd160", l_ripemd160 },
+  { "digest", l_digest },
+  { "hmac", l_hmac },
+  { "encrypt", l_encrypt },
+  { "decrypt", l_decrypt },
+  { "supported_digests", l_supported_digests },
+  { "supported_ciphers", l_supported_ciphers },
+  { NULL, NULL }
+};
+
+LUALIB_API int luaopen_openssl(lua_State *L) {
+
+  OpenSSL_add_all_algorithms();
+
+  luaL_register(L, OPENSSLLIBNAME, openssllib);
+
+  // create metatable for bignum
+  luaL_newmetatable( L, "BIGNUM" );
+  // metatable.__index = metatable
+  lua_pushvalue( L, -1 );
+  lua_setfield( L, -2, "__index" );
+  // register methods
+  luaL_register( L, NULL, bignum_methods );
+
+  return 1;
+}
+

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

Current thread: