<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -2,6 +2,7 @@
 
 * Added -B CLI option to use the :body authentication scheme (Seth)
 * Added :ca_file consumer option to allow consumer specific certificate override. (Pelle)
+* Added a secure_equals in Helper to prevent timing attacks. (Pelle)
 
 == 0.3.5 2009-06-03
 </diff>
      <filename>History.txt</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,13 @@
-%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
+%w[rubygems rake rake/clean fileutils].each { |f| require f }
 $LOAD_PATH &lt;&lt; File.dirname(__FILE__) + '/lib'
 require 'oauth'
 require 'oauth/version'
 
 begin
   require 'hoe'
+  require 'newgem'
+  require 'rubigen'
+  
   # Generate all the Rake tasks
   # Run 'rake -T' to see list of generated tasks (from gem root directory)
   $hoe = Hoe.new('oauth', OAuth::VERSION) do |p|</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,6 @@
 require 'openssl'
 require 'base64'
+require 'enumerator'
 
 module OAuth
   module Helper
@@ -70,9 +71,30 @@ module OAuth
       # convert into a Hash
       Hash[*params.flatten]
     end
-
+    
+    # A secure version of equals meant to avoid timing attacks as specified here
+    # http://codahale.com/a-lesson-in-timing-attacks/
+    def secure_equals(a,b)
+      return a==b unless a.is_a?(String)&amp;&amp;b.is_a?(String)
+      result = 0
+      bytes(a).zip(bytes(b)).each do |x,y|
+        result |= (x ^ y)
+      end
+      (result == 0) &amp;&amp; (a.length == b.length)
+    end
+    
     def unescape(value)
       URI.unescape(value.gsub('+', '%2B'))
     end
+    
+    # Creates a per byte enumerator for a string regardless of RUBY VERSION
+    def bytes(a)
+      return [] if a.nil?
+      if a.respond_to?(:bytes)
+        a.bytes
+      else
+        Enumerable::Enumerator.new(a, :each_byte)
+      end
+    end
   end
 end
\ No newline at end of file</diff>
      <filename>lib/oauth/helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -55,7 +55,7 @@ module OAuth::Signature
     end
 
     def ==(cmp_signature)
-      Base64.decode64(signature) == Base64.decode64(cmp_signature)
+      secure_equals(Base64.decode64(signature), Base64.decode64(cmp_signature))
     end
 
     def verify</diff>
      <filename>lib/oauth/signature/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,7 @@ module OAuth::Signature
     end
 
     def ==(cmp_signature)
-      signature == escape(cmp_signature)
+      secure_equals(signature , escape(cmp_signature))
     end
 
     def signature_base_string</diff>
      <filename>lib/oauth/signature/plaintext.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@
 
 Gem::Specification.new do |s|
   s.name = %q{oauth}
-  s.version = &quot;0.3.5&quot;
+  s.version = &quot;0.3.6&quot;
 
   s.required_rubygems_version = Gem::Requirement.new(&quot;&gt;= 0&quot;) if s.respond_to? :required_rubygems_version=
   s.authors = [&quot;Pelle Braendgaard&quot;, &quot;Blaine Cook&quot;, &quot;Larry Halff&quot;, &quot;Jesse Clark&quot;, &quot;Jon Crosby&quot;, &quot;Seth Fitzsimmons&quot;, &quot;Matt Sanford&quot;]</diff>
      <filename>oauth.gemspec</filename>
    </modified>
    <modified>
      <diff>@@ -1,19 +1,35 @@
+# encoding: utf-8
 require File.dirname(__FILE__) + '/test_helper.rb'
 
 class TestOauth &lt; Test::Unit::TestCase
-
+  include OAuth::Helper
+  
   def test_parameter_escaping_kcode_invariant
     old = $KCODE
     begin
       %w(n N e E s S u U).each do |kcode|
         $KCODE = kcode
-        assert_equal '%E3%81%82', OAuth::Helper.escape('&#12354;'),
+        assert_equal '%E3%81%82', OAuth::Helper.escape(&quot;&#12354;&quot;),
                       &quot;Failed to correctly escape Japanese under $KCODE = #{kcode}&quot;
-        assert_equal '%C3%A9', OAuth::Helper.escape('&#233;'),
+        assert_equal '%C3%A9', OAuth::Helper.escape(&quot;&#233;&quot;),
                       &quot;Failed to correctly escape e+acute under $KCODE = #{kcode}&quot;
       end
     ensure
       $KCODE = old
     end
   end
+  
+  def test_secure_equals
+    [nil,1,12345,&quot;12345&quot;,'1','Hello'*45].each do |value|
+      assert secure_equals(value,value)
+    end
+  end
+
+  def test_not_secure_equals
+    a=[nil,1,12345,&quot;12345&quot;,'1','Hello'*45]
+    a.zip(a.reverse).each do |a,b|
+      assert !secure_equals(a,b)
+    end
+  end
+
 end</diff>
      <filename>test/test_signature.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>41931cba088e575a0433da7f68a0c9e9b87730b9</id>
    </parent>
  </parents>
  <author>
    <name>Pelle Braendgaard</name>
    <email>pelleb@gmail.com</email>
  </author>
  <url>http://github.com/pelle/oauth/commit/c867394b4b14bc893cc29fbb0b1b839066843b93</url>
  <id>c867394b4b14bc893cc29fbb0b1b839066843b93</id>
  <committed-date>2009-08-13T11:13:38-07:00</committed-date>
  <authored-date>2009-08-13T11:13:38-07:00</authored-date>
  <message>Added a &quot;secure_equals&quot; method to Helper to avoid timing attacks as mentioned here:
http://codahale.com/a-lesson-in-timing-attacks/</message>
  <tree>52327c1f8f2f4884cc3e91b634a60e858b8f478d</tree>
  <committer>
    <name>Pelle Braendgaard</name>
    <email>pelleb@gmail.com</email>
  </committer>
</commit>
