[前][次][番号順一覧][スレッド一覧]

ruby-changes:19666

From: emboss <ko1@a...>
Date: Mon, 23 May 2011 10:01:56 +0900 (JST)
Subject: [ruby-changes:19666] emboss:r31711 (trunk): * ext/openssl/ossl_asn1.c: Do not parse zero-tagged values as EOC. Do

emboss	2011-05-23 10:01:49 +0900 (Mon, 23 May 2011)

  New Revision: 31711

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31711

  Log:
    * ext/openssl/ossl_asn1.c: Do not parse zero-tagged values as EOC. Do
    not let current length become negative for infinite length constructed
    values. Support constructed values of length zero. Added tests.

  Modified files:
    trunk/ChangeLog
    trunk/ext/openssl/ossl_asn1.c
    trunk/test/openssl/test_asn1.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 31710)
+++ ChangeLog	(revision 31711)
@@ -1,3 +1,9 @@
+Mon May 23 10:01:02 2011  Martin Bosslet  <Martin.Bosslet@g...>
+
+	* ext/openssl/ossl_asn1.c: Do not parse zero-tagged values as EOC. Do
+	not let current length become negative for infinite length constructed
+	values. Support constructed values of length zero. Added tests.
+
 Mon May 23 09:19:53 2011  Eric Hodel  <drbrain@s...>
 
 	* lib/net/smtp.rb:  Document Net::SMTP::Response.  Patch by J.R. Garcia.
Index: ext/openssl/ossl_asn1.c
===================================================================
--- ext/openssl/ossl_asn1.c	(revision 31710)
+++ ext/openssl/ossl_asn1.c	(revision 31711)
@@ -838,9 +838,9 @@
 }
 
 static VALUE
-int_ossl_asn1_decode0_cons(unsigned char **pp, long length, long *offset,
-			   int depth, int yield, int j, int tag, VALUE tc,
-			   long *num_read)
+int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
+			   long *offset, int depth, int yield, int j,
+			   int tag, VALUE tc, long *num_read)
 {
     VALUE value, asn1data, ary;
     int infinite;
@@ -851,13 +851,18 @@
 
     while (length > 0 || infinite) {
 	long inner_read = 0;
-	value = ossl_asn1_decode0(pp, length, &off, depth + 1, yield, &inner_read);
+	value = ossl_asn1_decode0(pp, max_len, &off, depth + 1, yield, &inner_read);
 	*num_read += inner_read;
+	max_len -= inner_read;
 	rb_ary_push(ary, value);
-	length -= inner_read;
+	if (length > 0)
+	    length -= inner_read;
 	
-	if (infinite && NUM2INT(ossl_asn1_get_tag(value)) == V_ASN1_EOC)
+	if (infinite &&
+	    NUM2INT(ossl_asn1_get_tag(value)) == V_ASN1_EOC &&
+	    SYM2ID(ossl_asn1_get_tag_class(value)) == sUNIVERSAL) {
 	    break;
+	}
     }
 
     if (tc == sUNIVERSAL && (tag == V_ASN1_SEQUENCE || V_ASN1_SET)) {
@@ -899,7 +904,7 @@
 {
     unsigned char *start, *p;
     const unsigned char *p0;
-    long len, inner_read = 0, off = *offset;
+    long len = 0, inner_read = 0, off = *offset;
     int hlen, tag, tc, j;
     VALUE asn1data, tag_class;
 
@@ -934,10 +939,9 @@
     }
 
     if(j & V_ASN1_CONSTRUCTED) {
-	long max_len = len == 0 ? length : len;
 	*pp += hlen;
 	off += hlen;
-	asn1data = int_ossl_asn1_decode0_cons(pp, max_len, &off, depth, yield, j, tag, tag_class, &inner_read);
+	asn1data = int_ossl_asn1_decode0_cons(pp, length, len, &off, depth, yield, j, tag, tag_class, &inner_read);
 	inner_read += hlen;
     }
     else {
Index: test/openssl/test_asn1.rb
===================================================================
--- test/openssl/test_asn1.rb	(revision 31710)
+++ test/openssl/test_asn1.rb	(revision 31711)
@@ -266,6 +266,31 @@
     end
   end
 
+  def test_parse_empty_sequence
+    expected = %w{ A0 07 30 02 30 00 02 01 00 }
+    raw = [expected.join('')].pack('H*')
+    asn1 = OpenSSL::ASN1.decode(raw)
+    assert_equal(raw, asn1.to_der)
+    assert_equal(2, asn1.value.size)
+    seq = asn1.value[0]
+    assert_equal(1, seq.value.size)
+    inner_seq = seq.value[0]
+    assert_equal(0, inner_seq.value.size)
+  end
+
+  def test_parse_tagged_0_infinite
+    expected = %w{ 30 80 02 01 01 80 01 02 00 00 }
+    raw = [expected.join('')].pack('H*')
+    asn1 = OpenSSL::ASN1.decode(raw)
+    assert_equal(3, asn1.value.size)
+    int = asn1.value[0]
+    assert_universal(OpenSSL::ASN1::INTEGER, int)
+    tagged = asn1.value[1]
+    assert_equal(0, tagged.tag)
+    assert_universal(OpenSSL::ASN1::EOC, asn1.value[2])
+    assert_equal(raw, asn1.to_der)
+  end
+
   def test_seq_infinite_length
     begin
       content = [ OpenSSL::ASN1::Null.new(nil),

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]