[or-cvs] r11214: some changes and new documentation (in topf/trunk: . config doc lib lib/fuzz-struct)

benedikt at seul.org benedikt at seul.org
Mon Aug 20 11:09:05 UTC 2007


Author: benedikt
Date: 2007-08-20 07:09:04 -0400 (Mon, 20 Aug 2007)
New Revision: 11214

Added:
   topf/trunk/binary/
Modified:
   topf/trunk/config/config.yml
   topf/trunk/doc/tutorial.tex
   topf/trunk/lib/cell.rb
   topf/trunk/lib/control.rb
   topf/trunk/lib/dir.rb
   topf/trunk/lib/fuzz-generic.rb
   topf/trunk/lib/fuzz-struct/char-field.rb
   topf/trunk/lib/fuzz-struct/float-field.rb
   topf/trunk/lib/fuzz-struct/fuzz-struct.rb
   topf/trunk/lib/fuzz-struct/hex-octet-field.rb
   topf/trunk/lib/fuzz-struct/nested-field.rb
   topf/trunk/lib/fuzz-struct/octet-field.rb
   topf/trunk/lib/fuzz-struct/pad-field.rb
   topf/trunk/lib/fuzz-struct/signed-field.rb
   topf/trunk/lib/fuzz-struct/text-field.rb
   topf/trunk/lib/fuzz-struct/unsigned-field.rb
   topf/trunk/lib/fuzz-struct/yaml.rb
   topf/trunk/lib/fuzz.rb
   topf/trunk/lib/pkcs1.rb
   topf/trunk/lib/topf.rb
   topf/trunk/tor-control-fuzz.rb
   topf/trunk/tor-dir-fuzz.rb
Log:
some changes and new documentation

Modified: topf/trunk/config/config.yml
===================================================================
--- topf/trunk/config/config.yml	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/config/config.yml	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,4 +1,3 @@
-
 ############################################################
 # This file holds information about our running tor-service
 ############################################################
@@ -6,5 +5,8 @@
 DIRPORT: "2324"
 CONTROLPORT: "2323"
 HOST: "127.0.0.1" 
-KEYFILE: stuff/fuzz-private.pem
+KEYFILE: "stuff/fuzz-private.pem"
 DEBUG: false
+COREDIR: "/home/Benedikt/topf/core"
+BINDIR: "/home/Benedikt/topf/binary"
+CONFDIR: "/home/Benedikt/topf/config"

Modified: topf/trunk/doc/tutorial.tex
===================================================================
--- topf/trunk/doc/tutorial.tex	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/doc/tutorial.tex	2007-08-20 11:09:04 UTC (rev 11214)
@@ -3,6 +3,7 @@
 \usepackage{amsmath}
 \usepackage{amsfonts}
 \usepackage{amssymb}
+
 \author{Benedikt Boss}
 \title{Howto use (T)he (O)nion (P)rotocol (F)uzzer}
 \begin{document}
@@ -38,11 +39,53 @@
 on your command-shell of choice.
 
 \subsection{Running the fuzz tests}
+\subsubsection{Adjusting the config File}
+To let the Framework work properly the right setup of the 
+config-file is nessesary. Just alter the given options 
+to your environment.
 
-... steps to running the tests already in topf svn
+\begin{verbatim}
+DIRPORT: "2324"
+CONTROLPORT: "2323"
+HOST: "127.0.0.1"
+KEYFILE: "stuff/fuzz-private.pem"
+DEBUG: false
+COREDIR: "/home/your_user/topf/core"
+BINDIR: "/home/your_user/topf/binary"
+CONFDIR: "/home/your_user/topf/config"
+\end{verbatim}
 
-... and how to interpret the results
+\subsubsection{Setting the u-limit}
+To let your system create core-dumps you normaly have
+to adjust your ulimit. You can do this on the 
+shell with the command: "ulimit -c unlimited"
+\subsubsection{Setting a core-pattern}
+T.O.P.F checks if a process has been crashed by diffing the 
+coredump-directory that was setup in the config-file.
+To let your system create core-files in this directory you 
+have to supply a core-pattern. If you work with Linux you
+can set the core-pattern with echoing a path+filepattern 
+into the file in proc named core\_pattern.
+When using Fedora this can be done with the following command
+ executed as root: 
+ \begin{verbatim}
+ echo "/home/youruser/path_to_topf/core/core" > /proc/sys/kernel/core_pattern
+ \end{verbatim}
 
+\subsubsection{Running the Dir-Port tests}
+To run the tests against the Dir-Port make sure you have setup
+the right host and dir-port in the configuration file.
+If everything is setup right you can just execute the dir-fuzzing
+with the command "ruby tor-dir-fuzz.rb".
+If something goes wrong a corefile should be dumped and the 
+test-script should give you a backtrace and register information
+out of that corefile. Also it should print out the data that triggered
+the bug.
+\subsubsection{Running the Control-Port tests}
+Running tests against the Control-Port should be the same as running
+the tests against the Dir-Port. If you're sure you did all config options
+right you can execute "ruby tor-control-fuzz.rb" and the rest is done
+automatically.
 \section{Writing T.O.P.F Structures}
 As described in Section~\ref{working} (yeah? where? -RD), T.O.P.F
 organizes its data in blocks. These blocks can have different types
@@ -53,8 +96,8 @@
 #example1.rb
 require "lib/fuzz-generic"
 
-class Example < BitStruct
-    text :example, 7
+class Example < FuzzStruct
+    text :example, 7, :fuzzable => false
     unsigned :version, 8
 
     initial_value.example = "example"
@@ -67,13 +110,14 @@
     pp e
 end
 \end{verbatim}
+This creates a Class called "Example" with the fields of a 8*8Bit long String, 
+a 8Bit unsigned integer. and the initial values "example" and 1 for these. 
+Also the Text-Field is declared as not fuzzable which means that later the 
+value assigned to it remains the same. Next in the begin/end block the 
+programm creates a Example object and sets the value of the version field to 2. 
+This also demonstrates how you are able to access all fields after you created 
+a fuzz-struct object.
 
-This creates a Class called "Example" with the fields of a 8*8Bit
-long String, a 8Bit unsigned integer. and the initial values "example"
-and 1 for these.  Next in the begin/end block the programm creates a
-Example object and sets the value of the version field to 2. This also
-demonstrates how you are able to access all fields after you created a
-fuzz-struct object.
 
 \subsection{Writing T.O.P.F Tests}
 Tests in the Framework are organized on a field-type base. This means
@@ -85,16 +129,17 @@
 \begin{verbatim}
     a_test = Fuzz::Test.new("char") {|arg, size|  "A"*1000}
 \end{verbatim}
-To apply this test to a fuzz-struct you actually need another object which
-acts as a collector for many tests. This object is called Fuzz::Tests
-and is later applied to a fuzz-struct.  The next example shows how you
-write some tests, assign them to the collector object and apply all
-tests to a structure.
+To apply this test to a fuzz-struct you actually need another object which 
+acts as a collector for many tests. This object is called Fuzz::Tests and 
+is later applied to a fuzz-struct. The next example shows how you write some 
+tests, assign them to the collector object and apply all tests to a structure 
+and output all permutations calculateable through these tests.
+
 \begin{verbatim}
 #example2.rb
 require "lib/fuzz-generic"
 
-class Example < BitStruct
+class Example < FuzzStruct
     text :example, 7
     unsigned :version, 8
 
@@ -103,21 +148,22 @@
 end
 
 begin
-	example_tests = Fuzz::Tests.new
-	# tests for the text field
-	example_tests.register Fuzz::Test.new("char") {|arg, size|  arg} # return argument
-	example_tests.register Fuzz::Test.new("char") {|arg, size|  ""}    # return empty string
-	example_tests.register Fuzz::Test.new("char") {|arg, size|  "A"*1000} # return many many A's
-	# tests for unsigned numbers
+    example_tests = Fuzz::Tests.new
+
+    # tests for the text field
+    example_tests.register Fuzz::Test.new("char") {|arg, size|  arg} # return argument
+    example_tests.register Fuzz::Test.new("char") {|arg, size|  ""}    # return empty string
+    example_tests.register Fuzz::Test.new("char") {|arg, size|  "A"*1000} # return many many A's
+
+    # tests for unsigned numbers
     example_tests.register Fuzz::Test.new("unsigned") {|arg, size|  arg } # return argument
     example_tests.register Fuzz::Test.new("unsigned") {|arg, size|  0 } # return zero 
     example_tests.register Fuzz::Test.new("unsigned") {|arg, size|  rand(5) } # return a small number 
     example_tests.register Fuzz::Test.new("unsigned") {|arg, size|  2.power!(size) } # return biggest number 
 
     e = Example.new
-	e.prepare! example_tests
+    e.prepare! example_tests
 end
-
 \end{verbatim}
 
 \subsection{Some example tests on Tor itself}
@@ -136,6 +182,12 @@
 \subsection{Dir}
 \subsection{Control}
 \subsection{Cell}
+\subsection{Logger}
+\subsection{Backtrace}
+\subsection{Proxy}
+\subsubsection{Http-Proxy}
+\subsubsection{Https-Proxy}
+
 \section{Fuzz-Struct Reference}
 \subsection{Types}
 \label{types}
@@ -152,10 +204,9 @@
 \subsubsection{hex-octet}
 \subsubsection{nested}
 \subsubsection{pad}
-\subsection{Logger}
 
-\appendix
 
+\section{Appendix}
 \section{Links}
 \label{links}
 \begin{verbatim}
@@ -166,5 +217,4 @@
 http://www.ruby-lang.org
 \end{verbatim}
 
-\end{document}\documentclass[10pt]{article}
-
+\end{document}

Modified: topf/trunk/lib/cell.rb
===================================================================
--- topf/trunk/lib/cell.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/cell.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -10,13 +10,13 @@
             [ 6, "" ] # CREATED FAST 
         ]
 
-        class Packet < BitStruct
+        class Packet < FuzzStruct
             unsigned :circID, 16
             unsigned :command, 16
             rest     :payload
         end
 
-        class Extended < BitStruct
+        class Extended < FuzzStruct
             hex_octets       :address, 32
             unsigned    :port, 16
             rest        :skin
@@ -38,7 +38,7 @@
             12  => "NOSUCHSERVICE"
         }
 
-        class Relay < BitStruct
+        class Relay < FuzzStruct
             unsigned :command, 8
             unsigned :recognized, 16
             unsigned :streamID, 16

Modified: topf/trunk/lib/control.rb
===================================================================
--- topf/trunk/lib/control.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/control.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -3,7 +3,7 @@
         class ItemFuzz
             attr_reader :item
             def initialize(item, tests, fields, values)
-                raise "item is not a BitStruct" if !item.is_a?(BitStruct)
+                raise "item is not a FuzzStruct" if !item.is_a?(FuzzStruct)
                 @item = item
                 @tests = tests
                 @fields = fields
@@ -94,7 +94,7 @@
 =end
         ]
 
-        class SetConfItem < BitStruct
+        class SetConfItem < FuzzStruct
             text :item, 7
             text :keyword, 30
             text :assign, 1
@@ -111,7 +111,7 @@
             "553 impossible configuration setting"
         ]
 
-        class ResetConfItem < BitStruct
+        class ResetConfItem < FuzzStruct
             text :item, 9
             text :keyword, 10
             text :assign, 1
@@ -121,7 +121,7 @@
             initial_value.assign    = "="
         end
 
-        class GetConfItem < BitStruct
+        class GetConfItem < FuzzStruct
             text :item, 7
             text :keyword, 10
             text :assign, 1
@@ -158,7 +158,7 @@
             "STREAM_BW"
         ]
 
-        class SetEventsItem < BitStruct
+        class SetEventsItem < FuzzStruct
             text :item, 9
             text :extended, 8 
             
@@ -174,7 +174,7 @@
             "514 authentication required"
         ]
 
-        class AuthenticateItem < BitStruct
+        class AuthenticateItem < FuzzStruct
             text :item, 13
             text :password, 8 
             rest :crlf
@@ -189,7 +189,7 @@
             "551 Unable to write configuration to disk"
         ]
 
-        class SaveConfItem < BitStruct
+        class SaveConfItem < FuzzStruct
             text :item, 8 
             initial_value.item = "SAVECONF"
         end
@@ -209,7 +209,7 @@
              "CLEARDNSCACHE"
         ]
 
-        class SignalItem < BitStruct
+        class SignalItem < FuzzStruct
             text :item, 6
             rest :signal
 

Modified: topf/trunk/lib/dir.rb
===================================================================
--- topf/trunk/lib/dir.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/dir.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -16,75 +16,82 @@
 
         PublicCertificate       =
 %{\n-----BEGIN RSA PUBLIC KEY-----
-MIGJAoGBAKo3Ijan5HOp6zzV1VJmveh2uvJv0A5qLiJtNVrebMTAM8kte14Fsylb
-DE5UmDryqbOmNi9gIcZKfjuqEKcuhsEPDObLeabNkdP+YGURVQ72IhQT8XRiGWg3
-2i8F9xhp5KPGKhjkXuAxnt2FS9lkOvIDnm4jnOtzfX0/RJRRrBCvAgMBAAE=
+MIGJAoGBAMhnUVkFc18CmqGNEKT15xSSsZlR1JBWUTRVF7vFmPmV5uKiKfI0uW1A
+uqgYVgeXyFRuH01CYr2Ymnkf4fi3waMSDhk/FPvsx0wXuUgINnKyTOrsIycrUYSP
+DKpSF6JcCE5TsgmbK/yuDsza+3mJw7/bHg4F+aFud4pxemZDozCvAgMBAAE=
 -----END RSA PUBLIC KEY-----}
 
-        class RouterItem < BitStruct
+        class RouterItem < FuzzStruct
             text    :item, 6, :fuzzable => false 
-            text    :nickname, TOPF::Dir::DefaultNicknameLength
-            hex_octets  :address, 32
+            text    :nickname, 16 
+            text    :address, 13 
             signed  :OrPort, 32
             signed  :SocksPort, 32
             signed  :DirPort, 32
             
             initial_value.item       = "router"
-            initial_value.nickname      = "foobar"
-            initial_value.address       = "127.0.0.1"
+            initial_value.nickname      = "pr0xydotathdotcx"
+            initial_value.address       = "88.191.37.194"
+            initial_value.OrPort        = 31337 
             initial_value.SocksPort     = 0
-            initial_value.OrPort        = TOPF::Dir::DefaultOrPort
-            initial_value.DirPort       = TOPF::Dir::DefaultDirPort
+            initial_value.DirPort       = 0
         end
 
-        class PublishedItem < BitStruct
+        class PublishedItem < FuzzStruct
             text    :item, 9
             text    :time, 19
 
             initial_value.item       = "published"
-            initial_value.time          = "#{Date.today.to_s} #{ Time.now.strftime "%H:%M:%S"}" 
+            #initial_value.time          = "#{Date.today.to_s} #{ Time.now.strftime "%H:%M:%S"}" 
+            initial_value.time          = "2007-08-19 01:09:40" 
         end
 
-        class OnionKeyItem < BitStruct
+        class OnionKeyItem < FuzzStruct
             text    :item, 9
-            rest    :publicKey      # key in PEM Format 
+            text    :publicKey, TOPF::Dir::PublicCertificate.size      # key in PEM Format 
 
             initial_value.item       = "onion-key"
             initial_value.publicKey     = TOPF::Dir::PublicCertificate
         end
 
-        class SigningKeyItem < BitStruct
+        class SigningKeyItem < FuzzStruct
             text    :item, 11
-            rest    :publicKey      # key in PEM Format
+            text    :publicKey, TOPF::Dir::PublicCertificate.size      # key in PEM Format 
 
             initial_value.item       = "signing-key"
             initial_value.publicKey     = TOPF::Dir::PublicCertificate
         end
 
-        class BandwidthItem < BitStruct
+        class BandwidthItem < FuzzStruct
             text    :item, 9
             signed  :avg,       128
             signed  :burst,     128
             signed  :observed,  128
 
             initial_value.item      = "bandwidth"
-            initial_value.avg       = 1 
-            initial_value.burst     = 1 
-            initial_value.observed  = 1 
+            initial_value.avg       = 10240000 
+            initial_value.burst     = 20380000
+            initial_value.observed  = 1804473
         end
 
-        class PlatformItem < BitStruct
+        class PlatformItem < FuzzStruct
             text :item, 8
-            rest :string
+            text :platform, 26
 
             initial_value.item = "platform"
+            initial_value.platform = "Tor 0.1.2.16 on Linux i686"
         end
 
-        class FingerprintItem < BitStruct
-            # FORMAT ?? 
+        class FingerprintItem < FuzzStruct
+            text :opt, 3
+            text :item, 11 
+            text :fingerprint, 49
+            initial_value.opt = "opt"
+            initial_value.item = "fingerprint"
+            initial_value.fingerprint = "36A1 0B84 C5BF CDB9 BC7C 6887 7826 D676 1309 2DD6"
         end 
 
-        class HibernateItem < BitStruct
+        class HibernateItem < FuzzStruct
             text :item, 11
             unsigned :state, 1
 
@@ -92,101 +99,69 @@
             initial_value.state     = 0 
         end
 
-        class UptimeItem < BitStruct
+        class UptimeItem < FuzzStruct
             text :item, 6
-            # FORMAT ?? 
-            
+            unsigned :time, 24
             initial_value.item  = "uptime"
+            initial_value.time  = 1209373
         end
 
-        class ContactItem < BitStruct
+        class ContactItem < FuzzStruct
             text :item, 7
-            rest :info
+            text :info, 40
 
             initial_value.item  = "contact"
+            initial_value.info  = "Felix Reinel <admin AT torproxy dot net>"
         end
 
-        class FamilyItem < BitStruct
+        class FamilyItem < FuzzStruct
             text :item, 6
             rest :names
 
             initial_value.item = "family"
         end
 
-        class ReadHistoryItem < BitStruct
-            text :item, 12
+        class ReadHistoryItem < FuzzStruct
+            text :item, 3 
+            text :read, 12
             text :time, 19
+            text :history, 968 
 
-            initial_value.item = "read-history"
-            initial_value.time          = "#{Date.today.to_s} #{ Time.now.strftime "%H:%M:%S"}" 
+            initial_value.item = "opt"
+            initial_value.read = "read-history"
+            #initial_value.time          = "#{Date.today.to_s} #{ Time.now.strftime "%H:%M:%S"}" 
+            initial_value.time          = "2007-08-19 01:09:37"
+            initial_value.history       = "(900 s) 760098816,627098624,693427200,679235584,697864192,657379328,705751040,658093056,712881152,752723968,711652352,784343040,719242240,716414976,661498880,647461888,681280512,623717376,569185280,587918336,551035904,593421312,593065984,560878592,618540032,570112000,525900800,502802432,696317952,648034304,728816640,638992384,806351872,785328128,699988992,732289024,642468864,715794432,719076352,737125376,702242816,706820096,615213056,717157376,582617088,725468160,820884480,623130624,696113152,748891136,758933504,789217280,731297792,701725696,608859136,653759488,683127808,618695680,654241792,712316928,862899200,616518656,845710336,773454848,819221504,822200320,773602304,733693952,831583232,816207872,862288896,875128832,720563200,858846208,805805056,632126464,682014720,670363648,838111232,766550016,788750336,745674752,699387904,778595328,885575680,1049205760,821670912,735636480,781303808,982372352,1007374336,811970560,828642304,809540608,721187840,756304896"
+ 
         end
 
-        class WriteHistoryItem < BitStruct
-            text :item, 12
+        class WriteHistoryItem < FuzzStruct
+            text :item, 3 
+            text :write, 13
             text :time, 19
+            text :history, 968 
 
-            initial_value.item = "write-history"
-            initial_value.time          = "#{Date.today.to_s} #{ Time.now.strftime "%H:%M:%S"}" 
+            initial_value.item = "opt"
+            initial_value.write = "write-history"
+            #initial_value.time          = "#{Date.today.to_s} #{ Time.now.strftime "%H:%M:%S"}" 
+            initial_value.time          = "2007-08-19 01:09:37"
+            initial_value.history       = "(900 s) 758238208,625318912,691261440,663665664,680981504,641565696,690364416,642569216,695374848,737664000,706840576,780549120,715257856,713936896,660255744,623203328,646553600,618431488,566634496,585960448,550209536,593250304,590551040,558642176,616057856,568313856,525464576,500299776,694533120,641624064,695276544,628350976,789766144,764145664,681135104,717862912,625372160,702624768,694521856,709050368,673614848,680497152,588131328,690713600,561212416,723578880,816830464,619859968,693881856,743980032,756367360,785605632,730672128,697923584,594031616,625268736,655276032,615368704,649592832,706004992,858901504,613521408,844616704,771748864,817015808,819881984,770548736,730366976,829035520,813772800,859834368,869432320,716977152,856101888,803599360,629864448,680253440,668408832,836214784,764502016,785489920,744428544,696685568,777190400,883115008,1046515712,818712576,709926912,778812416,978486272,1004804096,808800256,825538560,806936576,716456960,752701440" 
         end
 
-        class EventDnsItem < BitStruct
+        class RejectItem < FuzzStruct
+            text :item, 6   
+            text :reject, 3
+
+            initial_value.item  = "reject"
+            initial_value.reject= "*.*" 
+        end
+
+        class EventDnsItem < FuzzStruct
             text :item, 8
             unsigned :bool, 1
-                
+
             initial_value.item = "eventdns"
             initial_value.bool = 0
         end
-
-        class RouterDescriptor
-            def initialize(publicKey) 
-                @osslkey = OpenSSL::PKey::RSA.new(File.read(publicKey) )
-                @pkcs1 = PKCS1::SignatureScheme::RSASSAPKCS1v1_5.new(Digest::SHA1)
-
-                @key = PKCS1::Key::RSA.new(@osslkey.n.to_i , @osslkey.e.to_i, @osslkey.d.to_i)
-
-                @items = [  RouterItem.new, 
-                            PublishedItem.new,  
-                            OnionKeyItem.new,
-                            SigningKeyItem.new, 
-                            BandwidthItem.new,  
-                    ]
-                @prepared = false
-            end
-
-            def add_item( item )
-                @items.push item
-            end
-
-            def prepare_for_test
-                @items.each do |item|
-                    Fuzz::DEFAULT_TESTS.set_struct item
-                    Fuzz::DEFAULT_TESTS.generate_test_data
-                end
-            end
-
-            def fuzz!
-                if !@prepared 
-                    prepare_for_test
-                    @prepared = true
-                end
-
-                @items.each do |item|
-                    item.fuzz!
-                end
-            end
-
-            def to_s
-                resultString = ""
-                @items.each do |item|
-                    resultString << item.format << "\n"
-                end
-                resultString << "router-signature\n"
-                sig = Base64::b64encode( @pkcs1.sign(@key, resultString) )
-
-                resultString << "-----BEGIN SIGNATURE-----\n"
-                resultString << sig
-                resultString << "-----END SIGNATURE-----" << "\n"*2
-            end
-        end
     end
 end

Modified: topf/trunk/lib/fuzz-generic.rb
===================================================================
--- topf/trunk/lib/fuzz-generic.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-generic.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -6,3 +6,4 @@
 require "timeout"
 require "fuzz-struct"
 require "fuzz"
+require "gdb"

Modified: topf/trunk/lib/fuzz-struct/char-field.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/char-field.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-struct/char-field.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,8 +1,8 @@
 require 'fuzz-struct/fuzz-struct'
 
-class BitStruct
+class FuzzStruct
   # Class for fixed length binary strings of characters.
-  # Declared with BitStruct.char.
+  # Declared with FuzzStruct.char.
   class CharField < Field
     #def self.default
     #  don't define this, since it must specify N nulls and we don't know N
@@ -49,7 +49,7 @@
   end
   
   class << self
-    # Define a char string field in the current subclass of BitStruct,
+    # Define a char string field in the current subclass of FuzzStruct,
     # with the given _name_ and _length_ (in bits). Trailing nulls _are_
     # considered part of the string.
     #

Modified: topf/trunk/lib/fuzz-struct/float-field.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/float-field.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-struct/float-field.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,8 +1,8 @@
 require 'fuzz-struct/fuzz-struct'
 
-class BitStruct
+class FuzzStruct
   # Class for floats (single and double precision) in network order.
-  # Declared with BitStruct.float.
+  # Declared with FuzzStruct.float.
   class FloatField < Field
     # Used in describe.
     def self.class_name
@@ -62,7 +62,7 @@
   end
 
   class << self
-    # Define a floating point field in the current subclass of BitStruct,
+    # Define a floating point field in the current subclass of FuzzStruct,
     # with the given _name_ and _length_ (in bits).
     #
     # If a class is provided, use it for the Field class.

Modified: topf/trunk/lib/fuzz-struct/fuzz-struct.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/fuzz-struct.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-struct/fuzz-struct.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -8,7 +8,7 @@
 # Note that all string methods are still available: length, grep, etc.
 # The String#replace method is useful.
 #
-class BitStruct < String
+class FuzzStruct < String
   class Field
     # Offset of field in bits.
     attr_reader :offset
@@ -37,10 +37,10 @@
     attr_reader :fuzzable
 
     # Subclasses can override this to define a default for all fields of this
-    # class, not just the one currently being added to a BitStruct class, a
+    # class, not just the one currently being added to a FuzzStruct class, a
     # "default default" if you will. The global default, if #default returns
     # nil, is to fill the field with zero. Most field classes just let this
-    # default stand. The default can be overridden per-field when a BitStruct
+    # default stand. The default can be overridden per-field when a FuzzStruct
     # class is defined.
     def self.default; nil; end
 
@@ -83,7 +83,7 @@
       @display_name = opts[:display_name] || opts["display_name"]
       @default      = opts[:default] || opts["default"] || self.class.default
       @format       = opts[:format] || opts["format"]
- 
+
       if opts.has_key?(:fuzzable) || opts.has_key?("fuzzable")
           @fuzzable     = opts[:fuzzable] || opts["fuzzable"]
       else
@@ -147,7 +147,7 @@
 
     # Return the list of fields for this class including the rest field.
     def fields
-      @fields ||= self == BitStruct ? [] : superclass.fields.dup
+      @fields ||= self == FuzzStruct ? [] : superclass.fields.dup
     end
     
 
@@ -157,7 +157,7 @@
       @own_fields ||= []
     end
 
-    # Add a field to the BitStruct (usually, this is only used internally).
+    # Add a field to the FuzzStruct (usually, this is only used internally).
     def add_field(name, length, opts = {})
       round_byte_length ## just to make sure this has been calculated
       ## before adding anything
@@ -166,7 +166,7 @@
       
       if @closed
         raise ClosedClassError, "Cannot add field #{name}: " +
-          "The definition of the #{self.inspect} BitStruct class is closed."
+          "The definition of the #{self.inspect} FuzzStruct class is closed."
       end
 
       if fields.find {|f|f.name == name}
@@ -266,7 +266,7 @@
   # ------------------------
   # :section: metadata inspection methods
   #
-  # Methods to textually describe the format of a BitStruct subclass.
+  # Methods to textually describe the format of a FuzzStruct subclass.
   #
   # ------------------------
 
@@ -280,7 +280,7 @@
       DESCRIBE_FORMAT
     end
 
-    # Textually describe the fields of this class of BitStructs.
+    # Textually describe the fields of this class of FuzzStructs.
     # Returns a printable table (array of line strings), based on +fmt+,
     # which defaults to #describe_format, which defaults to +DESCRIBE_FORMAT+.
     def describe(fmt = nil, opts = {})
@@ -331,7 +331,7 @@
   # ------------------------
 
   # Initialize the string with the given string or bitstruct, or with a hash of
-  # field=>value pairs, or with the defaults for the BitStruct subclass. Fields
+  # field=>value pairs, or with the defaults for the FuzzStruct subclass. Fields
   # can be strings or symbols. Finally, if a block is given, yield the instance
   # for modification using accessors.
   def initialize(value = nil)   # :yields: instance
@@ -385,7 +385,7 @@
     end
   end
   
-  # Returns an array of values of the fields of the BitStruct. By default,
+  # Returns an array of values of the fields of the FuzzStruct. By default,
   # include the rest field.
   def to_a(include_rest = true)
     ary =
@@ -429,10 +429,10 @@
       @initial_value
     end
     
-    # Take +data+ (a string or BitStruct) and parse it into instances of
+    # Take +data+ (a string or FuzzStruct) and parse it into instances of
     # the +classes+, returning them in an array. The classes can be given
     # as an array or a separate arguments. (For parsing a string into a _single_
-    # BitStruct instance, just use the #new method with the string as an arg.)
+    # FuzzStruct instance, just use the #new method with the string as an arg.)
     def parse(data, *classes)
       classes.flatten.map do |c|
         c.new(data.slice!(0...c.round_byte_length))
@@ -496,31 +496,33 @@
       raise "argument must be of class Tests" if !tests.is_a?(Fuzz::Tests)
       result = []
       self.fields.each do |field|
-          arg = self.method(field.name).call
-          if field.fuzzable
-              temp = []
-              length = field.length
-              case field.class.to_s
-              when "BitStruct::SignedField"
-                  tests.signed_tests.each do |test|
-                  temp.push( test.run(arg, length) )
-                  end
-              result.push(temp)
-              when "BitStruct::UnsignedField"
-                  tests.unsigned_tests.each do |test|
-                  temp.push( test.run(arg, length) )
-                  end
-              result.push(temp)
-              when "BitStruct::TextField", "BitStruct::CharField", "BitStruct::Field"
-                  tests.char_tests.each do |test|
+          if field
+              arg = self.method(field.name).call
+              if field.fuzzable
+                  temp = []
+                  length = field.length
+                  case field.class.to_s
+                  when "FuzzStruct::SignedField"
+                      tests.signed_tests.each do |test|
                       temp.push( test.run(arg, length) )
+                      end
+                  result.push(temp)
+                  when "FuzzStruct::UnsignedField"
+                      tests.unsigned_tests.each do |test|
+                      temp.push( test.run(arg, length) )
+                      end
+                  result.push(temp)
+                  when "FuzzStruct::TextField", "FuzzStruct::CharField", "FuzzStruct::Field"
+                      tests.char_tests.each do |test|
+                      temp.push( test.run(arg, length) )
+                      end
+                  result.push(temp)
+                  else
+                      Fuzz::LOGGER.debug "new field-type: %s" % field.class.to_s
                   end
-              result.push(temp)
               else
-                  Fuzz::LOGGER.debug "new field-type: %s" % field.class.to_s
+                  result.push( [ arg ] )
               end
-          else
-              result.push( [ arg ] )
           end
       end
       @tests = result
@@ -529,9 +531,8 @@
       sizes =  @tests.collect {|element| element.size}
 
       @dimension = sizes.inject(1){|prod, element| prod*element }
-      
+    
       permutations = Array.new(sizes.size, Array.new(@dimension, 0) )
-
       result = []
       permutations.each_with_index do |element, index|
           count = 0 
@@ -551,15 +552,13 @@
 
       Fuzz::LOGGER.debug "[x] calculated %d permutations of struct %s" % [result.first.size, self.class]
       @permutations = result
-=begin
-# debugging stuff
-      @permutations[0].each_with_index do |element, index|
-          pp @permutations.collect{|el| el[index] }
-      end
-=end
       @permutation_index = 0
   end
 
+  def permutations
+      @permutations.first.size
+  end
+
   def fuzz!(opts = DEFAULT_INSPECT_OPTS)
       raise "no tests have been generated yet" if !@permutations or !@tests
       raise "end of tests" if @permutation_index.to_i == @dimension.to_i
@@ -576,16 +575,29 @@
       ret
   end
 
+  def output(join_char = "")
+      opts = DEFAULT_INSPECT_OPTS
+      fields_for_output = fields.select {|field| field.inspectable? if field}
+
+      if opts[:include_rest] and (rest_field = self.class.rest_field)
+          fields_for_output << rest_field
+      end
+
+      test = fields_for_output.map { |field|
+          field.to_s(self, opts)
+      }.join(join_char)
+  end
+
   def format(opts = DEFAULT_INSPECT_OPTS)
-        fields_for_output = fields.select {|field| field.inspectable?}
+        fields_for_output = fields.select {|field| field.inspectable? if field}
 
         if opts[:include_rest] and (rest_field = self.class.rest_field)
             fields_for_output << rest_field
         end
-        
+       
         fields_for_output.map { |field|
             field.to_s(self, opts)
-        }.join " "
+        }.join
   end
 
   # A more visually appealing inspect method that puts each field/value on
@@ -603,13 +615,13 @@
   # ------------------------
   
   # Define accessors for a variable length substring from the end of
-  # the defined fields to the end of the BitStruct. The _rest_ may behave as
-  # a String or as some other String or BitStruct subclass.
+  # the defined fields to the end of the FuzzStruct. The _rest_ may behave as
+  # a String or as some other String or FuzzStruct subclass.
   #
   # This does not add a field, which is useful because a superclass can have
   # a rest method which accesses subclass data. In particular, #rest does
   # not affect the #round_byte_length class method. Of course, any data
-  # in rest does add to the #length of the BitStruct, calculated as a string.
+  # in rest does add to the #length of the FuzzStruct, calculated as a string.
   # Also, _rest_ is not inherited.
   #
   # The +ary+ argument(s) work as follows:

Modified: topf/trunk/lib/fuzz-struct/hex-octet-field.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/hex-octet-field.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-struct/hex-octet-field.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,13 +1,13 @@
 require 'fuzz-struct/char-field'
 
-class BitStruct
+class FuzzStruct
   # Class for char fields that can be accessed with values like
   # "xx:xx:xx:xx", where each xx is up to 2 hex digits representing a
   # single octet. The original string-based accessors are still available with
   # the <tt>_chars</tt> suffix.
   # 
-  # Declared with BitStruct.hex_octets.
-  class HexOctetField < BitStruct::OctetField
+  # Declared with FuzzStruct.hex_octets.
+  class HexOctetField < FuzzStruct::OctetField
     # Used in describe.
     def self.class_name
       @class_name ||= "hex_octets"
@@ -19,7 +19,7 @@
   end
   
   class << self
-    # Define an octet string field in the current subclass of BitStruct,
+    # Define an octet string field in the current subclass of FuzzStruct,
     # with the given _name_ and _length_ (in bits). Trailing nulls are
     # not considered part of the string. The field is accessed using
     # period-separated hex digits.

Modified: topf/trunk/lib/fuzz-struct/nested-field.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/nested-field.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-struct/nested-field.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,8 +1,8 @@
 require 'fuzz-struct/fuzz-struct'
 
-class BitStruct
-  # Class for nesting a BitStruct as a field within another BitStruct.
-  # Declared with BitStruct.nest.
+class FuzzStruct
+  # Class for nesting a FuzzStruct as a field within another FuzzStruct.
+  # Declared with FuzzStruct.nest.
   class NestedField < Field
     attr_reader :nested_class
     
@@ -78,7 +78,7 @@
   end
   
   class << self
-    # Define a nested field in the current subclass of BitStruct,
+    # Define a nested field in the current subclass of FuzzStruct,
     # with the given _name_ and _nested_class_. Length is determined from
     # _nested_class_.
     #
@@ -93,11 +93,11 @@
     #
     # For example:
     #
-    #   class Sub < BitStruct
+    #   class Sub < FuzzStruct
     #     unsigned :x,    8
     #   end
     #
-    #   class A < BitStruct
+    #   class A < FuzzStruct
     #     nest    :n,  Sub
     #   end
     #

Modified: topf/trunk/lib/fuzz-struct/octet-field.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/octet-field.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-struct/octet-field.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,13 +1,13 @@
 require 'fuzz-struct/char-field'
 
-class BitStruct
+class FuzzStruct
   # Class for char fields that can be accessed with values like
   # "xxx.xxx.xxx.xxx", where each xxx is up to 3 decimal digits representing a
   # single octet. The original string-based accessors are still available with
   # the <tt>_chars</tt> suffix.
   # 
-  # Declared with BitStruct.octets.
-  class OctetField < BitStruct::CharField
+  # Declared with FuzzStruct.octets.
+  class OctetField < FuzzStruct::CharField
     # Used in describe.
     def self.class_name
       @class_name ||= "octets"
@@ -44,7 +44,7 @@
   end
   
   class << self
-    # Define an octet string field in the current subclass of BitStruct,
+    # Define an octet string field in the current subclass of FuzzStruct,
     # with the given _name_ and _length_ (in bits). Trailing nulls are
     # not considered part of the string. The field is accessed using
     # period-separated decimal digits.

Modified: topf/trunk/lib/fuzz-struct/pad-field.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/pad-field.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-struct/pad-field.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,6 +1,6 @@
 require 'fuzz-struct/fuzz-struct'
 
-class BitStruct
+class FuzzStruct
   # Class for fixed length padding.
   class PadField < Field
     # Used in describe.
@@ -16,7 +16,7 @@
   end
   
   class << self
-    # Define a padding field in the current subclass of BitStruct,
+    # Define a padding field in the current subclass of FuzzStruct,
     # with the given _name_ and _length_ (in bits).
     #
     # If a class is provided, use it for the Field class.

Modified: topf/trunk/lib/fuzz-struct/signed-field.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/signed-field.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-struct/signed-field.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,8 +1,8 @@
 require 'fuzz-struct/fuzz-struct'
 
-class BitStruct
+class FuzzStruct
   # Class for signed integers in network order, 1-16 bits, or 8n bits.
-  # Declared with BitStruct.signed.
+  # Declared with FuzzStruct.signed.
   class SignedField < Field
     # Used in describe.
     def self.class_name
@@ -214,7 +214,7 @@
   end
 
   class << self
-    # Define a signed integer field in the current subclass of BitStruct,
+    # Define a signed integer field in the current subclass of FuzzStruct,
     # with the given _name_ and _length_ (in bits).
     #
     # If a class is provided, use it for the Field class.

Modified: topf/trunk/lib/fuzz-struct/text-field.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/text-field.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-struct/text-field.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,8 +1,8 @@
 require 'fuzz-struct/fuzz-struct'
 
-class BitStruct
+class FuzzStruct
   # Class for null-terminated printable text strings.
-  # Declared with BitStruct.text.
+  # Declared with FuzzStruct.text.
   class TextField < Field
     # Used in describe.
     def self.class_name
@@ -45,7 +45,7 @@
   end
   
   class << self
-    # Define a printable text string field in the current subclass of BitStruct,
+    # Define a printable text string field in the current subclass of FuzzStruct,
     # with the given _name_ and _length_ (in bits). Trailing nulls are
     # _not_ considered part of the string.
     #

Modified: topf/trunk/lib/fuzz-struct/unsigned-field.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/unsigned-field.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-struct/unsigned-field.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,8 +1,8 @@
 require 'fuzz-struct/fuzz-struct'
 
-class BitStruct
+class FuzzStruct
   # Class for unsigned integers in network order, 1-16 bits, or 8n bits.
-  # Declared with BitStruct.unsigned.
+  # Declared with FuzzStruct.unsigned.
   class UnsignedField < Field
     # Used in describe.
     def self.class_name
@@ -204,7 +204,7 @@
   end
 
   class << self
-    # Define a unsigned integer field in the current subclass of BitStruct,
+    # Define a unsigned integer field in the current subclass of FuzzStruct,
     # with the given _name_ and _length_ (in bits).
     #
     # If a class is provided, use it for the Field class.

Modified: topf/trunk/lib/fuzz-struct/yaml.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/yaml.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz-struct/yaml.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,7 +1,7 @@
 require 'fuzz-struct/fuzz-struct'
 require 'yaml'
 
-class BitStruct
+class FuzzStruct
   if RUBY_VERSION == "1.8.2"
     def is_complex_yaml? # :nodoc:
       true
@@ -40,7 +40,7 @@
       props
     end
 
-    # Return YAML representation of the BitStruct.
+    # Return YAML representation of the FuzzStruct.
     def to_yaml( opts = {} )
       YAML::quick_emit( object_id, opts ) do |out|
         out.map( taguri, to_yaml_style ) do |map|
@@ -53,10 +53,10 @@
 
     def self.yaml_new( klass, tag, val ) # :nodoc:
       unless Hash === val
-        raise YAML::TypeError, "Invalid BitStruct: " + val.inspect
+        raise YAML::TypeError, "Invalid FuzzStruct: " + val.inspect
       end
 
-      bitstruct_name, bitstruct_type = YAML.read_type_class( tag, BitStruct )
+      bitstruct_name, bitstruct_type = YAML.read_type_class( tag, FuzzStruct )
 
       st = bitstruct_type.new
 

Modified: topf/trunk/lib/fuzz.rb
===================================================================
--- topf/trunk/lib/fuzz.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/fuzz.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,54 +1,135 @@
+class String
+    # insert! copies the string before altering it compared to the normal insert
+    # method
+    def insert!(index, inject)
+        self.clone.insert(index, inject)
+    end
+end
+
 module Fuzz
+    # define your own if you want :)
     MAX_RAND = 1000
 
+    # This Class collects many FuzzStructs and takes a block to calculate the
+    # wanted output of everything.
     class Collection
-        def initialize
-            @structs = []
+        attr_reader :structs, :number_of_tests
+        def initialize(join_character = "")
+            @join_character = join_character
+            @structs = Array.new 
+            @format_block = nil
+            @prepared = false
+            @fuzz_index = 0
+            @number_of_tests = 0
         end
-        def add(struct)
-            raise "argument must be a Fuzz::Test object" if !struct.is_a?(BitStruct)
-            @structs.push struct
+
+        # adds a FuzzStruct to the collection
+        def add_struct(struct)
+            @structs << struct if struct
         end
-        # fuzzes only one struct at the time
-        def linear_fuzz
+
+        # apply tests to all objects in the collection
+        def add_tests(tests)
+            raise "argument must be a Fuzz::Tests object" if !tests.is_a?(Fuzz::Tests)
             @structs.each do |struct|
-                
+                struct.prepare! tests
+                @number_of_tests += struct.permutations
             end
+            @prepared = true
         end
-        # joins all structs together but only fuzzes one struct after another
-        def join_fuzz
+
+        def add_format_block(&block)
+            @format_block = block
         end
+
+        def fuzz!(args)
+            raise "no tests have been added yet" if !@prepared
+            args[:fuzz_index] = @fuzz_index
+            resultString, @fuzz_index = to_s( args )
+            @number_of_tests-=1
+            [ resultString, @number_of_tests]
+        end
+
+        # supply a block on howto format the collection 
+        def to_s(args)
+            raise "no format block given yet!" if !@format_block
+            @format_block.call(args, @structs, @join_character) 
+        end
     end
 
-    class BinaryObserver 
-        def initialize( programname, *arguments )
+    class BinaryObserver
+        attr_reader :coremanager
+        def initialize( programname, corepath, *arguments )
             @programname = programname
             @arguments = arguments.to_a
             @pid = nil
+            @coremanager = Fuzz::CoreManager.new(@programname, corepath)
+            @running = false
         end
+        
         def observe!
-            @pid = fork do 
-                trap("CLD") do
-                    pid = Process.wait
-                    puts "Child pid #{pid}: terminated"
-                    process_status = $?
+            Thread.new do 
+                @pid = fork do 
+                    Fuzz::LOGGER.info "[x] starting #{@programname} #{@arguments.join(" ")}"
+                    exec("#{@programname} #{@arguments.join(" ")} ")
                 end
-                Fuzz::LOGGER.info "[x] starting #{@programname}"
-                system("#{@programname} #{@arguments.join(" ")} ")
+                @running = true
+                Process.wait
+                Fuzz::LOGGER.debug "[!] %d coredumped? %s" % [@pid, process_status.coredump?]
+                Fuzz::LOGGER.debug "[!] %d get uncaught signal %d" % [@pid, process_status.termsig] if process_status.signaled?
+                Fuzz::LOGGER.debug "[!] %d stopped by signal %d" % [@pid, process_status.stopsig] if process_status.stopped?
+                Fuzz::LOGGER.debug "[!] %d exited %d" % [@pid, process_status.exitstatus] if process_status.exited?
+                @running = false
             end
-                #            Fuzz::LOGGER.debug "[!] %d coredumped? %s" % [@pid, process_status.coredump?]
-                #            Fuzz::LOGGER.debug "[!] %d get uncaught signal %d" % [@pid, process_status.termsig] if process_status.signaled?
-                #            Fuzz::LOGGER.debug "[!] %d stopped by signal %d" % [@pid, process_status.stopsig] if process_status.stopped?
-                #            Fuzz::LOGGER.debug "[!] %d exited %d" % [@pid, process_status.exitstatus] if process_status.exited?
         end
         def get_pid
             @pid
         end
         def exit
-           Process.kill "KILL", @pid 
+           Process.kill "KILL", @pid if @running 
         end
     end
 
+    class CoreManager
+        def initialize(executable, corepath)
+            @executable = executable
+            @corepath = corepath
+            @list = get_corefiles
+            enable_coredump
+        end
+
+        def latest_corefile
+            @list.last
+        end
+
+        def new_corefile?
+            new = get_corefiles
+            if new.size > 0 && new != @list
+                @list = new
+                true
+            else
+                false
+            end
+        end       
+
+        def get_latest_backtrace
+            GDB::Interface.new( {:executable => @executable, :core => @corepath+"/"+ at list.last} ).bt if @list
+        end 
+   
+        def get_latest_registers
+            GDB::Interface.new( {:executable => @executable, :core => @corepath+"/"+ at list.last} ).info("registers") if @list
+        end
+
+        def enable_coredump
+            system("ulimit -c unlimited")
+        end
+    private
+
+        def get_corefiles
+            Dir.new(File.expand_path(@corepath)).entries.select{|entry| entry=~/core/ }.sort{|x, y| File.mtime(@corepath+"/"+x) <=> File.mtime(@corepath+"/"+y)}
+        end
+    end
+
     # This Class holds all tests to related to a given field-type
     class Tests
         attr_reader :tests, :permutations, :signed_tests, :char_tests, :unsigned_tests
@@ -143,6 +224,11 @@
                         temp.push( test.run(arg, length) )
                     end
                     result.push(temp)
+                when "BitStruct::HexOctetField"
+                    @hex_tests.each do |test|
+                        temp.push( test.run(arg, length) )
+                    end
+                    result.push(temp)
                 else
                     Fuzz::LOGGER.debug "new field-type: %s" % field.class.to_s
                 end
@@ -200,15 +286,55 @@
                 @test.call arg, size
         end
     end
-   
-    def Fuzz.coreObserver(file)
-        if Dir.new(File.expand_path(File.dirname(file)) ).entries.select{|x| x=~/\.core/}.size != 0
-            return true
-        else
-            return false
+
+    def Fuzz.fuzz_iterator(struct, &block)
+        while true
+            block.call( struct.fuzz! )
         end
     end
 
+    def Fuzz.fuzz(observer, struct, &block)
+        begin
+            Fuzz::fuzz_iterator(struct, &block)
+        rescue Exception => exception
+            Fuzz::LOGGER.info "[?] error while sending data:\n%s\n" % data
+            Fuzz::LOGGER.info "[?] locking for new corefiles.."
+            if observer.coremanager.new_corefile?
+                Fuzz::LOGGER.info "[?] found new corefile(%s)\nprinting backtrace:\n%s\nprinting registers:\n%s" %  [ observer.coremanager.latest_corefile, observer.coremanager.get_latest_backtrace, observer.coremanager.get_latest_registers ]
+            else
+                Fuzz::LOGGER.info "[?] no new corefile found"
+            end
+            Kernel::exit
+        end
+    end
+
+    def Fuzz.argument(application, struct, config)
+        reg = Regexp.new "outch!" 
+        coremanager = Fuzz::CoreManager.new(application, config["COREDIR"])
+        begin
+            Fuzz::fuzz_iterator(struct){|argument|
+                argument = argument.join if argument.is_a?(Array)
+                system(application + " " + argument)
+                raise "outch!\n%s" % argument if coremanager.new_corefile?
+            }
+        rescue Exception => exception
+            if exception.to_s =~ reg
+                argument = exception.to_s.gsub("outch!", "")
+                puts "!"*40
+                puts "argument:\n%s \nkilled the application!" % argument
+                puts "backtrace:"
+                puts coremanager.get_latest_backtrace
+                puts "_"*40
+                puts "registers:"
+                puts coremanager.get_latest_registers
+                puts "writing POC"
+                File.open("POC", "w+").write "#!/bin/sh\n#{application.strip} #{argument.strip}"
+                puts "!"*40 
+            end
+            Kernel::exit
+        end
+    end
+
     # makes a Connection to a given target and sends our raw data to it
     # see yourself what options are needed :>
     class Connection
@@ -219,7 +345,7 @@
             @path = args[:path]
             @http_direction = args[:http_direction]
             @http_url       = args[:http_url]
-            @object         = args[:object]
+            @observer       = args[:observer]
             args[:timeout] ? @timeout = args[:timeout] : @timeout = 0.2
 
             Fuzz::LOGGER.level = Logger::INFO if !args[:debug]
@@ -243,18 +369,15 @@
 
         def fuzz!(structs, join_character="", args={})
             structs = [structs] if !structs.is_a? Array
-            structs.each do |struct|
-                begin
-                    while true
-                        data = struct.fuzz!.join( join_character )
-                        Fuzz::LOGGER.debug "sending data: %s" % data
-                        self.send data
-                        assert(args[:assert] )
-                    end
-                rescue Exception => exception
-                    Fuzz::LOGGER.debug "[!] ERROR: %s" % $!
-                    Fuzz::LOGGER.debug "[!] \n%s" % exception.backtrace.join("\n")
-                end
+            structs.each_with_index do |struct, index|
+                Fuzz::LOGGER.info "[x] fuzzing struct %d of %d with %d permutations" % [index+1, structs.size, 0]
+  
+                Fuzz.fuzz(@observer, struct){|struct|
+                    data = struct.join( join_character )
+                    Fuzz::LOGGER.debug "sending data: %s" % data
+                    self.send data
+                    assert(args[:assert] )
+                }
             end
             raise "finished all tests"
         end
@@ -263,9 +386,8 @@
         def assert(reply = [])
             begin
                 timeout(@timeout) do 
-                    reply_data = @socket.readline()
-                    raise "ASSERTION %s FAILED" % reply.join(",") if !reply.include?(reply_data.strip)
-                    Fuzz::LOGGER.debug "reply: %s" % reply_data
+                    reply_data = Regexp.new( @socket.readline() )
+                    raise "ASSERTION %s FAILED\nreceived %s" % [ reply.join(","), reply_data] if !reply.find_all{|x| x=~ reply_data}
                 end
             rescue Exception
                 Fuzz::LOGGER.debug "[!] Exception: %s" % $!
@@ -302,9 +424,27 @@
         DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  ""      } # Return empty String 
         DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  "A"*arg.size    } # FAULTING ARGUMENT STRING
         DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  "A"*Fuzz::MAX_RAND    } # LONG STRING
-        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  "%n"*Fuzz::MAX_RAND   } # FORMAT STRING
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!(arg.size/2, "%n"*23)   } # FORMAT STRING
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  "\n"  } # newline 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "\n" )  } # neeline insert!
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  "\r\n"  } # newline 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "\r\n" )  } # newline insert!
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  "\0"  } # nullbyte
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "\0" )  } # nullbyte insert!
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "=" )  } # assign insert! 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "/" )  } # assign insert! 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "\\" )  } # assign insert! 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "," )  } # assign insert! 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, ";" )  } # assign insert! 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "{" )  } # assign insert! 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "}" )  } # assign insert! 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "[" )  } # assign insert! 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "]" )  } # assign insert! 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, "(" )  } # assign insert! 
+        DEFAULT_TESTS.register Fuzz::Test.new("char") {|arg, size|  arg.insert!( arg.size/2, ")" )  } # assign insert! 
 
         # Tests for signed numbers
+        DEFAULT_TESTS.register Fuzz::Test.new("signed") {|arg, size|  arg } # return zero 
         DEFAULT_TESTS.register Fuzz::Test.new("signed") {|arg, size|  0 } # return zero 
         DEFAULT_TESTS.register Fuzz::Test.new("signed") {|arg, size|  rand(5) } # return a small number 
         DEFAULT_TESTS.register Fuzz::Test.new("signed") {|arg, size|  -1      } # return -1 
@@ -312,6 +452,7 @@
         DEFAULT_TESTS.register Fuzz::Test.new("signed") {|arg, size|  -(2.power!(size)/2)       } # smallest 2s complement number
         
         # Tests for unsigned numbers
+        DEFAULT_TESTS.register Fuzz::Test.new("unsigned") {|arg, size|  arg } # return zero 
         DEFAULT_TESTS.register Fuzz::Test.new("unsigned") {|arg, size|  0 } # return zero 
         DEFAULT_TESTS.register Fuzz::Test.new("unsigned") {|arg, size|  rand(5) } # return a small number 
         DEFAULT_TESTS.register Fuzz::Test.new("unsigned") {|arg, size|  2.power!(size) } # return biggest number 

Modified: topf/trunk/lib/pkcs1.rb
===================================================================
--- topf/trunk/lib/pkcs1.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/pkcs1.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -20,808 +20,732 @@
 
 
 module PKCS1
+    # 1 Introduction
+    # 2 Notation
 
+    module Util
+        module_function
 
-# 1 Introduction
+        def nbits(num)
+            idx = num.size * 8 - 1
+            while idx >= 0
+                if num[idx].nonzero?
+                    return idx + 1
+                end
+                idx -= 1
+            end
+            0
+        end
 
+        def divceil(a, b)
+            (a + b - 1) / b
+        end
 
-# 2 Notation
-
-module Util
-module_function
-
-  def nbits(num)
-    idx = num.size * 8 - 1
-    while idx >= 0
-      if num[idx].nonzero?
-        return idx + 1
-      end
-      idx -= 1
+        def xor(a, b)
+            if a.size != b.size
+                raise ArgumentError
+            end
+            ary = []
+            a.size.times do |idx|
+                ary << (a[idx] ^ b[idx])
+            end
+            ary.pack("c*")
+        end
     end
-    0
-  end
 
-  def divceil(a, b)
-    (a + b - 1) / b
-  end
 
-  def xor(a, b)
-    if a.size != b.size
-      raise ArgumentError
-    end
-    ary = []
-    a.size.times do |idx|
-      ary << (a[idx] ^ b[idx])
-    end
-    ary.pack("c*")
-  end
-end
+    # 3 Key types
+    module Key
+        class RSAPublicKey
+            attr_reader :n
+            attr_reader :e
 
+            def initialize(n, e)
+                @n, @e = n, e
+                @n_bn = OpenSSL::BN.new(@n.to_s)
+                @e_bn = OpenSSL::BN.new(@e.to_s)
+            end
 
-# 3 Key types
-module Key
-  class RSAPublicKey
-    attr_reader :n
-    attr_reader :e
+            def encrypt(m)
+                calc(m)
+            end
 
-    def initialize(n, e)
-      @n, @e = n, e
-      @n_bn = OpenSSL::BN.new(@n.to_s)
-      @e_bn = OpenSSL::BN.new(@e.to_s)
-    end
+            # M = S ^ e (mod n)
+            def verify(s)
+                if s < 0 or s >= @n
+                    raise ArgumentError, "signature representative out of range"
+                end
+                calc(s)
+            end
 
-    def encrypt(m)
-      calc(m)
-    end
+            private
 
-    # M = S ^ e (mod n)
-    def verify(s)
-      if s < 0 or s >= @n
-        raise ArgumentError, "signature representative out of range"
-      end
-      calc(s)
-    end
+            # c = m ^ e (mod n)
+            def calc(input)
+                input_bn = OpenSSL::BN.new(input.to_s)
+                (input_bn.mod_exp(@e_bn, @n_bn)).to_i
+            end
+        end
 
-  private
 
-    # c = m ^ e (mod n)
-    def calc(input)
-      input_bn = OpenSSL::BN.new(input.to_s)
-      (input_bn.mod_exp(@e_bn, @n_bn)).to_i
-    end
-  end
+        class RSAPrivateKey
+            include Util
 
+            attr_reader :public_key
+            attr_reader :version
+            attr_reader :n
+            attr_reader :d
 
-  class RSAPrivateKey
-    include Util
+            def initialize(n, e, d)
+                @version = 0
+                @n, @d = n, d
+                @n_bn = OpenSSL::BN.new(@n.to_s)
+                @d_bn = OpenSSL::BN.new(@d.to_s)
+                @public_key = RSAPublicKey.new(n, e)
+            end
 
-    attr_reader :public_key
-    attr_reader :version
-    attr_reader :n
-    attr_reader :d
+            def modbytes
+                divceil(modbits, 8)
+            end
 
-    def initialize(n, e, d)
-      @version = 0
-      @n, @d = n, d
-      @n_bn = OpenSSL::BN.new(@n.to_s)
-      @d_bn = OpenSSL::BN.new(@d.to_s)
-      @public_key = RSAPublicKey.new(n, e)
-    end
+            def modbits
+                nbits(@n)
+            end
 
-    def modbytes
-      divceil(modbits, 8)
-    end
+            def encrypt(m)
+                @public_key.encrypt(m)
+            end
 
-    def modbits
-      nbits(@n)
-    end
+            def decrypt(c)
+                calc(c)
+            end
 
-    def encrypt(m)
-      @public_key.encrypt(m)
-    end
+            def sign(m)
+                if m < 0 or m >= @n
+                    raise ArgumentError, "message representative out of range"
+                end
+                calc(m)
+            end
 
-    def decrypt(c)
-      calc(c)
-    end
+            def verify(s)
+                @public_key.verify(s)
+            end
 
-    def sign(m)
-      if m < 0 or m >= @n
-        raise ArgumentError, "message representative out of range"
-      end
-      calc(m)
-    end
+            private
 
-    def verify(s)
-      @public_key.verify(s)
-    end
+            # s = m ^ d (mod n)
+            def calc(input)
+                input_bn = OpenSSL::BN.new(input.to_s)
+                (input_bn.mod_exp(@d_bn, @n_bn)).to_i
+            end
+        end
 
-  private
 
-    # s = m ^ d (mod n)
-    def calc(input)
-      input_bn = OpenSSL::BN.new(input.to_s)
-      (input_bn.mod_exp(@d_bn, @n_bn)).to_i
-    end
-  end
+        class RSACRTPrivateKey
+            include Util
 
+            attr_reader :public_key
+            attr_reader :version
+            attr_reader :n
+            attr_reader :p
+            attr_reader :q
+            attr_reader :dp
+            attr_reader :dq
+            attr_reader :qinv
 
-  class RSACRTPrivateKey
-    include Util
+            def initialize(n, e, p, q, dp, dq, qinv)
+                @version = 0
+                @n = n
+                @n_bn = OpenSSL::BN.new(@n.to_s)
+                @p, @q, @dp, @dq, @qinv = p, q, dp, dq, qinv
+                @p_bn = OpenSSL::BN.new(@p.to_s)
+                @q_bn = OpenSSL::BN.new(@q.to_s)
+                @dp_bn = OpenSSL::BN.new(@dp.to_s)
+                @dq_bn = OpenSSL::BN.new(@dq.to_s)
+                @qinv_bn = OpenSSL::BN.new(@qinv.to_s)
+                @public_key = RSAPublicKey.new(n, e)
+            end
 
-    attr_reader :public_key
-    attr_reader :version
-    attr_reader :n
-    attr_reader :p
-    attr_reader :q
-    attr_reader :dp
-    attr_reader :dq
-    attr_reader :qinv
+            def modbytes
+                divceil(modbits, 8)
+            end
 
-    def initialize(n, e, p, q, dp, dq, qinv)
-      @version = 0
-      @n = n
-      @n_bn = OpenSSL::BN.new(@n.to_s)
-      @p, @q, @dp, @dq, @qinv = p, q, dp, dq, qinv
-      @p_bn = OpenSSL::BN.new(@p.to_s)
-      @q_bn = OpenSSL::BN.new(@q.to_s)
-      @dp_bn = OpenSSL::BN.new(@dp.to_s)
-      @dq_bn = OpenSSL::BN.new(@dq.to_s)
-      @qinv_bn = OpenSSL::BN.new(@qinv.to_s)
-      @public_key = RSAPublicKey.new(n, e)
-    end
+            def modbits
+                nbits(@n)
+            end
 
-    def modbytes
-      divceil(modbits, 8)
-    end
+            def encrypt(m)
+                @public_key.encrypt(m)
+            end
 
-    def modbits
-      nbits(@n)
-    end
+            def decrypt(c)
+                calc(c)
+            end
 
-    def encrypt(m)
-      @public_key.encrypt(m)
-    end
+            def sign(m)
+                if m < 0 or m >= @n
+                    raise ArgumentError, "message representative out of range"
+                end
+                calc(m)
+            end
 
-    def decrypt(c)
-      calc(c)
-    end
+            def verify(s)
+                @public_key.verify(s)
+            end
 
-    def sign(m)
-      if m < 0 or m >= @n
-        raise ArgumentError, "message representative out of range"
-      end
-      calc(m)
-    end
+            private
 
-    def verify(s)
-      @public_key.verify(s)
-    end
+            # s1 = m ^ dp (mod p)
+            # s2 = m ^ dq (mod q)
+            # h = (s1 - s2) * qinv (mod p)
+            # s = s2 + q * h
+            def calc(input)
+                input_bn = OpenSSL::BN.new(input.to_s)
+                s1 = input_bn.mod_exp(@dp_bn, @p_bn)
+                s2 = input_bn.mod_exp(@dq_bn, @q_bn)
+                h = @qinv_bn.mod_mul(s1 - s2, @p_bn)
+                (s2 + q * h).to_i
+            end
+        end
 
-  private
 
-    # s1 = m ^ dp (mod p)
-    # s2 = m ^ dq (mod q)
-    # h = (s1 - s2) * qinv (mod p)
-    # s = s2 + q * h
-    def calc(input)
-      input_bn = OpenSSL::BN.new(input.to_s)
-      s1 = input_bn.mod_exp(@dp_bn, @p_bn)
-      s2 = input_bn.mod_exp(@dq_bn, @q_bn)
-      h = @qinv_bn.mod_mul(s1 - s2, @p_bn)
-      (s2 + q * h).to_i
+        RSA = RSAPrivateKey
+        RSACRT = RSACRTPrivateKey
     end
-  end
 
 
-  RSA = RSAPrivateKey
-  RSACRT = RSACRTPrivateKey
-end
+    # 4 Data conversion primitives
+    module DataConversion
+        module_function
 
-
-# 4 Data conversion primitives
-module DataConversion
-module_function
-
-  # Integer to Octet String primitive
-  def i2osp(x, len)
-    if x >= 256 ** len
-      raise ArgumentError, "integer too large"
-    end
-    os = to_bytes(x).sub(/^\x00+/, '')
+        # Integer to Octet String primitive
+        def i2osp(x, len)
+            if x >= 256 ** len
+                raise ArgumentError, "integer too large"
+            end
+            os = to_bytes(x).sub(/^\x00+/, '')
     "\x00" * (len - os.size) + os
-  end
+        end
 
-  # Octet String to Integer primitive
-  def os2ip(x)
-    from_bytes(x)
-  end
+        # Octet String to Integer primitive
+        def os2ip(x)
+            from_bytes(x)
+        end
 
-  def to_bytes(num)
-    bits = num.size * 8
-    pos = value = 0
-    str = ""
-    for idx in 0..(bits - 1)
-      if num[idx].nonzero?
-        value |= (num[idx] << pos)
-      end
-      pos += 1
-      if pos == 32
-        str = [value].pack("N") + str
-        pos = value = 0
-      end
-    end
-    str
-  end
+        def to_bytes(num)
+            bits = num.size * 8
+            pos = value = 0
+            str = ""
+            for idx in 0..(bits - 1)
+                if num[idx].nonzero?
+                    value |= (num[idx] << pos)
+                end
+                pos += 1
+                if pos == 32
+                    str = [value].pack("N") + str
+                    pos = value = 0
+                end
+            end
+            str
+        end
 
-  def from_bytes(bytes)
-    num = 0
-    bytes.each_byte do |c|
-      num <<= 8
-      num |= c
+        def from_bytes(bytes)
+            num = 0
+            bytes.each_byte do |c|
+                num <<= 8
+                num |= c
+            end
+            num
+        end
     end
-    num
-  end
-end
 
 
-# 5 Cryptographic primitives
-module CryptographicPrimitive
-module_function
+    # 5 Cryptographic primitives
+    module CryptographicPrimitive
+        module_function
 
-  def rsaep(key, msg)
-    key.encrypt(msg)
-  end
+        def rsaep(key, msg)
+            key.encrypt(msg)
+        end
 
-  def rsadp(key, cipher)
-    key.decrypt(cipher)
-  end
+        def rsadp(key, cipher)
+            key.decrypt(cipher)
+        end
 
-  def rsasp1(key, msg)
-    key.sign(msg)
-  end
+        def rsasp1(key, msg)
+            key.sign(msg)
+        end
 
-  def rsavp1(key, sig)
-    key.verify(sig)
-  end
-end
+        def rsavp1(key, sig)
+            key.verify(sig)
+        end
+    end
 
 
-# 6 Overview of schemes
+    # 6 Overview of schemes
 
 
-# 7 Encryption schemes
-module EncryptionScheme
-module_function
-  
-  def rsaes_oaep_encrypt(key, msg, seed = nil, label = '')
-    RSAESOAEP.new.encrypt(key, msg, seed, label)
-  end
+    # 7 Encryption schemes
+    module EncryptionScheme
+        module_function
 
-  def rsaes_oaep_decrypt(key, cipher, seed = nil, label = '')
-    RSAESOAEP.new.decrypt(key, cipher, seed, label)
-  end
+        def rsaes_oaep_encrypt(key, msg, seed = nil, label = '')
+            RSAESOAEP.new.encrypt(key, msg, seed, label)
+        end
 
+        def rsaes_oaep_decrypt(key, cipher, seed = nil, label = '')
+            RSAESOAEP.new.decrypt(key, cipher, seed, label)
+        end
 
-  class RSAESOAEP
-    include DataConversion
-    include CryptographicPrimitive
 
-    def initialize(digest = Digest::SHA1)
-      @hlen = Hash.size(digest)
-      @encryption_encoder = EncryptionEncoding::EMEOAEP.new(digest)
-    end
+        class RSAESOAEP
+            include DataConversion
+            include CryptographicPrimitive
 
-    def encrypt(key, msg, seed = nil, label = '')
-      k = key.modbytes
-      if msg.size > k - 2 * @hlen - 2
-        raise ArgumentError, "message too long"
-      end
-      em = @encryption_encoder.encode(msg, k, seed, label)
-      m = os2ip(em)
-      c = rsaep(key, m)
-      i2osp(c, k)
-    end
+            def initialize(digest = Digest::SHA1)
+                @hlen = Hash.size(digest)
+                @encryption_encoder = EncryptionEncoding::EMEOAEP.new(digest)
+            end
 
-    def decrypt(key, cipher, label = '')
-      k = key.modbytes
-      if cipher.size != k
-        raise ArgumentError, "decryption error"
-      end
-      if k < 2 * @hlen + 2
-        raise ArgumentError, "decryption error"
-      end
-      c = os2ip(cipher)
-      m = rsadp(key, c)
-      em = i2osp(m, k)
-      @encryption_encoder.decode(em, k, label)
+            def encrypt(key, msg, seed = nil, label = '')
+                k = key.modbytes
+                if msg.size > k - 2 * @hlen - 2
+                    raise ArgumentError, "message too long"
+                end
+                em = @encryption_encoder.encode(msg, k, seed, label)
+                m = os2ip(em)
+                c = rsaep(key, m)
+                i2osp(c, k)
+            end
+
+            def decrypt(key, cipher, label = '')
+                k = key.modbytes
+                if cipher.size != k
+                    raise ArgumentError, "decryption error"
+                end
+                if k < 2 * @hlen + 2
+                    raise ArgumentError, "decryption error"
+                end
+                c = os2ip(cipher)
+                m = rsadp(key, c)
+                em = i2osp(m, k)
+                @encryption_encoder.decode(em, k, label)
+            end
+        end
     end
-  end
-end
 
 
-# 7.1.1 1.b and 7.1.2 3 Encoding methods for encryption
-module EncryptionEncoding
-module_function
+    # 7.1.1 1.b and 7.1.2 3 Encoding methods for encryption
+    module EncryptionEncoding
+        module_function
 
-  def eme_oaep_encode(msg, embits, seed = nil)
-    EMEOAEP.new.encode(msg, embits, seed)
-  end
+        def eme_oaep_encode(msg, embits, seed = nil)
+            EMEOAEP.new.encode(msg, embits, seed)
+        end
 
-  def eme_oaep_decode(msg, em, embits)
-    EMEOAEP.new.decode(msg, em, embits)
-  end
+        def eme_oaep_decode(msg, em, embits)
+            EMEOAEP.new.decode(msg, em, embits)
+        end
 
 
-  class EMEOAEP
-    include Util
+        class EMEOAEP
+            include Util
 
-    def initialize(digest = Digest::SHA1, mgf = nil)
-      @digest = digest
-      @hlen = Hash.size(@digest)
-      @mgf = mgf || MaskGeneration::MGF1.new(@digest)
-    end
+            def initialize(digest = Digest::SHA1, mgf = nil)
+                @digest = digest
+                @hlen = Hash.size(@digest)
+                @mgf = mgf || MaskGeneration::MGF1.new(@digest)
+            end
 
-    def encode(msg, embytes, seed = nil, label = '')
-      lhash = dohash(label)
-      ps = "\x00" * (embytes - msg.size - 2 * @hlen - 2)
-      db = lhash + ps + "\x01" + msg
-      seed ||= OpenSSL::Random.random_bytes(@hlen)
-      dbmask = @mgf.generate(seed, embytes - @hlen - 1)
-      maskeddb = xor(db, dbmask)
-      seedmask = @mgf.generate(maskeddb, @hlen)
-      maskedseed = xor(seed, seedmask)
+            def encode(msg, embytes, seed = nil, label = '')
+                lhash = dohash(label)
+                ps = "\x00" * (embytes - msg.size - 2 * @hlen - 2)
+                db = lhash + ps + "\x01" + msg
+                seed ||= OpenSSL::Random.random_bytes(@hlen)
+                dbmask = @mgf.generate(seed, embytes - @hlen - 1)
+                maskeddb = xor(db, dbmask)
+                seedmask = @mgf.generate(maskeddb, @hlen)
+                maskedseed = xor(seed, seedmask)
       "\x00" + maskedseed + maskeddb
-    end
+            end
 
-    def decode(em, embytes, label = '')
-      lhash = dohash(label)
-      y = em[0]
-      maskedseed = em[1, @hlen]
-      maskeddb = em[1 + @hlen, embytes - @hlen - 1]
-      seedmask = @mgf.generate(maskeddb, @hlen)
-      seed = xor(maskedseed, seedmask)
-      dbmask = @mgf.generate(seed, embytes - @hlen - 1)
-      db = xor(maskeddb, dbmask)
-      lhashdash = db[0, @hlen]
-      if lhashdash != lhash
-        raise ArgumentError, "decryption error"
-      end
-      psm = db[@hlen, embytes - 2 * @hlen - 1]
-      if /\A(\x00*)\x01([\x00-\xff]*)\z/ =~ psm
-        ps, m = $1, $2
-      else
-        raise ArgumentError, "decryption error"
-      end
-      m
-    end
+            def decode(em, embytes, label = '')
+                lhash = dohash(label)
+                y = em[0]
+                maskedseed = em[1, @hlen]
+                maskeddb = em[1 + @hlen, embytes - @hlen - 1]
+                seedmask = @mgf.generate(maskeddb, @hlen)
+                seed = xor(maskedseed, seedmask)
+                dbmask = @mgf.generate(seed, embytes - @hlen - 1)
+                db = xor(maskeddb, dbmask)
+                lhashdash = db[0, @hlen]
+                if lhashdash != lhash
+                    raise ArgumentError, "decryption error"
+                end
+                psm = db[@hlen, embytes - 2 * @hlen - 1]
+                if /\A(\x00*)\x01([\x00-\xff]*)\z/ =~ psm
+                    ps, m = $1, $2
+                else
+                    raise ArgumentError, "decryption error"
+                end
+                m
+            end
 
-  private
+            private
 
-    def dohash(msg)
-      @digest.digest(msg)
+            def dohash(msg)
+                @digest.digest(msg)
+            end
+        end
     end
-  end
-end
 
 
-# 8 Signature schemes
-module SignatureScheme
-module_function
+    # 8 Signature schemes
+    module SignatureScheme
+        module_function
 
-  def rsassa_pss_sign(key, msg)
-    RSASSAPSS.new.sign(key, msg)
-  end
+        def rsassa_pss_sign(key, msg)
+            RSASSAPSS.new.sign(key, msg)
+        end
 
-  def rsassa_pss_verify(key, msg, sig)
-    RSASSAPSS.new.verify(key, msg, sig)
-  end
+        def rsassa_pss_verify(key, msg, sig)
+            RSASSAPSS.new.verify(key, msg, sig)
+        end
 
-  def rsassa_pss_sign_hash(key, hash)
-    RSASSAPSS.new.sign_hash(key, hash)
-  end
+        def rsassa_pss_sign_hash(key, hash)
+            RSASSAPSS.new.sign_hash(key, hash)
+        end
 
-  def rsassa_pss_verify_hash(key, hash, sig)
-    RSASSAPSS.new.verify_hash(key, hash, sig)
-  end
+        def rsassa_pss_verify_hash(key, hash, sig)
+            RSASSAPSS.new.verify_hash(key, hash, sig)
+        end
 
-  def rsassa_pkcs1v1_5_sign(key, msg)
-    RSASSAPKCS1v1_5.new.sign(key, msg)
-  end
+        def rsassa_pkcs1v1_5_sign(key, msg)
+            RSASSAPKCS1v1_5.new.sign(key, msg)
+        end
 
-  def rsassa_pkcs1v1_5_verify(key, msg, sig)
-    RSASSAPKCS1v1_5.new.verify(key, msg, sig)
-  end
+        def rsassa_pkcs1v1_5_verify(key, msg, sig)
+            RSASSAPKCS1v1_5.new.verify(key, msg, sig)
+        end
 
-  def rsassa_pkcs1v1_5_sign_hash(key, hash)
-    RSASSAPKCS1v1_5.new.sign_hash(key, hash)
-  end
+        def rsassa_pkcs1v1_5_sign_hash(key, hash)
+            RSASSAPKCS1v1_5.new.sign_hash(key, hash)
+        end
 
-  def rsassa_pkcs1v1_5_verify_hash(key, hash, sig)
-    RSASSAPKCS1v1_5.new.verify_hash(key, hash, sig)
-  end
+        def rsassa_pkcs1v1_5_verify_hash(key, hash, sig)
+            RSASSAPKCS1v1_5.new.verify_hash(key, hash, sig)
+        end
 
 
-  class RSASSAPSS
-    include Util
-    include DataConversion
-    include CryptographicPrimitive
+        class RSASSAPSS
+            include Util
+            include DataConversion
+            include CryptographicPrimitive
 
-    def initialize(digest = Digest::SHA1, slen = 20, mgf = nil)
-      @signature_encoder = SignatureEncoding::EMSAPSS.new(digest, slen, mgf)
-    end
+            def initialize(digest = Digest::SHA1, slen = 20, mgf = nil)
+                @signature_encoder = SignatureEncoding::EMSAPSS.new(digest, slen, mgf)
+            end
 
-    def sign(key, msg, salt = nil)
-      modbits = key.modbits
-      em = @signature_encoder.encode(msg, modbits - 1, salt)
-      sign_em(key, em, modbits)
-    end
+            def sign(key, msg, salt = nil)
+                modbits = key.modbits
+                em = @signature_encoder.encode(msg, modbits - 1, salt)
+                sign_em(key, em, modbits)
+            end
 
-    def sign_hash(key, hash, salt = nil)
-      modbits = key.modbits
-      em = @signature_encoder.encode_hash(hash, modbits - 1, salt)
-      sign_em(key, em, modbits)
-    end
+            def sign_hash(key, hash, salt = nil)
+                modbits = key.modbits
+                em = @signature_encoder.encode_hash(hash, modbits - 1, salt)
+                sign_em(key, em, modbits)
+            end
 
-    def verify(key, msg, sig)
-      modbits = key.modbits
-      em = decode_em(key, sig, modbits)
-      @signature_encoder.verify(msg, em, modbits - 1)
-    end
+            def verify(key, msg, sig)
+                modbits = key.modbits
+                em = decode_em(key, sig, modbits)
+                @signature_encoder.verify(msg, em, modbits - 1)
+            end
 
-    def verify_hash(key, hash, sig)
-      modbits = key.modbits
-      em = decode_em(key, sig, modbits)
-      @signature_encoder.verify_hash(hash, em, modbits - 1)
-    end
+            def verify_hash(key, hash, sig)
+                modbits = key.modbits
+                em = decode_em(key, sig, modbits)
+                @signature_encoder.verify_hash(hash, em, modbits - 1)
+            end
 
-  private
+            private
 
-    def sign_em(key, em, modbits)
-      m = os2ip(em)
-      s = rsasp1(key, m)
-      s = i2osp(s, divceil(modbits, 8))
-      s
-    end
+            def sign_em(key, em, modbits)
+                m = os2ip(em)
+                s = rsasp1(key, m)
+                s = i2osp(s, divceil(modbits, 8))
+                s
+            end
 
-    def decode_em(key, sig, modbits)
-      if sig.size != divceil(modbits - 1, 8)
-        raise ArgumentError, "invalid signature"
-      end
-      s = os2ip(sig)
-      m = rsavp1(key, s)
-      emlen = divceil(modbits - 1, 8)
-      i2osp(m, emlen)
-    end
-  end
+            def decode_em(key, sig, modbits)
+                if sig.size != divceil(modbits - 1, 8)
+                    raise ArgumentError, "invalid signature"
+                end
+                s = os2ip(sig)
+                m = rsavp1(key, s)
+                emlen = divceil(modbits - 1, 8)
+                i2osp(m, emlen)
+            end
+        end
 
 
-  class RSASSAPKCS1v1_5
-    include DataConversion
-    include CryptographicPrimitive
+        class RSASSAPKCS1v1_5
+            include DataConversion
+            include CryptographicPrimitive
 
-    def initialize(digest = Digest::SHA1)
-      @signature_encoder = SignatureEncoding::EMSAPKCS1v1_5.new(digest)
-    end
+            def initialize(digest = Digest::SHA1)
+                @signature_encoder = SignatureEncoding::EMSAPKCS1v1_5.new(digest)
+            end
 
-    def sign(key, msg)
-      k = key.modbytes
-      em = @signature_encoder.encode(msg, k)
-      sign_em(key, em, k)
-    end
+            def sign(key, msg)
+                k = key.modbytes
+                em = @signature_encoder.encode(msg, k)
+                sign_em(key, em, k)
+            end
 
-    def sign_hash(key, hash)
-      k = key.modbytes
-      em = @signature_encoder.encode_hash(hash, k)
-      sign_em(key, em, k)
-    end
+            def sign_hash(key, hash)
+                k = key.modbytes
+                em = @signature_encoder.encode_hash(hash, k)
+                sign_em(key, em, k)
+            end
 
-    def verify(key, msg, sig)
-      k = key.modbytes
-      em = decode_em(key, sig, k)
-      emdash = @signature_encoder.encode(msg, k)
-      unless em == emdash
-        raise ArgumentError, "invalid signature"
-      end
-      true
-    end
+            def verify(key, msg, sig)
+                k = key.modbytes
+                em = decode_em(key, sig, k)
+                emdash = @signature_encoder.encode(msg, k)
+                unless em == emdash
+                    raise ArgumentError, "invalid signature"
+                end
+                true
+            end
 
-    def verify_hash(key, hash, sig)
-      k = key.modbytes
-      em = decode_em(key, sig, k)
-      emdash = @signature_encoder.encode_hash(hash, k)
-      unless em == emdash
-        raise ArgumentError, "invalid signature"
-      end
-      true
-    end
+            def verify_hash(key, hash, sig)
+                k = key.modbytes
+                em = decode_em(key, sig, k)
+                emdash = @signature_encoder.encode_hash(hash, k)
+                unless em == emdash
+                    raise ArgumentError, "invalid signature"
+                end
+                true
+            end
 
-  private
+            private
 
-    def sign_em(key, em, k)
-      m = os2ip(em)
-      s = rsasp1(key, m)
-      i2osp(s, k)
-    end
+            def sign_em(key, em, k)
+                m = os2ip(em)
+                s = rsasp1(key, m)
+                i2osp(s, k)
+            end
 
-    def decode_em(key, sig, k)
-      if sig.size != k
-        raise ArgumentError, "invalid signature"
-      end
-      s = os2ip(sig)
-      m = rsavp1(key, s)
-      i2osp(m, k)
+            def decode_em(key, sig, k)
+                if sig.size != k
+                    raise ArgumentError, "invalid signature"
+                end
+                s = os2ip(sig)
+                m = rsavp1(key, s)
+                i2osp(m, k)
+            end
+        end
     end
-  end
-end
 
 
-# 9 Encoding methods for signatures with appendix
-module SignatureEncoding
-module_function
+    # 9 Encoding methods for signatures with appendix
+    module SignatureEncoding
+        module_function
 
-  def emsa_pss_encode(msg, embits, salt = nil)
-    EMSAPSS.new.encode(msg, embits, salt)
-  end
+        def emsa_pss_encode(msg, embits, salt = nil)
+            EMSAPSS.new.encode(msg, embits, salt)
+        end
 
-  def emsa_pss_verify(msg, em, embits)
-    EMSAPSS.new.verify(msg, em, embits)
-  end
+        def emsa_pss_verify(msg, em, embits)
+            EMSAPSS.new.verify(msg, em, embits)
+        end
 
-  def emsa_pkcs1_v1_5_encode(msg, emlen)
-    EMSAPKCS1v1_5.new.encode(msg, emlen)
-  end
+        def emsa_pkcs1_v1_5_encode(msg, emlen)
+            EMSAPKCS1v1_5.new.encode(msg, emlen)
+        end
 
 
-  class EMSAPSS
-    include Util
+        class EMSAPSS
+            include Util
 
-    def initialize(digest = Digest::SHA1, slen = 20, mgf = nil)
-      @digest = digest
-      @slen = slen
-      @hlen = Hash.size(@digest)
-      @mgf = mgf || MaskGeneration::MGF1.new(@digest)
-    end
+            def initialize(digest = Digest::SHA1, slen = 20, mgf = nil)
+                @digest = digest
+                @slen = slen
+                @hlen = Hash.size(@digest)
+                @mgf = mgf || MaskGeneration::MGF1.new(@digest)
+            end
 
-    def encode(msg, embits, salt = nil)
-      mhash = dohash(msg)
-      encode_hash(mhash, embits, salt)
-    end
+            def encode(msg, embits, salt = nil)
+                mhash = dohash(msg)
+                encode_hash(mhash, embits, salt)
+            end
 
-    def encode_hash(mhash, embits, salt = nil)
-      emlen = divceil(embits, 8)
-      if emlen < @hlen + @slen + 2
-        raise ArgumentError, "encoding error"
-      end
-      salt ||= OpenSSL::Random.random_bytes(@slen)
-      mdash = "\x00" * 8 + mhash + salt
-      h = dohash(mdash)
-      ps = "\x00" * (emlen - @slen - @hlen - 2)
-      db = ps + "\x01" + salt
-      dbmask = @mgf.generate(h, emlen - @hlen - 1)
-      maskeddb = xor(db, dbmask)
-      maskeddb[0] &= (0xff >> (8 * emlen - embits))
-      p [emlen, embits, (0xff >> (8 * emlen - embits))]
-      em = maskeddb + h + "\xbc"
-      em
-    end
+            def encode_hash(mhash, embits, salt = nil)
+                emlen = divceil(embits, 8)
+                if emlen < @hlen + @slen + 2
+                    raise ArgumentError, "encoding error"
+                end
+                salt ||= OpenSSL::Random.random_bytes(@slen)
+                mdash = "\x00" * 8 + mhash + salt
+                h = dohash(mdash)
+                ps = "\x00" * (emlen - @slen - @hlen - 2)
+                db = ps + "\x01" + salt
+                dbmask = @mgf.generate(h, emlen - @hlen - 1)
+                maskeddb = xor(db, dbmask)
+                maskeddb[0] &= (0xff >> (8 * emlen - embits))
+                #p [emlen, embits, (0xff >> (8 * emlen - embits))]
+                em = maskeddb + h + "\xbc"
+                em
+            end
 
-    def verify(msg, em, embits)
-      mhash = dohash(msg)
-      verify_hash(mhash, em, embits)
-    end
+            def verify(msg, em, embits)
+                mhash = dohash(msg)
+                verify_hash(mhash, em, embits)
+            end
 
-    def verify_hash(mhash, em, embits)
-      emlen = divceil(embits, 8)
-      if emlen < @hlen + @slen + 2
-        raise ArgumentError, "inconsistent"
-      end
-      if em[-1] != 0xbc
-        raise ArgumentError, "inconsistent"
-      end
-      maskeddb = em[0, emlen - @hlen - 1]
-      h = em[emlen - @hlen - 1, @hlen]
-      if maskeddb[0] & (0xff >> (8 * emlen - embits)) != maskeddb[0]
-        raise ArgumentError, "inconsistent"
-      end
-      dbmask = @mgf.generate(h, emlen - @hlen - 1)
-      db = xor(maskeddb, dbmask)
-      db[0] &= (0xff >> (8 * emlen - embits))
-      if /\A\x00+\z/ !~ db[0, emlen - @hlen - @slen - 2]
-        raise ArgumentError, "inconsistent"
-      end
-      if db[emlen - @hlen - @slen - 2] != 0x01
-        raise ArgumentError, "inconsistent"
-      end
-      salt = db[db.size - @slen, @slen]
-      mdash = "\x00" * 8 + mhash + salt
-      hdash = dohash(mdash)
-      if h != hdash
-        raise ArgumentError, "inconsistent"
-      end
-      true
-    end
+            def verify_hash(mhash, em, embits)
+                emlen = divceil(embits, 8)
+                if emlen < @hlen + @slen + 2
+                    raise ArgumentError, "inconsistent"
+                end
+                if em[-1] != 0xbc
+                    raise ArgumentError, "inconsistent"
+                end
+                maskeddb = em[0, emlen - @hlen - 1]
+                h = em[emlen - @hlen - 1, @hlen]
+                if maskeddb[0] & (0xff >> (8 * emlen - embits)) != maskeddb[0]
+                    raise ArgumentError, "inconsistent"
+                end
+                dbmask = @mgf.generate(h, emlen - @hlen - 1)
+                db = xor(maskeddb, dbmask)
+                db[0] &= (0xff >> (8 * emlen - embits))
+                if /\A\x00+\z/ !~ db[0, emlen - @hlen - @slen - 2]
+                    raise ArgumentError, "inconsistent"
+                end
+                if db[emlen - @hlen - @slen - 2] != 0x01
+                    raise ArgumentError, "inconsistent"
+                end
+                salt = db[db.size - @slen, @slen]
+                mdash = "\x00" * 8 + mhash + salt
+                hdash = dohash(mdash)
+                if h != hdash
+                    raise ArgumentError, "inconsistent"
+                end
+                true
+            end
 
-  private
+            private
 
-    def dohash(msg)
-      @digest.digest(msg)
-    end
-  end
+            def dohash(msg)
+                @digest.digest(msg)
+            end
+        end
 
 
-  class EMSAPKCS1v1_5
-    def initialize(digest = Digest::SHA1)
-      @digest = digest
-    end
+        class EMSAPKCS1v1_5
+            def initialize(digest = Digest::SHA1)
+                @digest = digest
+            end
 
-    def encode(msg, emlen)
-      h = dohash(msg)
-      encode_hash(h, emlen)
-    end
+            def encode(msg, emlen)
+                h = dohash(msg)
+                encode_hash(h, emlen)
+            end
 
-    def encode_hash(h, emlen)
-      t = Hash.asnoid(@digest) + h
-      if emlen < t.size + 11
-        raise ArgumentError, "intended encoded message length too short"
-      end
-      ps = "\xff" * (emlen - t.size - 3)
+            def encode_hash(h, emlen)
+                t = Hash.asnoid(@digest) + h
+                if emlen < t.size + 11
+                    raise ArgumentError, "intended encoded message length too short"
+                end
+                ps = "\xff" * (emlen - t.size - 3)
       "\x00\x01" + ps + "\x00" + t
-    end
+            end
 
-  private
+            private
 
-    def dohash(msg)
-      @digest.digest(msg)
+            def dohash(msg)
+                @digest.digest(msg)
+            end
+        end
     end
-  end
-end
 
 
-# B.1 Hash functions
-module Hash
-  ALGORITHMS = {
-    # MD5: 1.2.840.113549.2.5
-    Digest::MD5 => [16, [0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48,
-      0x86, 0xF7, 0x0D, 0x02, 0x05, 0x00, 0x04, 0x10]],
-    # SHA-1: 1.3.14.3.2.26
-    Digest::SHA1 => [20, [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03,
-      0x02, 0x1A, 0x05, 0x00, 0x04, 0x14]],
-    # SHA256: 2.16.840.1.101.3.4.2.1
-    Digest::SHA256 => [32, [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20]],
-    # SHA384: 2.16.840.1.101.3.4.2.2
-    Digest::SHA384 => [48, [0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30]],
-    # SHA512: 2.16.840.1.101.3.4.2.3
-    Digest::SHA512 => [64, [0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40]],
-  }
+    # B.1 Hash functions
+    module Hash
+        ALGORITHMS = {
+            # MD5: 1.2.840.113549.2.5
+            Digest::MD5 => [16, [0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48,
+                0x86, 0xF7, 0x0D, 0x02, 0x05, 0x00, 0x04, 0x10]],
+                # SHA-1: 1.3.14.3.2.26
+                Digest::SHA1 => [20, [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03,
+                    0x02, 0x1A, 0x05, 0x00, 0x04, 0x14]],
+                    # SHA256: 2.16.840.1.101.3.4.2.1
+                    Digest::SHA256 => [32, [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+                        0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20]],
+                        # SHA384: 2.16.840.1.101.3.4.2.2
+                        Digest::SHA384 => [48, [0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+                            0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30]],
+                            # SHA512: 2.16.840.1.101.3.4.2.3
+                            Digest::SHA512 => [64, [0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+                                0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40]],
+        }
 
-module_function
+        module_function
 
-  def asnoid(digest)
-    unless ALGORITHMS.key?(digest)
-      raise ArgumentError, "unknown digest: #{digest}"
-    end
-    ALGORITHMS[digest][1].pack("c*")
-  end
+        def asnoid(digest)
+            unless ALGORITHMS.key?(digest)
+                raise ArgumentError, "unknown digest: #{digest}"
+            end
+            ALGORITHMS[digest][1].pack("c*")
+        end
 
-  def size(digest)
-    unless ALGORITHMS.key?(digest)
-      raise ArgumentError, "unknown digest: #{digest}"
+        def size(digest)
+            unless ALGORITHMS.key?(digest)
+                raise ArgumentError, "unknown digest: #{digest}"
+            end
+            ALGORITHMS[digest][0]
+        end
     end
-    ALGORITHMS[digest][0]
-  end
-end
 
 
-# B.2 Mask generation functions
-module MaskGeneration
-module_function
+    # B.2 Mask generation functions
+    module MaskGeneration
+        module_function
 
-  def mgf1(seed, masklen)
-    MGF1.new.generate(seed, masklen)
-  end
+        def mgf1(seed, masklen)
+            MGF1.new.generate(seed, masklen)
+        end
 
 
-  class MGF1
-    include Util
-    include DataConversion
+        class MGF1
+            include Util
+            include DataConversion
 
-    def initialize(digest = Digest::SHA1)
-      @digest = digest
-      @hlen = Hash.size(@digest)
-    end
+            def initialize(digest = Digest::SHA1)
+                @digest = digest
+                @hlen = Hash.size(@digest)
+            end
 
-    def generate(seed, masklen)
-      if masklen > (2 << 31) * @hlen
-        raise ArgumentError, "mask too long"
-      end
-      t = ""
-      divceil(masklen, @hlen).times do |counter|
-        t += dohash(seed + i2osp(counter, 4))
-      end
-      t[0, masklen]
-    end
+            def generate(seed, masklen)
+                if masklen > (2 << 31) * @hlen
+                    raise ArgumentError, "mask too long"
+                end
+                t = ""
+                divceil(masklen, @hlen).times do |counter|
+                    t += dohash(seed + i2osp(counter, 4))
+                end
+                t[0, masklen]
+            end
 
-  private
+            private
 
-    def dohash(msg)
-      @digest.digest(msg)
+            def dohash(msg)
+                @digest.digest(msg)
+            end
+        end
     end
-  end
-end
 
-
 end
-
-=begin
-if $0 == __FILE__
-  #pkeyfile = ARGV.shift or raise "pkey file not given"
-
-  osslkey = OpenSSL::PKey::RSA.new(1024)
-
-  n = osslkey.n.to_i
-  e = osslkey.e.to_i
-  d = osslkey.d.to_i
-  p = osslkey.p.to_i
-  q = osslkey.q.to_i
-  dp = osslkey.dmp1.to_i
-  dq = osslkey.dmq1.to_i
-  qinv = osslkey.iqmp.to_i
-
-require 'hexdump'
-require 'base64'
-  rsapss = PKCS1::SignatureScheme::RSASSAPSS.new(Digest::SHA256, 0, PKCS1::MaskGeneration::MGF1.new(Digest::SHA1))
-  key = PKCS1::Key::RSA.new(n, e, d)
-# {{{
-#  key2 = PKCS1::Key::RSACRTPrivateKey.new(n, d, p, q, dp, dq, qinv)
-#  puts PGP::HexDump.encode(rsapss.sign_hash(key2, "hello world", "\0"*8))
-
-  #p Base64::b64encode  PKCS1::DataConversion.i2osp(65537, 3)
-  #puts "-"*100
-  #p PKCS1::DataConversion.os2ip(PKCS1::DataConversion.i2osp(65537, 3))
-# }}}
-  key = PKCS1::Key::RSA.new(osslkey.n.to_i, osslkey.e.to_i, osslkey.d.to_i)
-  msg = "hello"
-  #p PKCS1::DataConversion.i2osp(PKCS1::CryptographicPrimitive.rsadp(key, PKCS1::CryptographicPrimitive.rsaep(key, PKCS1::DataConversion.os2ip(msg))), msg.size)# {{{
-  #p PKCS1::DataConversion.i2osp(PKCS1::CryptographicPrimitive.rsavp1(key, PKCS1::CryptographicPrimitive.rsasp1(key, PKCS1::DataConversion.os2ip(msg))), msg.size)
-
-  #p PKCS1::MaskGeneration.mgf1("abc", 20)
-  #p PKCS1::MaskGeneration.mgf1("abcd", 20)
-# }}}
-  pss = PKCS1::SignatureEncoding::EMSAPSS.new(Digest::SHA1, 8)
-  #p pss.encode("hello", 1023)# {{{
-  #p pss.verify("hello", pss.encode("hello", 1023), 1023)
-
-  #rsapss = PKCS1::SignatureScheme::RSASSAPSS.new(Digest::SHA1, 0)
-  #p rsapss.sign(key, "hello")
-  #p rsapss.verify(key, "hello", rsapss.sign(key, "hello"))
-# }}}
-  msg = "foo\nbar" * 1024
-  hash = Digest::SHA1.digest(msg)
-  #p rsapss.verify_hash(key, hash, rsapss.sign_hash(key, hash))# {{{
-  #p rsapss.verify(key, msg, rsapss.sign_hash(key, hash))
-  #p rsapss.verify_hash(key, hash, rsapss.sign(key, msg))
-
-  #p Base64::b64encode PKCS1::SignatureEncoding.emsa_pkcs1_v1_5_encode("foo", 128)# }}}
-  puts "-"*100
-  rsapkcs1 = PKCS1::SignatureScheme::RSASSAPKCS1v1_5.new(Digest::SHA1)
-  p Base64::b64encode rsapkcs1.sign(key, "hello")
-  puts "-"*100# {{{
-  #p Base64::b64encode rsapkcs1.verify(key, "hello", rsapkcs1.sign(key, "hello"))
-  puts "-"*100
-  #p  Base64::b64encode osslkey.sign(OpenSSL::Digest::SHA1.new, "hello")
-  puts "-"*100
-  #p  Base64::b64encode osslkey.verify(OpenSSL::Digest::SHA1.new, rsapkcs1.sign(key, "hello"), "hello")
-# }}}
-  rsaoaep = PKCS1::EncryptionScheme::RSAESOAEP.new(Digest::SHA1)
-  msg = "hello"
-#  p rsaoaep.encrypt(key, msg)
-#  p Base64::b64encode osslkey.public_encrypt(msg, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
-  puts "-"*100# {{{
-  #p osslkey.private_decrypt(rsaoaep.encrypt(key, msg), OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) == msg
-  #puts "-"*100
-  #p rsaoaep.decrypt(key, rsaoaep.encrypt(key, msg)) == msg# }}}
-end
-=end

Modified: topf/trunk/lib/topf.rb
===================================================================
--- topf/trunk/lib/topf.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/lib/topf.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -11,6 +11,7 @@
 
 require "fuzz-struct"
 require "fuzz"
+require "gdb"
 
 require "dir"
 require "control"

Modified: topf/trunk/tor-control-fuzz.rb
===================================================================
--- topf/trunk/tor-control-fuzz.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/tor-control-fuzz.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,7 +1,9 @@
 require "lib/topf"
 
 begin
-    observer = Fuzz::BinaryObserver.new "tor", "-f stuff/torrc", "&> /dev/null"
+    config = YAML::load_file "config/config.yml"
+
+    observer = Fuzz::BinaryObserver.new "#{config["BINDIR"]}/tor", config["COREDIR"], "-f #{config["CONFDIR"]}/torrc", "&> /dev/null"
     observer.observe!
     sleep 2 
     
@@ -15,14 +17,14 @@
    
     Fuzz::LOGGER.info "[x] loading options"
 
-    config = YAML::load_file "config/config.yml"
 
     options = {
         :host => config["HOST"], 
         :port => config["CONTROLPORT"],
         :debug => config["DEBUG"],
         :type => :tcp,
-        :timeout => 0.01,
+        #:timeout => 0.01,
+        :timeout => 0.5,
         :observer => observer
     }
 
@@ -60,7 +62,7 @@
     
 rescue Exception => error
     #Fuzz::LOGGER.info "[x] %s\n%s\nclosing everything down" % [ $!, error.backtrace.join("\n") ]
-    Fuzz::LOGGER.info "[x] %s\nclosing everything down" % [ $! ]
+    Fuzz::LOGGER.info "[x] closing everything down" 
     fuzzer.close if fuzzer
     observer.exit if observer and started
 end

Modified: topf/trunk/tor-dir-fuzz.rb
===================================================================
--- topf/trunk/tor-dir-fuzz.rb	2007-08-20 10:10:09 UTC (rev 11213)
+++ topf/trunk/tor-dir-fuzz.rb	2007-08-20 11:09:04 UTC (rev 11214)
@@ -1,17 +1,15 @@
 require "lib/topf"
 
 begin
-    observer = Fuzz::BinaryObserver.new "tor", "-f torrc", "&> /dev/null"
+    config = YAML::load_file "config/config.yml"
+
+    observer = Fuzz::BinaryObserver.new "#{config["BINDIR"]}/tor", config["COREDIR"], "-f #{config["CONFDIR"]}/torrc", "&> /dev/null"
     observer.observe!
     sleep 2
 
-
-    config = YAML::load_file "config.yml"
+    Fuzz::LOGGER.info "[x] tor pid: %d" % observer.get_pid
     
-    rd = TOPF::Dir::RouterDescriptor.new( config["KEYFILE"])
-    
     options = {
-        :object => rd,
         :host   => config["HOST"],
         :port   => config["DIRPORT"],
         :type   => :http,
@@ -20,8 +18,76 @@
         :debug => config["DEBUG"] 
     }
 
-    fuzzer = Fuzz::Connection.new( options ) 
-    fuzzer.fuzz!
+    osslkey = OpenSSL::PKey::RSA.new(1024)
+    pkcs1 = PKCS1::SignatureScheme::RSASSAPKCS1v1_5.new(Digest::SHA1)
+    key = PKCS1::Key::RSA.new(osslkey.n.to_i , osslkey.e.to_i, osslkey.d.to_i)
+
+
+    TOPF::Dir::ROUTERDESCRIPTOR = Fuzz::Collection.new("\n")
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::RouterItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::PlatformItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::PublishedItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::FingerprintItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::UptimeItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::BandwidthItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::OnionKeyItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::SigningKeyItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::WriteHistoryItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::ReadHistoryItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::ContactItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_struct TOPF::Dir::RejectItem.new
+    TOPF::Dir::ROUTERDESCRIPTOR.add_tests Fuzz::DEFAULT_TESTS
+
+    TOPF::Dir::ROUTERDESCRIPTOR.add_format_block{|args, structs, join_char|
+        resultString = []
+        structs.each_with_index do |struct, index|
+            if index == args[:fuzz_index]
+                begin
+                    data = struct.fuzz!.join(" ")
+                    resultString.push data 
+                rescue Exception => exception
+                    Fuzz::LOGGER.info "[x] fuzzing #{struct.class}" 
+                    args[:fuzz_index] += 1
+                end
+            else
+                resultString.push struct.output(" ") 
+            end
+        end
+        resultString = resultString.join(join_char)
+
+        resultString << "\nrouter-signature\n"
+        #sig = Base64::b64encode( args[:pkcs1].sign(args[:key], resultString) )
+        #sig =  Base64::b64encode( Digest::SHA1.hexdigest( args[:pkcs1].sign(args[:key], resultString)  ) )
+        #sig = Base64::b64encode( PKCS1::SignatureScheme::RSASSAPSS.new.sign(args[:key], resultString)  )
+        #sig = Base64::b64encode( PKCS1::SignatureScheme::RSASSAPKCS1v1_5.new.sign(args[:key], resultString)  )
+        sig = ""
+
+        resultString << "-----BEGIN SIGNATURE-----\n"
+        resultString << sig
+        resultString << "-----END SIGNATURE-----" << "\n"*2
+        [ resultString, args[:fuzz_index] ]
+    }
+
+    fuzzer = Fuzz::Connection.new( options )
+    
+    actual_number = 0
+    number_of_tests = TOPF::Dir::ROUTERDESCRIPTOR.number_of_tests
+
+    Thread.new do 
+        while true
+            sleep 10
+            actual = number_of_tests-actual_number
+            Fuzz::LOGGER.info "[i] %d%% %d/%d tests done" % [ actual/(number_of_tests/100.0), actual, number_of_tests  ]
+        end
+    end
+
+    while true
+        data, actual_number = TOPF::Dir::ROUTERDESCRIPTOR.fuzz!( {:pkcs1 => pkcs1, :key => key , :osslkey => osslkey} ) 
+        response, body = fuzzer.send data
+    end
+
+rescue Exception => exception
+    Fuzz::LOGGER.info "[x] %s\n%s\nclosing everything down" % [ $!, exception.backtrace.join("\n") ]
     fuzzer.close
     observer.exit
 end



More information about the tor-commits mailing list