Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 99d9987

Browse files
authoredApr 20, 2024
Merge pull request #286 from justinstoller/prepare-bc-1.76
[refactor] replace methods removed in BC 1.75
2 parents 2e8b6b6 + 6dc57df commit 99d9987

File tree

3 files changed

+808
-24
lines changed

3 files changed

+808
-24
lines changed
 

‎src/main/java/org/jruby/ext/openssl/ASN1.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,23 +1072,22 @@ else if ( obj instanceof DERBMPString ) {
10721072
return ASN1.getClass("ObjectId").newInstance(context, runtime.newString(objId), Block.NULL_BLOCK);
10731073
}
10741074

1075-
if ( obj instanceof ASN1ApplicationSpecific ) { // TODO this will likely break in BC version > 1.71
1076-
final ASN1ApplicationSpecific appSpecific = (ASN1ApplicationSpecific) obj;
1077-
IRubyObject tag = runtime.newFixnum( appSpecific.getApplicationTag() );
1078-
IRubyObject tag_class = runtime.newSymbol("APPLICATION");
1079-
final ASN1Sequence sequence = (ASN1Sequence) appSpecific.getObject(SEQUENCE);
1080-
@SuppressWarnings("unchecked")
1081-
final RubyArray valArr = decodeObjects(context, ASN1, sequence.getObjects());
1082-
return ASN1.getClass("ASN1Data").newInstance(context, new IRubyObject[] { valArr, tag, tag_class }, Block.NULL_BLOCK);
1083-
}
1084-
1085-
if ( obj instanceof ASN1TaggedObject ) {
1075+
if (obj instanceof ASN1TaggedObject) {
10861076
final ASN1TaggedObject taggedObj = (ASN1TaggedObject) obj;
1087-
IRubyObject val = decodeObject(context, ASN1, taggedObj.getBaseObject());
1088-
IRubyObject tag = runtime.newFixnum( taggedObj.getTagNo() );
1089-
IRubyObject tag_class = runtime.newSymbol("CONTEXT_SPECIFIC");
1090-
final RubyArray valArr = runtime.newArray(val);
1091-
return ASN1.getClass("ASN1Data").newInstance(context, new IRubyObject[] { valArr, tag, tag_class }, Block.NULL_BLOCK);
1077+
if (taggedObj.getTagClass() == BERTags.APPLICATION) {
1078+
IRubyObject tag = runtime.newFixnum( taggedObj.getTagNo() );
1079+
IRubyObject tag_class = runtime.newSymbol("APPLICATION");
1080+
final ASN1Sequence sequence = (ASN1Sequence) taggedObj.getBaseUniversal(false, SEQUENCE);
1081+
@SuppressWarnings("unchecked")
1082+
final RubyArray valArr = decodeObjects(context, ASN1, sequence.getObjects());
1083+
return ASN1.getClass("ASN1Data").newInstance(context, new IRubyObject[] { valArr, tag, tag_class }, Block.NULL_BLOCK);
1084+
} else {
1085+
IRubyObject val = decodeObject(context, ASN1, taggedObj.getBaseObject());
1086+
IRubyObject tag = runtime.newFixnum( taggedObj.getTagNo() );
1087+
IRubyObject tag_class = runtime.newSymbol("CONTEXT_SPECIFIC");
1088+
final RubyArray valArr = runtime.newArray(val);
1089+
return ASN1.getClass("ASN1Data").newInstance(context, new IRubyObject[] { valArr, tag, tag_class }, Block.NULL_BLOCK);
1090+
}
10921091
}
10931092

10941093
if ( obj instanceof ASN1Sequence ) {
@@ -1698,13 +1697,13 @@ ASN1Encodable toASN1(final ThreadContext context) {
16981697
}
16991698

17001699
if ( type == DERGeneralString.class ) {
1701-
return DERGeneralString.getInstance( val.asString().getBytes() );
1700+
return ASN1GeneralString.getInstance( val.asString().getBytes() );
17021701
}
17031702
if ( type == DERVisibleString.class ) {
1704-
return DERVisibleString.getInstance( val.asString().getBytes() );
1703+
return ASN1VisibleString.getInstance( val.asString().getBytes() );
17051704
}
17061705
if ( type == DERNumericString.class ) {
1707-
return DERNumericString.getInstance( val.asString().getBytes() );
1706+
return ASN1NumericString.getInstance( val.asString().getBytes() );
17081707
}
17091708

17101709
if ( val instanceof RubyString ) {

‎src/main/java/org/jruby/ext/openssl/X509Extension.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.bouncycastle.asn1.ASN1EncodableVector;
3939
import org.bouncycastle.asn1.ASN1Encoding;
4040
import org.bouncycastle.asn1.ASN1Integer;
41+
import org.bouncycastle.asn1.ASN1IA5String;
4142
import org.bouncycastle.asn1.ASN1Object;
4243
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
4344
import org.bouncycastle.asn1.ASN1OctetString;
@@ -46,7 +47,6 @@
4647
import org.bouncycastle.asn1.ASN1String;
4748
import org.bouncycastle.asn1.ASN1TaggedObject;
4849
import org.bouncycastle.asn1.BERTags;
49-
import org.bouncycastle.asn1.DERIA5String;
5050
import org.bouncycastle.asn1.DEROctetString;
5151
import org.bouncycastle.asn1.DERUniversalString;
5252
import org.bouncycastle.asn1.DLSequence;
@@ -620,7 +620,7 @@ private static boolean formatGeneralName(final GeneralName name, final ByteList
620620
case GeneralName.uniformResourceIdentifier:
621621
if ( ! tagged ) out.append('U').append('R').append('I').
622622
append(':');
623-
val = DERIA5String.getInstance(obj).getString();
623+
val = ASN1IA5String.getInstance(obj).getString();
624624
out.append( ByteList.plain(val) );
625625
break;
626626
case GeneralName.directoryName:

‎src/test/ruby/test_asn1.rb

Lines changed: 788 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,212 @@
33

44
class TestASN1 < TestCase
55

6+
def test_decode_x509_certificate
7+
subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA")
8+
key = Fixtures.pkey("rsa1024")
9+
now = Time.at(Time.now.to_i) # suppress usec
10+
s = 0xdeadbeafdeadbeafdeadbeafdeadbeaf
11+
exts = [
12+
["basicConstraints","CA:TRUE,pathlen:1",true],
13+
["keyUsage","keyCertSign, cRLSign",true],
14+
["subjectKeyIdentifier","hash",false],
15+
]
16+
dgst = OpenSSL::Digest.new('SHA256')
17+
cert = issue_cert(subj, key, s, exts, nil, nil, digest: dgst, not_before: now, not_after: now+3600)
18+
19+
20+
asn1 = OpenSSL::ASN1.decode(cert)
21+
assert_equal(OpenSSL::ASN1::Sequence, asn1.class)
22+
assert_equal(3, asn1.value.size)
23+
tbs_cert, sig_alg, sig_val = *asn1.value
24+
25+
assert_equal(OpenSSL::ASN1::Sequence, tbs_cert.class)
26+
assert_equal(8, tbs_cert.value.size)
27+
28+
version = tbs_cert.value[0]
29+
assert_equal(:CONTEXT_SPECIFIC, version.tag_class)
30+
assert_equal(0, version.tag)
31+
assert_equal(1, version.value.size)
32+
assert_equal(OpenSSL::ASN1::Integer, version.value[0].class)
33+
assert_equal(2, version.value[0].value)
34+
35+
serial = tbs_cert.value[1]
36+
assert_equal(OpenSSL::ASN1::Integer, serial.class)
37+
assert_equal(0xdeadbeafdeadbeafdeadbeafdeadbeaf, serial.value)
38+
39+
sig = tbs_cert.value[2]
40+
assert_equal(OpenSSL::ASN1::Sequence, sig.class)
41+
assert_equal(2, sig.value.size)
42+
assert_equal(OpenSSL::ASN1::ObjectId, sig.value[0].class)
43+
assert_equal("1.2.840.113549.1.1.11", sig.value[0].oid)
44+
assert_equal(OpenSSL::ASN1::Null, sig.value[1].class)
45+
46+
dn = tbs_cert.value[3] # issuer
47+
assert_equal(subj.hash, OpenSSL::X509::Name.new(dn).hash)
48+
assert_equal(OpenSSL::ASN1::Sequence, dn.class)
49+
assert_equal(3, dn.value.size)
50+
assert_equal(OpenSSL::ASN1::Set, dn.value[0].class)
51+
assert_equal(OpenSSL::ASN1::Set, dn.value[1].class)
52+
assert_equal(OpenSSL::ASN1::Set, dn.value[2].class)
53+
assert_equal(1, dn.value[0].value.size)
54+
assert_equal(1, dn.value[1].value.size)
55+
assert_equal(1, dn.value[2].value.size)
56+
assert_equal(OpenSSL::ASN1::Sequence, dn.value[0].value[0].class)
57+
assert_equal(OpenSSL::ASN1::Sequence, dn.value[1].value[0].class)
58+
assert_equal(OpenSSL::ASN1::Sequence, dn.value[2].value[0].class)
59+
assert_equal(2, dn.value[0].value[0].value.size)
60+
assert_equal(2, dn.value[1].value[0].value.size)
61+
assert_equal(2, dn.value[2].value[0].value.size)
62+
oid, value = *dn.value[0].value[0].value
63+
assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
64+
assert_equal("0.9.2342.19200300.100.1.25", oid.oid)
65+
assert_equal(OpenSSL::ASN1::IA5String, value.class)
66+
assert_equal("org", value.value)
67+
oid, value = *dn.value[1].value[0].value
68+
assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
69+
assert_equal("0.9.2342.19200300.100.1.25", oid.oid)
70+
assert_equal(OpenSSL::ASN1::IA5String, value.class)
71+
assert_equal("ruby-lang", value.value)
72+
oid, value = *dn.value[2].value[0].value
73+
assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
74+
assert_equal("2.5.4.3", oid.oid)
75+
assert_equal(OpenSSL::ASN1::UTF8String, value.class)
76+
assert_equal("TestCA", value.value)
77+
78+
validity = tbs_cert.value[4]
79+
assert_equal(OpenSSL::ASN1::Sequence, validity.class)
80+
assert_equal(2, validity.value.size)
81+
assert_equal(OpenSSL::ASN1::UTCTime, validity.value[0].class)
82+
assert_equal(now, validity.value[0].value)
83+
assert_equal(OpenSSL::ASN1::UTCTime, validity.value[1].class)
84+
assert_equal(now+3600, validity.value[1].value)
85+
86+
dn = tbs_cert.value[5] # subject
87+
assert_equal(subj.hash, OpenSSL::X509::Name.new(dn).hash)
88+
assert_equal(OpenSSL::ASN1::Sequence, dn.class)
89+
assert_equal(3, dn.value.size)
90+
assert_equal(OpenSSL::ASN1::Set, dn.value[0].class)
91+
assert_equal(OpenSSL::ASN1::Set, dn.value[1].class)
92+
assert_equal(OpenSSL::ASN1::Set, dn.value[2].class)
93+
assert_equal(1, dn.value[0].value.size)
94+
assert_equal(1, dn.value[1].value.size)
95+
assert_equal(1, dn.value[2].value.size)
96+
assert_equal(OpenSSL::ASN1::Sequence, dn.value[0].value[0].class)
97+
assert_equal(OpenSSL::ASN1::Sequence, dn.value[1].value[0].class)
98+
assert_equal(OpenSSL::ASN1::Sequence, dn.value[2].value[0].class)
99+
assert_equal(2, dn.value[0].value[0].value.size)
100+
assert_equal(2, dn.value[1].value[0].value.size)
101+
assert_equal(2, dn.value[2].value[0].value.size)
102+
oid, value = *dn.value[0].value[0].value
103+
assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
104+
assert_equal("0.9.2342.19200300.100.1.25", oid.oid)
105+
assert_equal(OpenSSL::ASN1::IA5String, value.class)
106+
assert_equal("org", value.value)
107+
oid, value = *dn.value[1].value[0].value
108+
assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
109+
assert_equal("0.9.2342.19200300.100.1.25", oid.oid)
110+
assert_equal(OpenSSL::ASN1::IA5String, value.class)
111+
assert_equal("ruby-lang", value.value)
112+
oid, value = *dn.value[2].value[0].value
113+
assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
114+
assert_equal("2.5.4.3", oid.oid)
115+
assert_equal(OpenSSL::ASN1::UTF8String, value.class)
116+
assert_equal("TestCA", value.value)
117+
118+
pkey = tbs_cert.value[6]
119+
assert_equal(OpenSSL::ASN1::Sequence, pkey.class)
120+
assert_equal(2, pkey.value.size)
121+
assert_equal(OpenSSL::ASN1::Sequence, pkey.value[0].class)
122+
assert_equal(2, pkey.value[0].value.size)
123+
assert_equal(OpenSSL::ASN1::ObjectId, pkey.value[0].value[0].class)
124+
assert_equal("1.2.840.113549.1.1.1", pkey.value[0].value[0].oid)
125+
assert_equal(OpenSSL::ASN1::BitString, pkey.value[1].class)
126+
assert_equal(0, pkey.value[1].unused_bits)
127+
spkey = OpenSSL::ASN1.decode(pkey.value[1].value)
128+
assert_equal(OpenSSL::ASN1::Sequence, spkey.class)
129+
assert_equal(2, spkey.value.size)
130+
assert_equal(OpenSSL::ASN1::Integer, spkey.value[0].class)
131+
assert_equal(cert.public_key.n, spkey.value[0].value)
132+
assert_equal(OpenSSL::ASN1::Integer, spkey.value[1].class)
133+
assert_equal(cert.public_key.e, spkey.value[1].value)
134+
135+
extensions = tbs_cert.value[7]
136+
assert_equal(:CONTEXT_SPECIFIC, extensions.tag_class)
137+
assert_equal(3, extensions.tag)
138+
assert_equal(1, extensions.value.size)
139+
assert_equal(OpenSSL::ASN1::Sequence, extensions.value[0].class)
140+
assert_equal(3, extensions.value[0].value.size)
141+
142+
ext = extensions.value[0].value[0] # basicConstraints
143+
assert_equal(OpenSSL::ASN1::Sequence, ext.class)
144+
assert_equal(3, ext.value.size)
145+
assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)
146+
assert_equal("2.5.29.19", ext.value[0].oid)
147+
assert_equal(OpenSSL::ASN1::Boolean, ext.value[1].class)
148+
assert_equal(true, ext.value[1].value)
149+
assert_equal(OpenSSL::ASN1::OctetString, ext.value[2].class)
150+
extv = OpenSSL::ASN1.decode(ext.value[2].value)
151+
assert_equal(OpenSSL::ASN1::Sequence, extv.class)
152+
assert_equal(2, extv.value.size)
153+
assert_equal(OpenSSL::ASN1::Boolean, extv.value[0].class)
154+
assert_equal(true, extv.value[0].value)
155+
assert_equal(OpenSSL::ASN1::Integer, extv.value[1].class)
156+
assert_equal(1, extv.value[1].value)
157+
158+
ext = extensions.value[0].value[1] # keyUsage
159+
assert_equal(OpenSSL::ASN1::Sequence, ext.class)
160+
assert_equal(3, ext.value.size)
161+
assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)
162+
assert_equal("2.5.29.15", ext.value[0].oid)
163+
assert_equal(OpenSSL::ASN1::Boolean, ext.value[1].class)
164+
assert_equal(true, ext.value[1].value)
165+
assert_equal(OpenSSL::ASN1::OctetString, ext.value[2].class)
166+
extv = OpenSSL::ASN1.decode(ext.value[2].value)
167+
assert_equal(OpenSSL::ASN1::BitString, extv.class)
168+
str = +"\000"; str[0] = 0b00000110.chr
169+
assert_equal(str, extv.value)
170+
171+
ext = extensions.value[0].value[2] # subjectKeyIdentifier
172+
assert_equal(OpenSSL::ASN1::Sequence, ext.class)
173+
assert_equal(2, ext.value.size)
174+
assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)
175+
assert_equal("2.5.29.14", ext.value[0].oid)
176+
assert_equal(OpenSSL::ASN1::OctetString, ext.value[1].class)
177+
extv = OpenSSL::ASN1.decode(ext.value[1].value)
178+
assert_equal(OpenSSL::ASN1::OctetString, extv.class)
179+
sha1 = OpenSSL::Digest.new('SHA1')
180+
sha1.update(pkey.value[1].value)
181+
assert_equal(sha1.digest, extv.value)
182+
183+
assert_equal(OpenSSL::ASN1::Sequence, sig_alg.class)
184+
assert_equal(2, sig_alg.value.size)
185+
assert_equal(OpenSSL::ASN1::ObjectId, pkey.value[0].value[0].class)
186+
assert_equal("1.2.840.113549.1.1.1", pkey.value[0].value[0].oid)
187+
assert_equal(OpenSSL::ASN1::Null, pkey.value[0].value[1].class)
188+
189+
assert_equal(OpenSSL::ASN1::BitString, sig_val.class)
190+
cululated_sig = key.sign(OpenSSL::Digest.new('SHA256'), tbs_cert.to_der)
191+
# TODO: Import Issue
192+
# Fails from import with:
193+
# <"\x9E\x19\xE3oI\xC0\x85n$\xF4\xCE\n" +
194+
# "\x87\xA6\xFCu\x1AQbti\xB1\xE0o\xD5\x18?}\xFAEq\xC8\xEF\x17K\xCA|d\xDEu;%\xFB\xA1\xD4\x14\x04\x837\x90E\xAC.p=\x14\xA7\x8B\xAE\xC4\xBE-\x99\xBAx\xB8\x9B+\x87\x80\e\xA1\x17{\fV\xA0\xCF\xA60b\xDFc\x06\x81\xFB\xD3:\x01\x17\x8F\xC5[\xE0m\xAB,\xD3D\xBE\xA0\xA5\x8C\x1E\xCB\x18!\xBF&\x17\xA6\xCF\x8A\xDD\xF1\xB4\x1C\x89\xD8t\xAEz\x95\xC6\xE4\x9E\xA3\xA4">
195+
# expected but was
196+
# <",\xF4.\x1CH\xD5y\xFE\x05~\xB2\x05\xB7\xCB{2VwdZ\xD7\r^\x87AF\x16\x1A\xC8+U\xA1\xCA'\x1Ca\xCE}\xD2H<g\x9D\b\xB3\rz\x81f\x8Eu\x16+G\x84\xF8\xDB\xDF\xC8YV\xE3Fa\x14\x16\b\x86\xF7\xB7w\xCB9\xA67\x11\x91MJ\n" +
197+
# "\x83M{3\x1D|\xBCK\xF8\xFA\ei\xAC\xFD\xF7q\xE6\xC5\xD8\xDC.$\x99\x94\xE9\xC4rl\xE5D\x82\x17\x03\x81\x96)\e\xE0\xCE\x02\x13y\xBD\xB5\x843V\x8A">
198+
#assert_equal(cululated_sig, sig_val.value)
199+
end
200+
6201
def test_encode_boolean
7-
encode_decode_test(OpenSSL::ASN1::Boolean, [true, false])
202+
encode_decode_test1(OpenSSL::ASN1::Boolean, [true, false])
203+
end
204+
205+
def test_end_of_content
206+
# TODO: Import Issue
207+
# raises OpenSSL::ASN1::ASN1Error: unexpected end-of-contents marker
208+
#encode_decode_test B(%w{ 00 00 }), OpenSSL::ASN1::EndOfContent.new
209+
assert_raise(OpenSSL::ASN1::ASN1Error) {
210+
OpenSSL::ASN1.decode(B(%w{ 00 01 00 }))
211+
}
8212
end
9213

10214
def test_encode_integer
@@ -21,6 +225,13 @@ def test_encode_integer
21225
assert_equal i, OpenSSL::ASN1.decode(ai.to_der).value
22226
end
23227

228+
def test_enumerated
229+
encode_decode_test B(%w{ 0A 01 00 }), OpenSSL::ASN1::Enumerated.new(0)
230+
encode_decode_test B(%w{ 0A 01 48 }), OpenSSL::ASN1::Enumerated.new(72)
231+
encode_decode_test B(%w{ 0A 02 00 80 }), OpenSSL::ASN1::Enumerated.new(128)
232+
encode_decode_test B(%w{ 0A 09 01 00 00 00 00 00 00 00 00 }), OpenSSL::ASN1::Enumerated.new(2 ** 64)
233+
end
234+
24235
def test_encode_nested_sequence_to_der
25236
data_sequence = ::OpenSSL::ASN1::Sequence([::OpenSSL::ASN1::Integer(0)])
26237
asn1 = ::OpenSSL::ASN1::Sequence(data_sequence)
@@ -33,13 +244,79 @@ def test_encode_nested_set_to_der
33244
assert_equal "1\x03\x02\x01\x00", asn1.to_der
34245
end
35246

247+
def test_null
248+
# TODO: Import Issue -- Is this related to the comment below in test_encode_all?
249+
# TypeError: nil value
250+
#encode_decode_test B(%w{ 05 00 }), OpenSSL::ASN1::Null.new(nil)
251+
assert_raise(OpenSSL::ASN1::ASN1Error) {
252+
OpenSSL::ASN1.decode(B(%w{ 05 01 00 }))
253+
}
254+
end
255+
36256
def test_encode_nil
37257
#Primitives raise TypeError, Constructives NoMethodError
38258

39259
assert_raise(TypeError) { OpenSSL::ASN1::Integer.new(nil).to_der }
40260
assert_raise(TypeError) { OpenSSL::ASN1::Boolean.new(nil).to_der }
41261
end
42262

263+
def test_object_identifier
264+
encode_decode_test B(%w{ 06 01 00 }), OpenSSL::ASN1::ObjectId.new("0.0".b)
265+
encode_decode_test B(%w{ 06 01 28 }), OpenSSL::ASN1::ObjectId.new("1.0".b)
266+
encode_decode_test B(%w{ 06 03 88 37 03 }), OpenSSL::ASN1::ObjectId.new("2.999.3".b)
267+
encode_decode_test B(%w{ 06 05 2A 22 83 BB 55 }), OpenSSL::ASN1::ObjectId.new("1.2.34.56789".b)
268+
obj = encode_decode_test B(%w{ 06 09 60 86 48 01 65 03 04 02 01 }), OpenSSL::ASN1::ObjectId.new("sha256")
269+
assert_equal "2.16.840.1.101.3.4.2.1", obj.oid
270+
assert_equal "SHA256", obj.sn
271+
assert_equal "sha256", obj.ln
272+
# TODO: Import Issue
273+
# Fails with: <OpenSSL::ASN1::ASN1Error> expected but was <RuntimeError(<(TypeError) string not an OID>)
274+
#assert_raise(OpenSSL::ASN1::ASN1Error) {
275+
# OpenSSL::ASN1.decode(B(%w{ 06 00 }))
276+
#}
277+
#assert_raise(OpenSSL::ASN1::ASN1Error) {
278+
# OpenSSL::ASN1.decode(B(%w{ 06 01 80 }))
279+
#}
280+
# <OpenSSL::ASN1::ASN1Error> expected but was <TypeError(<string 3.0 not an OID>)
281+
#assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("3.0".b).to_der }
282+
# <OpenSSL::ASN1::ASN1Error> exception was expected but none was thrown.
283+
#assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("0.40".b).to_der }
284+
285+
oid = (0...100).to_a.join(".").b
286+
obj = OpenSSL::ASN1::ObjectId.new(oid)
287+
assert_equal oid, obj.oid
288+
289+
aki = [
290+
OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier"),
291+
OpenSSL::ASN1::ObjectId.new("X509v3 Authority Key Identifier"),
292+
OpenSSL::ASN1::ObjectId.new("2.5.29.35")
293+
]
294+
295+
ski = [
296+
OpenSSL::ASN1::ObjectId.new("subjectKeyIdentifier"),
297+
OpenSSL::ASN1::ObjectId.new("X509v3 Subject Key Identifier"),
298+
OpenSSL::ASN1::ObjectId.new("2.5.29.14")
299+
]
300+
301+
aki.each do |a|
302+
# TODO: Import Issue
303+
# None of these are equivalent to each other
304+
#aki.each do |b|
305+
# assert a == b
306+
#end
307+
308+
ski.each do |b|
309+
refute a == b
310+
end
311+
end
312+
313+
# TODO: Import Issue
314+
# <TypeError> exception was expected but none was thrown.
315+
#assert_raise(TypeError) {
316+
# OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier") == nil
317+
#}
318+
end
319+
43320
def test_instantiate
44321
# nothing shall raise :
45322
OpenSSL::ASN1::Null.new(nil)
@@ -81,6 +358,199 @@ def test_simple_to_der
81358
assert_equal "1\x00", OpenSSL::ASN1::Set.new(nil).to_der
82359
end
83360

361+
def test_sequence
362+
encode_decode_test B(%w{ 30 00 }), OpenSSL::ASN1::Sequence.new([])
363+
# TODO: Import Issue
364+
# TypeError: nil value
365+
#encode_decode_test B(%w{ 30 07 05 00 30 00 04 01 00 }), OpenSSL::ASN1::Sequence.new([
366+
# OpenSSL::ASN1::Null.new(nil),
367+
# OpenSSL::ASN1::Sequence.new([]),
368+
# OpenSSL::ASN1::OctetString.new(B(%w{ 00 }))
369+
#])
370+
371+
expected = OpenSSL::ASN1::Sequence.new([OpenSSL::ASN1::OctetString.new(B(%w{ 00 }))])
372+
expected.indefinite_length = true
373+
encode_decode_test B(%w{ 30 80 04 01 00 00 00 }), expected
374+
375+
# OpenSSL::ASN1::EndOfContent can only be at the end
376+
obj = OpenSSL::ASN1::Sequence.new([
377+
OpenSSL::ASN1::EndOfContent.new,
378+
OpenSSL::ASN1::OctetString.new(B(%w{ 00 })),
379+
OpenSSL::ASN1::EndOfContent.new,
380+
])
381+
obj.indefinite_length = true
382+
# TODO: Import Issue
383+
# <OpenSSL::ASN1::ASN1Error> exception was expected but none was thrown.
384+
#assert_raise(OpenSSL::ASN1::ASN1Error) { obj.to_der }
385+
386+
# The last EOC in value is ignored if indefinite length form is used
387+
expected = OpenSSL::ASN1::Sequence.new([
388+
OpenSSL::ASN1::OctetString.new(B(%w{ 00 })),
389+
OpenSSL::ASN1::EndOfContent.new
390+
])
391+
expected.indefinite_length = true
392+
encode_test B(%w{ 30 80 04 01 00 00 00 }), expected
393+
end
394+
395+
def test_set
396+
encode_decode_test B(%w{ 31 00 }), OpenSSL::ASN1::Set.new([])
397+
# TODO: Import Issue
398+
# <"1\a\x05\x000\x00\x04\x01\x00"> expected but was <"1\a\x04\x01\x00\x05\x000\x00">
399+
#encode_decode_test B(%w{ 31 07 05 00 30 00 04 01 00 }), OpenSSL::ASN1::Set.new([
400+
# OpenSSL::ASN1::Null.new(nil),
401+
# OpenSSL::ASN1::Sequence.new([]),
402+
# OpenSSL::ASN1::OctetString.new(B(%w{ 00 }))
403+
#])
404+
expected = OpenSSL::ASN1::Set.new([OpenSSL::ASN1::OctetString.new(B(%w{ 00 }))])
405+
expected.indefinite_length = true
406+
encode_decode_test B(%w{ 31 80 04 01 00 00 00 }), expected
407+
end
408+
409+
def test_utctime
410+
encode_decode_test B(%w{ 17 0D }) + "160908234339Z".b,
411+
OpenSSL::ASN1::UTCTime.new(Time.utc(2016, 9, 8, 23, 43, 39))
412+
begin
413+
# possible range of UTCTime is 1969-2068 currently
414+
encode_decode_test B(%w{ 17 0D }) + "690908234339Z".b,
415+
OpenSSL::ASN1::UTCTime.new(Time.utc(1969, 9, 8, 23, 43, 39))
416+
rescue OpenSSL::ASN1::ASN1Error
417+
pend "No negative time_t support?"
418+
end
419+
# not implemented
420+
# decode_test B(%w{ 17 11 }) + "500908234339+0930".b,
421+
# OpenSSL::ASN1::UTCTime.new(Time.new(1950, 9, 8, 23, 43, 39, "+09:30"))
422+
# decode_test B(%w{ 17 0F }) + "5009082343-0930".b,
423+
# OpenSSL::ASN1::UTCTime.new(Time.new(1950, 9, 8, 23, 43, 0, "-09:30"))
424+
# assert_raise(OpenSSL::ASN1::ASN1Error) {
425+
# OpenSSL::ASN1.decode(B(%w{ 17 0C }) + "500908234339".b)
426+
# }
427+
# assert_raise(OpenSSL::ASN1::ASN1Error) {
428+
# OpenSSL::ASN1.decode(B(%w{ 17 0D }) + "500908234339Y".b)
429+
# }
430+
end
431+
432+
def test_generalizedtime
433+
encode_decode_test B(%w{ 18 0F }) + "20161208193429Z".b,
434+
OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 29))
435+
encode_decode_test B(%w{ 18 0F }) + "99990908234339Z".b,
436+
OpenSSL::ASN1::GeneralizedTime.new(Time.utc(9999, 9, 8, 23, 43, 39))
437+
# not implemented
438+
# decode_test B(%w{ 18 13 }) + "20161208193439+0930".b,
439+
# OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 39, "+09:30"))
440+
# decode_test B(%w{ 18 11 }) + "201612081934-0930".b,
441+
# OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 0, "-09:30"))
442+
# decode_test B(%w{ 18 11 }) + "201612081934-09".b,
443+
# OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 0, "-09:00"))
444+
# decode_test B(%w{ 18 0D }) + "2016120819.5Z".b,
445+
# OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 30, 0))
446+
# decode_test B(%w{ 18 0D }) + "2016120819,5Z".b,
447+
# OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 30, 0))
448+
# decode_test B(%w{ 18 0F }) + "201612081934.5Z".b,
449+
# OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 30))
450+
# decode_test B(%w{ 18 11 }) + "20161208193439.5Z".b,
451+
# OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 39.5))
452+
# assert_raise(OpenSSL::ASN1::ASN1Error) {
453+
# OpenSSL::ASN1.decode(B(%w{ 18 0D }) + "201612081934Y".b)
454+
# }
455+
end
456+
457+
def test_basic_asn1data
458+
# TODO: Import Issue
459+
# Java::JavaLang::ClassCastException:
460+
# class org.jruby.RubyString cannot be cast to class org.jruby.ext.openssl.ASN1$ASN1Data
461+
# org.jruby.ext.openssl.ASN1$ASN1Data.toASN1TaggedObject(ASN1.java:1408)
462+
# org.jruby.ext.openssl.ASN1$ASN1Data.toASN1(ASN1.java:1383)
463+
# org.jruby.ext.openssl.ASN1$ASN1Data.toDER(ASN1.java:1424)
464+
# org.jruby.ext.openssl.ASN1$ASN1Data.to_der(ASN1.java:1414)
465+
#encode_test B(%w{ 00 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 0, :UNIVERSAL)
466+
#encode_test B(%w{ 01 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :UNIVERSAL)
467+
#encode_decode_test B(%w{ 41 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :APPLICATION)
468+
#encode_decode_test B(%w{ 81 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :CONTEXT_SPECIFIC)
469+
#encode_decode_test B(%w{ C1 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :PRIVATE)
470+
# TODO: Import Issue
471+
# OpenSSL::ASN1::ASN1Error: tag number for :UNIVERSAL too large
472+
# org/jruby/RubyClass.java:942:in `new'
473+
#encode_decode_test B(%w{ 1F 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 32, :UNIVERSAL)
474+
#encode_decode_test B(%w{ 1F C0 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 8224, :UNIVERSAL)
475+
# TODO: Import Issue (same as start of this test)
476+
# Java::JavaLang::ClassCastException:
477+
# class org.jruby.RubyString cannot be cast to class org.jruby.ext.openssl.ASN1$ASN1Data
478+
# org.jruby.ext.openssl.ASN1$ASN1Data.toASN1TaggedObject(ASN1.java:1408)
479+
# org.jruby.ext.openssl.ASN1$ASN1Data.toASN1(ASN1.java:1383)
480+
# org.jruby.ext.openssl.ASN1$ASN1Data.toDER(ASN1.java:1424)
481+
# org.jruby.ext.openssl.ASN1$ASN1Data.to_der(ASN1.java:1414)
482+
#encode_decode_test B(%w{ 41 02 AB CD }), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 1, :APPLICATION)
483+
#encode_decode_test B(%w{ 41 81 80 } + %w{ AB CD } * 64), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD } * 64), 1, :APPLICATION)
484+
#encode_decode_test B(%w{ 41 82 01 00 } + %w{ AB CD } * 128), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD } * 128), 1, :APPLICATION)
485+
#encode_decode_test B(%w{ 61 00 }), OpenSSL::ASN1::ASN1Data.new([], 1, :APPLICATION)
486+
#obj = OpenSSL::ASN1::ASN1Data.new([OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 2, :PRIVATE)], 1, :APPLICATION)
487+
#obj.indefinite_length = true
488+
#encode_decode_test B(%w{ 61 80 C2 02 AB CD 00 00 }), obj
489+
#obj = OpenSSL::ASN1::ASN1Data.new([
490+
# OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 2, :PRIVATE),
491+
# OpenSSL::ASN1::EndOfContent.new
492+
#], 1, :APPLICATION)
493+
#obj.indefinite_length = true
494+
#encode_test B(%w{ 61 80 C2 02 AB CD 00 00 }), obj
495+
#obj = OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 1, :UNIVERSAL)
496+
#obj.indefinite_length = true
497+
# TODO: Import Issue
498+
# <OpenSSL::ASN1::ASN1Error> expected but was <#<Java::JavaLang::ClassCastException: class org.jruby.RubyString cannot be cast to class org.jruby.ext.openssl.ASN1$ASN1Data
499+
#assert_raise(OpenSSL::ASN1::ASN1Error) { obj.to_der }
500+
end
501+
502+
def test_basic_primitive
503+
# TODO: Import Issue
504+
# Java::JavaLang::NullPointerException:
505+
# org.jruby.ext.openssl.ASN1$Primitive.toDER(ASN1.java:1610)
506+
# org.jruby.ext.openssl.ASN1$ASN1Data.to_der(ASN1.java:1414)
507+
# org.jruby.ext.openssl.ASN1$Primitive.to_der(ASN1.java:1522)
508+
#encode_test B(%w{ 00 00 }), OpenSSL::ASN1::Primitive.new(B(%w{}), 0)
509+
# TODO: Import Issue
510+
# <"\x01\x00"> expected but was <"\x01\x01\xFF">
511+
#encode_test B(%w{ 01 00 }), OpenSSL::ASN1::Primitive.new(B(%w{}), 1, nil, :UNIVERSAL)
512+
# <"\x81\x00"> expected but was <"\x01\x01\xFF">
513+
#encode_test B(%w{ 81 00 }), OpenSSL::ASN1::Primitive.new(B(%w{}), 1, nil, :CONTEXT_SPECIFIC)
514+
# <"\x01\x02\xAB\xCD"> expected but was <"\x01\x01\xFF">
515+
#encode_test B(%w{ 01 02 AB CD }), OpenSSL::ASN1::Primitive.new(B(%w{ AB CD }), 1)
516+
# <TypeError> exception was expected but none was thrown.
517+
#assert_raise(TypeError) { OpenSSL::ASN1::Primitive.new([], 1).to_der }
518+
519+
prim = OpenSSL::ASN1::Integer.new(50)
520+
assert_equal false, prim.indefinite_length
521+
assert_not_respond_to prim, :indefinite_length=
522+
end
523+
524+
#
525+
# MRI seems to have some different tests for similar things (constructive
526+
# vs constructed) There may be some duplicated test cases within these but
527+
# for completeness' sake I'm going to include all of MRI's tests below
528+
#
529+
530+
def test_basic_constructed
531+
#octet_string = OpenSSL::ASN1::OctetString.new(B(%w{ AB CD }))
532+
# TODO: Import Issue
533+
# OpenSSL::ASN1::ASN1Error: Constructive shall only be used with indefinite length
534+
#encode_test B(%w{ 20 00 }), OpenSSL::ASN1::Constructive.new([], 0)
535+
#encode_test B(%w{ 21 00 }), OpenSSL::ASN1::Constructive.new([], 1, nil, :UNIVERSAL)
536+
#encode_test B(%w{ A1 00 }), OpenSSL::ASN1::Constructive.new([], 1, nil, :CONTEXT_SPECIFIC)
537+
#encode_test B(%w{ 21 04 04 02 AB CD }), OpenSSL::ASN1::Constructive.new([octet_string], 1)
538+
# Java::JavaLang::UnsupportedOperationException:
539+
# #<OpenSSL::ASN1::Constructive:0x4fc256ec @tag=1, @value=[#<OpenSSL::ASN1::OctetString:0x7fc56d61
540+
# @tag=4, @value="\xAB\xCD", @tag_class=:UNIVERSAL, @tagging=nil, @indefinite_length=false>],
541+
# @tag_class=:CONTEXT_SPECIFIC, @tagging=:EXPLICIT, @indefinite_length=true>
542+
# org.jruby.ext.openssl.ASN1$Constructive.toDER(ASN1.java:1881)
543+
# org.jruby.ext.openssl.ASN1$ASN1Data.to_der(ASN1.java:1414)
544+
# org.jruby.ext.openssl.ASN1$Constructive.to_der(ASN1.java:1858)
545+
#obj = OpenSSL::ASN1::Constructive.new([octet_string], 1)
546+
#obj.indefinite_length = true
547+
#encode_decode_test B(%w{ 21 80 04 02 AB CD 00 00 }), obj
548+
# (see above) Java::JavaLang::UnsupportedOperationException
549+
#obj = OpenSSL::ASN1::Constructive.new([octet_string, OpenSSL::ASN1::EndOfContent.new], 1)
550+
#obj.indefinite_length = true
551+
#encode_test B(%w{ 21 80 04 02 AB CD 00 00 }), obj
552+
end
553+
84554
def test_constructive
85555
oct = OpenSSL::ASN1::OctetString.new("")
86556
assert_equal "\x04\x00", oct.to_der
@@ -113,6 +583,213 @@ def test_constructive
113583
assert_equal "0\x800\x80\x02\x01\x01\x00\x00\x00\x00", outer.to_der
114584
end
115585

586+
def test_prim_explicit_tagging
587+
# TODO: Import Issue
588+
# <"\xA0\x03\x04\x01a"> expected but was <"\x04\x01a">
589+
#oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT)
590+
#encode_test B(%w{ A0 03 04 01 61 }), oct_str
591+
# <"a\x03\x04\x01a"> expected but was <"\x04\x01a">
592+
oct_str2 = OpenSSL::ASN1::OctetString.new("a", 1, :EXPLICIT, :APPLICATION)
593+
#encode_test B(%w{ 61 03 04 01 61 }), oct_str2
594+
595+
decoded = OpenSSL::ASN1.decode(oct_str2.to_der)
596+
# <:APPLICATION> expected but was <:UNIVERSAL>
597+
#assert_equal :APPLICATION, decoded.tag_class
598+
# <1> expected but was <4>
599+
#assert_equal 1, decoded.tag
600+
assert_equal 1, decoded.value.size
601+
#inner = decoded.value[0]
602+
# <OpenSSL::ASN1::OctetString> expected but was <String>
603+
#assert_equal OpenSSL::ASN1::OctetString, inner.class
604+
# NoMethodError: undefined method `value' for "a":String
605+
#assert_equal B(%w{ 61 }), inner.value
606+
end
607+
608+
def test_prim_implicit_tagging
609+
#int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT)
610+
# TODO: Import Issue
611+
# <"\x80\x01\x01"> expected but was <"\x02\x01\x01">
612+
#encode_test B(%w{ 80 01 01 }), int
613+
#int2 = OpenSSL::ASN1::Integer.new(1, 1, :IMPLICIT, :APPLICATION)
614+
# <"A\x01\x01"> expected but was <"\x02\x01\x01">
615+
#encode_test B(%w{ 41 01 01 }), int2
616+
#decoded = OpenSSL::ASN1.decode(int2.to_der)
617+
# <:APPLICATION> expected but was <:UNIVERSAL>
618+
#assert_equal :APPLICATION, decoded.tag_class
619+
# <1> expected but was <2>
620+
#assert_equal 1, decoded.tag
621+
# <"\x01"> expected but was <#<OpenSSL::BN 1>>
622+
#assert_equal B(%w{ 01 }), decoded.value
623+
624+
# Special behavior: Encoding universal types with non-default 'tag'
625+
# attribute and nil tagging method.
626+
#int3 = OpenSSL::ASN1::Integer.new(1, 1)
627+
# <"\x01\x01\x01"> expected but was <"\x02\x01\x01">
628+
#encode_test B(%w{ 01 01 01 }), int3
629+
end
630+
631+
def test_cons_explicit_tagging
632+
#content = [ OpenSSL::ASN1::PrintableString.new('abc') ]
633+
#seq = OpenSSL::ASN1::Sequence.new(content, 2, :EXPLICIT)
634+
# TODO: Import Issue
635+
# RuntimeError: No message available
636+
#encode_test B(%w{ A2 07 30 05 13 03 61 62 63 }), seq
637+
#seq2 = OpenSSL::ASN1::Sequence.new(content, 3, :EXPLICIT, :APPLICATION)
638+
# RuntimeError: No message available
639+
#encode_test B(%w{ 63 07 30 05 13 03 61 62 63 }), seq2
640+
641+
#content3 = [ OpenSSL::ASN1::PrintableString.new('abc'),
642+
# OpenSSL::ASN1::EndOfContent.new() ]
643+
#seq3 = OpenSSL::ASN1::Sequence.new(content3, 2, :EXPLICIT)
644+
#seq3.indefinite_length = true
645+
# RuntimeError: No message available
646+
#encode_test B(%w{ A2 80 30 80 13 03 61 62 63 00 00 00 00 }), seq3
647+
end
648+
649+
def test_cons_implicit_tagging
650+
#content = [ OpenSSL::ASN1::Null.new(nil) ]
651+
#seq = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT)
652+
# TODO: Import Issue
653+
# <"\xA1\x02\x05\x00"> expected but was <"0\x02\x05\x00">
654+
#encode_test B(%w{ A1 02 05 00 }), seq
655+
#seq2 = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT, :APPLICATION)
656+
# <"a\x02\x05\x00"> expected but was <"0\x02\x05\x00">
657+
#encode_test B(%w{ 61 02 05 00 }), seq2
658+
659+
#content3 = [ OpenSSL::ASN1::Null.new(nil),
660+
# OpenSSL::ASN1::EndOfContent.new() ]
661+
#seq3 = OpenSSL::ASN1::Sequence.new(content3, 1, :IMPLICIT)
662+
#seq3.indefinite_length = true
663+
# <"\xA1\x80\x05\x00\x00\x00"> expected but was <"0\x80\x05\x00\x00\x00">
664+
#encode_test B(%w{ A1 80 05 00 00 00 }), seq3
665+
666+
# Special behavior: Encoding universal types with non-default 'tag'
667+
# attribute and nil tagging method.
668+
#seq4 = OpenSSL::ASN1::Sequence.new([], 1)
669+
# <"!\x00"> expected but was <"0\x00">
670+
#encode_test B(%w{ 21 00 }), seq4
671+
end
672+
673+
def test_octet_string_constructed_tagging
674+
#octets = [ OpenSSL::ASN1::OctetString.new('aaa') ]
675+
#cons = OpenSSL::ASN1::Constructive.new(octets, 0, :IMPLICIT)
676+
# TODO: Import Issues
677+
# OpenSSL::ASN1::ASN1Error: Constructive shall only be used with indefinite length
678+
#encode_test B(%w{ A0 05 04 03 61 61 61 }), cons
679+
680+
#octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
681+
# OpenSSL::ASN1::EndOfContent.new() ]
682+
#cons = OpenSSL::ASN1::Constructive.new(octets, 0, :IMPLICIT)
683+
#cons.indefinite_length = true
684+
# Java::JavaLang::UnsupportedOperationException:
685+
# #<OpenSSL::ASN1::Constructive:0x4a86be01 @tag=0,
686+
# @value=[#<OpenSSL::ASN1::OctetString:0x53b907d9 @tag=4, @value="aaa",
687+
# @tag_class=:UNIVERSAL, @tagging=nil, @indefinite_length=false>,
688+
# #<OpenSSL::ASN1::EndOfContent:0x2c3b0cc8 @tag=0, @value="",
689+
# @tag_class=:UNIVERSAL>], @tag_class=:CONTEXT_SPECIFIC, @tagging=:IMPLICIT, @indefinite_length=true>
690+
#encode_test B(%w{ A0 80 04 03 61 61 61 00 00 }), cons
691+
end
692+
693+
def test_recursive_octet_string_indefinite_length
694+
#octets_sub1 = [ OpenSSL::ASN1::OctetString.new("\x01"),
695+
# OpenSSL::ASN1::EndOfContent.new() ]
696+
#octets_sub2 = [ OpenSSL::ASN1::OctetString.new("\x02"),
697+
# OpenSSL::ASN1::EndOfContent.new() ]
698+
#container1 = OpenSSL::ASN1::Constructive.new(octets_sub1, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
699+
#container1.indefinite_length = true
700+
#container2 = OpenSSL::ASN1::Constructive.new(octets_sub2, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
701+
#container2.indefinite_length = true
702+
#octets3 = OpenSSL::ASN1::OctetString.new("\x03")
703+
704+
#octets = [ container1, container2, octets3,
705+
# OpenSSL::ASN1::EndOfContent.new() ]
706+
#cons = OpenSSL::ASN1::Constructive.new(octets, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
707+
#cons.indefinite_length = true
708+
#raw = B(%w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 })
709+
# TODO: Implict Issue
710+
# Java::JavaLang::UnsupportedOperationException
711+
# org.jruby.ext.openssl.ASN1$Constructive$InternalEncodable.toASN1Primitive(ASN1.java:1961)
712+
# org.jruby.ext.openssl.ASN1$Constructive.octetStringToDER(ASN1.java:1904)
713+
# org.jruby.ext.openssl.ASN1$Constructive.toDER(ASN1.java:1873)
714+
# org.jruby.ext.openssl.ASN1$ASN1Data.to_der(ASN1.java:1414)
715+
#assert_equal(raw, cons.to_der)
716+
# <"$\x80$\x80\x04\x01\x01\x00\x00$\x80\x04\x01\x02\x00\x00\x04\x01\x03\x00\x00"> expected but was <"$\x80\x04\x03\x01\x02\x03\x00\x00">
717+
#assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
718+
end
719+
720+
def test_recursive_octet_string_parse
721+
raw = B(%w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 })
722+
asn1 = OpenSSL::ASN1.decode(raw)
723+
assert_equal(OpenSSL::ASN1::Constructive, asn1.class)
724+
# TODO: Import Issue
725+
# <false> expected but was <true>
726+
#assert_universal(OpenSSL::ASN1::OCTET_STRING, asn1)
727+
assert_equal(true, asn1.indefinite_length)
728+
# <3> expected but was <2>
729+
#assert_equal(3, asn1.value.size)
730+
nested1 = asn1.value[0]
731+
# <OpenSSL::ASN1::Constructive> expected but was <OpenSSL::ASN1::OctetString>
732+
#assert_equal(OpenSSL::ASN1::Constructive, nested1.class)
733+
assert_universal(OpenSSL::ASN1::OCTET_STRING, nested1)
734+
# <true> expected but was <false>
735+
#assert_equal(true, nested1.indefinite_length)
736+
# <1> expected but was <3>
737+
#assert_equal(1, nested1.value.size)
738+
#oct1 = nested1.value[0]
739+
# NoMethodError: undefined method `tag' for "\x01":String
740+
# Did you mean? tap
741+
# src/test/ruby/test_asn1.rb:1286:in `assert_universal'
742+
#assert_universal(OpenSSL::ASN1::OCTET_STRING, oct1)
743+
# NoMethodError: undefined method `indefinite_length' for "\x01":String
744+
#assert_equal(false, oct1.indefinite_length)
745+
#nested2 = asn1.value[1]
746+
# <OpenSSL::ASN1::Constructive> expected but was <OpenSSL::ASN1::EndOfContent>
747+
#assert_equal(OpenSSL::ASN1::Constructive, nested2.class)
748+
# <4> expected but was <0>
749+
#assert_universal(OpenSSL::ASN1::OCTET_STRING, nested2)
750+
# <true> expected but was <nil>
751+
#assert_equal(true, nested2.indefinite_length)
752+
# <1> expected but was <0>
753+
#assert_equal(1, nested2.value.size)
754+
#oct2 = nested2.value[0]
755+
# NoMethodError: undefined method `tag' for nil:NilClass
756+
#assert_universal(OpenSSL::ASN1::OCTET_STRING, oct2)
757+
# NoMethodError: undefined method `indefinite_length' for nil:NilClass
758+
#assert_equal(false, oct2.indefinite_length)
759+
#oct3 = asn1.value[2]
760+
# NoMethodError: undefined method `tag' for nil:NilClass
761+
#assert_universal(OpenSSL::ASN1::OCTET_STRING, oct3)
762+
# NoMethodError: undefined method `indefinite_length' for nil:NilClass
763+
#assert_equal(false, oct3.indefinite_length)
764+
end
765+
766+
def test_decode_constructed_overread
767+
#test = %w{ 31 06 31 02 30 02 05 00 }
768+
## ^ <- invalid
769+
#raw = [test.join].pack("H*")
770+
#ret = []
771+
# <OpenSSL::ASN1::ASN1Error> exception was expected but none was thrown.
772+
#assert_raise(OpenSSL::ASN1::ASN1Error) {
773+
# OpenSSL::ASN1.traverse(raw) { |x| ret << x }
774+
#}
775+
# <2> expected but was <0>
776+
#assert_equal 2, ret.size
777+
# NoMethodError: undefined method `[]' for nil:NilClass
778+
#assert_equal 17, ret[0][6]
779+
#assert_equal 17, ret[1][6]
780+
781+
#test = %w{ 31 80 30 03 00 00 }
782+
## ^ <- invalid
783+
#raw = [test.join].pack("H*")
784+
#ret = []
785+
# <OpenSSL::ASN1::ASN1Error> exception was expected but none was thrown.
786+
#assert_raise(OpenSSL::ASN1::ASN1Error) {
787+
# OpenSSL::ASN1.traverse(raw) { |x| ret << x }
788+
#}
789+
#assert_equal 1, ret.size
790+
#assert_equal 17, ret[0][6]
791+
end
792+
116793
def test_constructive_nesting
117794
seq = OpenSSL::ASN1::Sequence.new([
118795
OpenSSL::ASN1::ObjectId.new('DC'),
@@ -472,6 +1149,33 @@ def test_decode
4721149
#assert_equal calulated_sig, sig_val.value
4731150
end
4741151

1152+
# This is from the upstream MRI tests, might be superseded by `test_bit_string_infinite_length`?
1153+
def test_bitstring
1154+
# TODO: Import Issue
1155+
# fails <nil> expected but was <0>
1156+
#encode_decode_test B(%w{ 03 01 00 }), OpenSSL::ASN1::BitString.new(B(%w{}))
1157+
# TODO: Import Issue
1158+
# fails with <nil> expected but was <0>
1159+
#encode_decode_test B(%w{ 03 02 00 01 }), OpenSSL::ASN1::BitString.new(B(%w{ 01 }))
1160+
obj = OpenSSL::ASN1::BitString.new(B(%w{ F0 }))
1161+
obj.unused_bits = 4
1162+
encode_decode_test B(%w{ 03 02 04 F0 }), obj
1163+
assert_raise(OpenSSL::ASN1::ASN1Error) {
1164+
OpenSSL::ASN1.decode(B(%w{ 03 00 }))
1165+
}
1166+
assert_raise(OpenSSL::ASN1::ASN1Error) {
1167+
OpenSSL::ASN1.decode(B(%w{ 03 03 08 FF 00 }))
1168+
}
1169+
1170+
# TODO: Import Issue
1171+
# exception was expected but none was thrown.
1172+
#assert_raise(OpenSSL::ASN1::ASN1Error) {
1173+
# obj = OpenSSL::ASN1::BitString.new(B(%w{ FF FF }))
1174+
# obj.unused_bits = 8
1175+
# obj.to_der
1176+
#}
1177+
end
1178+
4751179
def test_bit_string_infinite_length
4761180
begin
4771181
content = [ OpenSSL::ASN1::BitString.new("\x01"), OpenSSL::ASN1::EndOfContent.new() ]
@@ -480,11 +1184,52 @@ def test_bit_string_infinite_length
4801184
expected = %w{ 23 80 03 02 00 01 00 00 }
4811185
raw = [expected.join('')].pack('H*')
4821186
assert_equal raw, cons.to_der
483-
# TODO for now we can no decode our own sh*t :
1187+
# TODO for now we can not decode our own sh*t :
4841188
#assert_equal raw, OpenSSL::ASN1.decode(raw).to_der
4851189
end
4861190
end
4871191

1192+
def test_string_basic
1193+
test = -> (tag, klass) {
1194+
encode_decode_test tag.chr + B(%w{ 00 }), klass.new(B(%w{}))
1195+
encode_decode_test tag.chr + B(%w{ 02 00 01 }), klass.new(B(%w{ 00 01 }))
1196+
}
1197+
test.(4, OpenSSL::ASN1::OctetString)
1198+
test.(12, OpenSSL::ASN1::UTF8String)
1199+
# TODO: Import Issue
1200+
# The below tests cause NPEs in the first call to `encode_test` above
1201+
# org.jruby.ext.openssl.ASN1$Primitive.toDER(ASN1.java:1610)
1202+
# org.jruby.ext.openssl.ASN1$ASN1Data.to_der(ASN1.java:1414)
1203+
# org.jruby.ext.openssl.ASN1$Primitive.to_der(ASN1.java:1522)
1204+
# org.jruby.ext.openssl.ASN1$Primitive$INVOKER$i$0$0$to_der.call(ASN1$Primitive$INVOKER$i$0$0$to_der.gen)
1205+
#test.(18, OpenSSL::ASN1::NumericString)
1206+
#test.(19, OpenSSL::ASN1::PrintableString)
1207+
#test.(20, OpenSSL::ASN1::T61String)
1208+
#test.(21, OpenSSL::ASN1::VideotexString)
1209+
test.(22, OpenSSL::ASN1::IA5String)
1210+
# See above
1211+
#test.(25, OpenSSL::ASN1::GraphicString)
1212+
#test.(26, OpenSSL::ASN1::ISO64String)
1213+
#test.(27, OpenSSL::ASN1::GeneralString)
1214+
1215+
# TODO: Import Issue
1216+
# This fails with:
1217+
# <""> expected but was <"#1C00">
1218+
#test.(28, OpenSSL::ASN1::UniversalString)
1219+
1220+
# TODO: Import Issue
1221+
# This fails with:
1222+
# <"\x1E\x02\x00\x01">(US-ASCII) expected but was <"\x1E\x04\x00\x00\x00\x01">(ASCII-8BIT)
1223+
#test.(30, OpenSSL::ASN1::BMPString)
1224+
end
1225+
1226+
def test_constructive_each
1227+
data = [OpenSSL::ASN1::Integer.new(0), OpenSSL::ASN1::Integer.new(1)]
1228+
seq = OpenSSL::ASN1::Sequence.new data
1229+
1230+
assert_equal data, seq.entries
1231+
end
1232+
4881233
def test_decode_all
4891234
expected = %w{ 02 01 01 02 01 02 02 01 03 }
4901235
raw = [expected.join('')].pack('H*')
@@ -543,13 +1288,53 @@ def test_encode_der_integer_wrapped
5431288

5441289
private
5451290

1291+
def B(ary)
1292+
[ary.join].pack("H*")
1293+
end
1294+
1295+
def assert_asn1_equal(a, b)
1296+
assert_equal a.class, b.class
1297+
assert_equal a.tag, b.tag
1298+
assert_equal a.tag_class, b.tag_class
1299+
assert_equal a.indefinite_length, b.indefinite_length
1300+
assert_equal a.unused_bits, b.unused_bits if a.respond_to?(:unused_bits)
1301+
case a.value
1302+
when Array
1303+
a.value.each_with_index { |ai, i|
1304+
assert_asn1_equal ai, b.value[i]
1305+
}
1306+
else
1307+
if OpenSSL::ASN1::ObjectId === a
1308+
assert_equal a.oid, b.oid
1309+
else
1310+
assert_equal a.value, b.value
1311+
end
1312+
end
1313+
assert_equal a.to_der, b.to_der
1314+
end
1315+
1316+
def encode_test(der, obj)
1317+
assert_equal der, obj.to_der
1318+
end
1319+
1320+
def decode_test(der, obj)
1321+
decoded = OpenSSL::ASN1.decode(der)
1322+
assert_asn1_equal obj, decoded
1323+
decoded
1324+
end
1325+
1326+
def encode_decode_test(der, obj)
1327+
encode_test(der, obj)
1328+
decode_test(der, obj)
1329+
end
1330+
5461331
def assert_universal(tag, asn1, inf_len=false)
5471332
assert_equal(tag, asn1.tag)
5481333
assert_equal(:UNIVERSAL, asn1.tag_class)
5491334
assert_equal(inf_len, asn1.infinite_length)
5501335
end
5511336

552-
def encode_decode_test(type, values)
1337+
def encode_decode_test1(type, values)
5531338
values.each do |v|
5541339
assert_equal(v, OpenSSL::ASN1.decode(type.new(v).to_der).value)
5551340
end

0 commit comments

Comments
 (0)
Please sign in to comment.