Nmap Development mailing list archives

[NSE][PATCH] OpenSSL bindings for NSE


From: Sven Klemm <sven () c3d2 de>
Date: Sun, 31 Aug 2008 14:33:11 +0200

Hi,

I've updated the openssl bindings. The module is now built as a static module. The module is built when OpenSSL is available and Lua is enabled.

The module currently includes all the functions I needed for writing the SSH hostkey script, which are mostly bignum functions. I've also added documentation for the included functions.

Any opinions about integrating this into nmap?

Cheers,
Sven

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

Index: Makefile.in
===================================================================
--- Makefile.in (.../nmap)      (revision 9880)
+++ Makefile.in (.../nmap-exp/sven/nse_openssl) (revision 9880)
@@ -63,6 +63,11 @@
 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
 NSESTDLIB=nsestdlib
+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 9880)
+++ nse_init.cc (.../nmap-exp/sven/nse_openssl) (revision 9880)
@@ -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"
 
@@ -223,6 +227,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 9880)
+++ docs/scripting.xml  (.../nmap-exp/sven/nse_openssl) (revision 9880)
@@ -1143,6 +1143,149 @@
         <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>
+
+       </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 9880)
@@ -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
Index: nse_openssl.cc
===================================================================
--- nse_openssl.cc      (.../nmap)      (revision 0)
+++ nse_openssl.cc      (.../nmap-exp/sven/nse_openssl) (revision 9880)
@@ -0,0 +1,258 @@
+#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 "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 ) );
+  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 );
+  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 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},
+  { NULL, NULL }
+};
+
+LUALIB_API int luaopen_openssl(lua_State *L) {
+
+  luaL_openlib(L, OPENSSLLIBNAME, openssllib, 0);
+
+  // 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: