JRuby-OpenSSL 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,34 @@
1
+ warn "Warning: OpenSSL ASN1/PKey/X509/Netscape/PKCS7 implementation unavailable"
2
+ warn "You need to download or install BouncyCastle jars (bc-prov-*.jar, bc-mail-*.jar)"
3
+ warn "to fix this."
4
+ module OpenSSL
5
+ module ASN1
6
+ class ASN1Error < OpenSSLError; end
7
+ class ASN1Data; end
8
+ class Primitive; end
9
+ class Constructive; end
10
+ end
11
+ module PKey
12
+ class PKeyError < OpenSSLError; end
13
+ class PKey; def initialize(*args); end; end
14
+ class RSA < PKey; end
15
+ class DSA < PKey; end
16
+ class DH < PKey; end
17
+ end
18
+ module X509
19
+ class Name; end
20
+ class Certificate; end
21
+ class Extension; end
22
+ class CRL; end
23
+ class Revoked; end
24
+ class Store; end
25
+ class Request; end
26
+ class Attribute; end
27
+ end
28
+ module Netscape
29
+ class SPKI; end
30
+ end
31
+ module PKCS7
32
+ class PKCS7; end
33
+ end
34
+ end
@@ -0,0 +1,13 @@
1
+ warn "Warning: OpenSSL SSL implementation unavailable"
2
+ warn "You must run on JDK 1.5 (Java 5) or higher to use SSL"
3
+ module OpenSSL
4
+ module SSL
5
+ class SSLError < OpenSSLError; end
6
+ class SSLContext; end
7
+ class SSLSocket; end
8
+ VERIFY_NONE = 0
9
+ VERIFY_PEER = 1
10
+ VERIFY_FAIL_IF_NO_PEER_CERT = 2
11
+ VERIFY_CLIENT_ONCE = 4
12
+ end
13
+ end
@@ -0,0 +1,135 @@
1
+ =begin
2
+ = $RCSfile: ssl.rb,v $ -- Ruby-space definitions that completes C-space funcs for SSL
3
+
4
+ = Info
5
+ 'OpenSSL for Ruby 2' project
6
+ Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
7
+ All rights reserved.
8
+
9
+ = Licence
10
+ This program is licenced under the same licence as Ruby.
11
+ (See the file 'LICENCE'.)
12
+
13
+ = Version
14
+ $Id: ssl.rb,v 1.5.2.6 2006/05/23 18:14:05 gotoyuzo Exp $
15
+ =end
16
+
17
+ require "openssl"
18
+ require "openssl/buffering"
19
+ require "fcntl"
20
+
21
+ module OpenSSL
22
+ module SSL
23
+ module SocketForwarder
24
+ def addr
25
+ to_io.addr
26
+ end
27
+
28
+ def peeraddr
29
+ to_io.peeraddr
30
+ end
31
+
32
+ def setsockopt(level, optname, optval)
33
+ to_io.setsockopt(level, optname, optval)
34
+ end
35
+
36
+ def getsockopt(level, optname)
37
+ to_io.getsockopt(level, optname)
38
+ end
39
+
40
+ def fcntl(*args)
41
+ to_io.fcntl(*args)
42
+ end
43
+
44
+ def closed?
45
+ to_io.closed?
46
+ end
47
+
48
+ def do_not_reverse_lookup=(flag)
49
+ to_io.do_not_reverse_lookup = flag
50
+ end
51
+ end
52
+
53
+ module Nonblock
54
+ def initialize(*args)
55
+ flag = File::NONBLOCK
56
+ flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)
57
+ @io.fcntl(Fcntl::F_SETFL, flag)
58
+ super
59
+ end
60
+ end
61
+
62
+ class SSLSocket
63
+ include Buffering
64
+ include SocketForwarder
65
+ include Nonblock
66
+
67
+ def post_connection_check(hostname)
68
+ check_common_name = true
69
+ cert = peer_cert
70
+ cert.extensions.each{|ext|
71
+ next if ext.oid != "subjectAltName"
72
+ ext.value.split(/,\s+/).each{|general_name|
73
+ if /\ADNS:(.*)/ =~ general_name
74
+ check_common_name = false
75
+ reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+")
76
+ return true if /\A#{reg}\z/i =~ hostname
77
+ elsif /\AIP Address:(.*)/ =~ general_name
78
+ check_common_name = false
79
+ return true if $1 == hostname
80
+ end
81
+ }
82
+ }
83
+ if check_common_name
84
+ cert.subject.to_a.each{|oid, value|
85
+ if oid == "CN"
86
+ reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
87
+ return true if /\A#{reg}\z/i =~ hostname
88
+ end
89
+ }
90
+ end
91
+ raise SSLError, "hostname not match"
92
+ end
93
+ end
94
+
95
+ class SSLServer
96
+ include SocketForwarder
97
+ attr_accessor :start_immediately
98
+
99
+ def initialize(svr, ctx)
100
+ @svr = svr
101
+ @ctx = ctx
102
+ unless ctx.session_id_context
103
+ session_id = OpenSSL::Digest::MD5.hexdigest($0)
104
+ @ctx.session_id_context = session_id
105
+ end
106
+ @start_immediately = true
107
+ end
108
+
109
+ def to_io
110
+ @svr
111
+ end
112
+
113
+ def listen(backlog=5)
114
+ @svr.listen(backlog)
115
+ end
116
+
117
+ def accept
118
+ sock = @svr.accept
119
+ begin
120
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
121
+ ssl.sync_close = true
122
+ ssl.accept if @start_immediately
123
+ ssl
124
+ rescue SSLError => ex
125
+ sock.close
126
+ raise ex
127
+ end
128
+ end
129
+
130
+ def close
131
+ @svr.close
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,154 @@
1
+ =begin
2
+ = $RCSfile: x509.rb,v $ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses
3
+
4
+ = Info
5
+ 'OpenSSL for Ruby 2' project
6
+ Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz>
7
+ All rights reserved.
8
+
9
+ = Licence
10
+ This program is licenced under the same licence as Ruby.
11
+ (See the file 'LICENCE'.)
12
+
13
+ = Version
14
+ $Id: x509.rb,v 1.4.2.2 2004/12/19 08:28:33 gotoyuzo Exp $
15
+ =end
16
+
17
+ require "openssl"
18
+
19
+ module OpenSSL
20
+ module X509
21
+ class ExtensionFactory
22
+ def create_extension(*arg)
23
+ if arg.size > 1
24
+ create_ext(*arg)
25
+ else
26
+ send("create_ext_from_"+arg[0].class.name.downcase, arg[0])
27
+ end
28
+ end
29
+
30
+ def create_ext_from_array(ary)
31
+ raise ExtensionError, "unexpected array form" if ary.size > 3
32
+ create_ext(ary[0], ary[1], ary[2])
33
+ end
34
+
35
+ def create_ext_from_string(str) # "oid = critical, value"
36
+ oid, value = str.split(/=/, 2)
37
+ oid.strip!
38
+ value.strip!
39
+ create_ext(oid, value)
40
+ end
41
+
42
+ def create_ext_from_hash(hash)
43
+ create_ext(hash["oid"], hash["value"], hash["critical"])
44
+ end
45
+ end
46
+
47
+ class Extension
48
+ def to_s # "oid = critical, value"
49
+ str = self.oid
50
+ str << " = "
51
+ str << "critical, " if self.critical?
52
+ str << self.value.gsub(/\n/, ", ")
53
+ end
54
+
55
+ def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false}
56
+ {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?}
57
+ end
58
+
59
+ def to_a
60
+ [ self.oid, self.value, self.critical? ]
61
+ end
62
+ end
63
+
64
+ class Name
65
+ module RFC2253DN
66
+ Special = ',=+<>#;'
67
+ HexChar = /[0-9a-fA-F]/
68
+ HexPair = /#{HexChar}#{HexChar}/
69
+ HexString = /#{HexPair}+/
70
+ Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/
71
+ StringChar = /[^#{Special}\\"]/
72
+ QuoteChar = /[^\\"]/
73
+ AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/
74
+ AttributeValue = /
75
+ (?!["#])((?:#{StringChar}|#{Pair})*)|
76
+ \#(#{HexString})|
77
+ "((?:#{QuoteChar}|#{Pair})*)"
78
+ /x
79
+ TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/
80
+
81
+ module_function
82
+
83
+ def expand_pair(str)
84
+ return nil unless str
85
+ return str.gsub(Pair){|pair|
86
+ case pair.size
87
+ when 2 then pair[1,1]
88
+ when 3 then Integer("0x#{pair[1,2]}").chr
89
+ else raise OpenSSL::X509::NameError, "invalid pair: #{str}"
90
+ end
91
+ }
92
+ end
93
+
94
+ def expand_hexstring(str)
95
+ return nil unless str
96
+ der = str.gsub(HexPair){|hex| Integer("0x#{hex}").chr }
97
+ a1 = OpenSSL::ASN1.decode(der)
98
+ return a1.value, a1.tag
99
+ end
100
+
101
+ def expand_value(str1, str2, str3)
102
+ value = expand_pair(str1)
103
+ value, tag = expand_hexstring(str2) unless value
104
+ value = expand_pair(str3) unless value
105
+ return value, tag
106
+ end
107
+
108
+ def scan(dn)
109
+ str = dn
110
+ ary = []
111
+ while true
112
+ if md = TypeAndValue.match(str)
113
+ matched = md.to_s
114
+ remain = md.post_match
115
+ type = md[1]
116
+ value, tag = expand_value(md[2], md[3], md[4]) rescue nil
117
+ if value
118
+ type_and_value = [type, value]
119
+ type_and_value.push(tag) if tag
120
+ ary.unshift(type_and_value)
121
+ if remain.length > 2 && remain[0] == ?,
122
+ str = remain[1..-1]
123
+ next
124
+ elsif remain.length > 2 && remain[0] == ?+
125
+ raise OpenSSL::X509::NameError,
126
+ "multi-valued RDN is not supported: #{dn}"
127
+ elsif remain.empty?
128
+ break
129
+ end
130
+ end
131
+ end
132
+ msg_dn = dn[0, dn.length - str.length] + " =>" + str
133
+ raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}"
134
+ end
135
+ return ary
136
+ end
137
+ end
138
+
139
+ class <<self
140
+ def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
141
+ ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
142
+ self.new(ary, template)
143
+ end
144
+
145
+ def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
146
+ ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
147
+ self.new(ary, template)
148
+ end
149
+
150
+ alias parse parse_openssl
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,81 @@
1
+ require "socket"
2
+ require "thread"
3
+ require "openssl"
4
+ require File.join(File.dirname(__FILE__), "utils.rb")
5
+
6
+ def get_pem(io=$stdin)
7
+ buf = ""
8
+ while line = io.gets
9
+ if /^-----BEGIN / =~ line
10
+ buf << line
11
+ break
12
+ end
13
+ end
14
+ while line = io.gets
15
+ buf << line
16
+ if /^-----END / =~ line
17
+ break
18
+ end
19
+ end
20
+ return buf
21
+ end
22
+
23
+ def make_key(pem)
24
+ begin
25
+ return OpenSSL::PKey::RSA.new(pem)
26
+ rescue
27
+ return OpenSSL::PKey::DSA.new(pem)
28
+ end
29
+ end
30
+
31
+ ca_cert = OpenSSL::X509::Certificate.new(get_pem)
32
+ ssl_cert = OpenSSL::X509::Certificate.new(get_pem)
33
+ ssl_key = make_key(get_pem)
34
+ port = Integer(ARGV.shift)
35
+ verify_mode = Integer(ARGV.shift)
36
+ start_immediately = (/yes/ =~ ARGV.shift)
37
+
38
+ store = OpenSSL::X509::Store.new
39
+ store.add_cert(ca_cert)
40
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
41
+ ctx = OpenSSL::SSL::SSLContext.new
42
+ ctx.cert_store = store
43
+ #ctx.extra_chain_cert = [ ca_cert ]
44
+ ctx.cert = ssl_cert
45
+ ctx.key = ssl_key
46
+ ctx.verify_mode = verify_mode
47
+
48
+ Socket.do_not_reverse_lookup = true
49
+ tcps = nil
50
+ 100.times{|i|
51
+ begin
52
+ tcps = TCPServer.new("0.0.0.0", port+i)
53
+ port = port + i
54
+ break
55
+ rescue Errno::EADDRINUSE
56
+ next
57
+ end
58
+ }
59
+ ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
60
+ ssls.start_immediately = start_immediately
61
+
62
+ $stdout.sync = true
63
+ $stdout.puts Process.pid
64
+ $stdout.puts port
65
+
66
+ loop do
67
+ ssl = ssls.accept rescue next
68
+ Thread.start{
69
+ q = Queue.new
70
+ th = Thread.start{ ssl.write(q.shift) while true }
71
+ while line = ssl.gets
72
+ if line =~ /^STARTTLS$/
73
+ ssl.accept
74
+ next
75
+ end
76
+ q.push(line)
77
+ end
78
+ th.kill if q.empty?
79
+ ssl.close
80
+ }
81
+ end
@@ -0,0 +1,199 @@
1
+ begin
2
+ require "openssl"
3
+ require File.join(File.dirname(__FILE__), "utils.rb")
4
+ rescue LoadError
5
+ end
6
+ require 'test/unit'
7
+
8
+ class OpenSSL::TestASN1 < Test::Unit::TestCase
9
+ def test_decode
10
+ subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA")
11
+ key = OpenSSL::TestUtils::TEST_KEY_RSA1024
12
+ now = Time.at(Time.now.to_i) # suppress usec
13
+ # now = Time.utc(2006,04,03,22,15,13)
14
+ s = 0xdeadbeafdeadbeafdeadbeafdeadbeaf
15
+ exts = [
16
+ ["basicConstraints","CA:TRUE,pathlen:1",true],
17
+ ["keyUsage","keyCertSign, cRLSign",true],
18
+ ["subjectKeyIdentifier","hash",false],
19
+ ]
20
+ dgst = OpenSSL::Digest::SHA1.new
21
+ cert = OpenSSL::TestUtils.issue_cert(
22
+ subj, key, s, now, now+3600, exts, nil, nil, dgst)
23
+
24
+ asn1 = OpenSSL::ASN1.decode(cert)
25
+ assert_equal(OpenSSL::ASN1::Sequence, asn1.class)
26
+ assert_equal(3, asn1.value.size)
27
+ tbs_cert, sig_alg, sig_val = *asn1.value
28
+
29
+ assert_equal(OpenSSL::ASN1::Sequence, tbs_cert.class)
30
+ assert_equal(8, tbs_cert.value.size)
31
+
32
+ version = tbs_cert.value[0]
33
+ assert_equal(:CONTEXT_SPECIFIC, version.tag_class)
34
+ assert_equal(0, version.tag)
35
+
36
+ assert_equal(1, version.value.size)
37
+ assert_equal(OpenSSL::ASN1::Integer, version.value[0].class)
38
+ assert_equal(2, version.value[0].value)
39
+
40
+ serial = tbs_cert.value[1]
41
+ assert_equal(OpenSSL::ASN1::Integer, serial.class)
42
+ assert_equal(0xdeadbeafdeadbeafdeadbeafdeadbeaf, serial.value)
43
+
44
+ sig = tbs_cert.value[2]
45
+ assert_equal(OpenSSL::ASN1::Sequence, sig.class)
46
+ assert_equal(2, sig.value.size)
47
+ assert_equal(OpenSSL::ASN1::ObjectId, sig.value[0].class)
48
+ assert_equal("1.2.840.113549.1.1.5", sig.value[0].oid)
49
+ assert_equal(OpenSSL::ASN1::Null, sig.value[1].class)
50
+
51
+ dn = tbs_cert.value[3] # issuer
52
+ assert_equal(subj.hash, OpenSSL::X509::Name.new(dn).hash)
53
+ assert_equal(OpenSSL::ASN1::Sequence, dn.class)
54
+ assert_equal(3, dn.value.size)
55
+ assert_equal(OpenSSL::ASN1::Set, dn.value[0].class)
56
+ assert_equal(OpenSSL::ASN1::Set, dn.value[1].class)
57
+ assert_equal(OpenSSL::ASN1::Set, dn.value[2].class)
58
+ assert_equal(1, dn.value[0].value.size)
59
+ assert_equal(1, dn.value[1].value.size)
60
+ assert_equal(1, dn.value[2].value.size)
61
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[0].value[0].class)
62
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[1].value[0].class)
63
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[2].value[0].class)
64
+ assert_equal(2, dn.value[0].value[0].value.size)
65
+ assert_equal(2, dn.value[1].value[0].value.size)
66
+ assert_equal(2, dn.value[2].value[0].value.size)
67
+ oid, value = *dn.value[0].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("org", value.value)
72
+ oid, value = *dn.value[1].value[0].value
73
+ assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
74
+ assert_equal("0.9.2342.19200300.100.1.25", oid.oid)
75
+ assert_equal(OpenSSL::ASN1::IA5String, value.class)
76
+ assert_equal("ruby-lang", value.value)
77
+ oid, value = *dn.value[2].value[0].value
78
+ assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
79
+ assert_equal("2.5.4.3", oid.oid)
80
+ assert_equal(OpenSSL::ASN1::UTF8String, value.class)
81
+ assert_equal("TestCA", value.value)
82
+
83
+ validity = tbs_cert.value[4]
84
+ assert_equal(OpenSSL::ASN1::Sequence, validity.class)
85
+ assert_equal(2, validity.value.size)
86
+ assert_equal(OpenSSL::ASN1::UTCTime, validity.value[0].class)
87
+ assert_equal(now, validity.value[0].value)
88
+ assert_equal(OpenSSL::ASN1::UTCTime, validity.value[1].class)
89
+ assert_equal(now+3600, validity.value[1].value)
90
+
91
+ dn = tbs_cert.value[5] # subject
92
+ assert_equal(subj.hash, OpenSSL::X509::Name.new(dn).hash)
93
+ assert_equal(OpenSSL::ASN1::Sequence, dn.class)
94
+ assert_equal(3, dn.value.size)
95
+ assert_equal(OpenSSL::ASN1::Set, dn.value[0].class)
96
+ assert_equal(OpenSSL::ASN1::Set, dn.value[1].class)
97
+ assert_equal(OpenSSL::ASN1::Set, dn.value[2].class)
98
+ assert_equal(1, dn.value[0].value.size)
99
+ assert_equal(1, dn.value[1].value.size)
100
+ assert_equal(1, dn.value[2].value.size)
101
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[0].value[0].class)
102
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[1].value[0].class)
103
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[2].value[0].class)
104
+ assert_equal(2, dn.value[0].value[0].value.size)
105
+ assert_equal(2, dn.value[1].value[0].value.size)
106
+ assert_equal(2, dn.value[2].value[0].value.size)
107
+ oid, value = *dn.value[0].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("org", value.value)
112
+ oid, value = *dn.value[1].value[0].value
113
+ assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
114
+ assert_equal("0.9.2342.19200300.100.1.25", oid.oid)
115
+ assert_equal(OpenSSL::ASN1::IA5String, value.class)
116
+ assert_equal("ruby-lang", value.value)
117
+ oid, value = *dn.value[2].value[0].value
118
+ assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
119
+ assert_equal("2.5.4.3", oid.oid)
120
+ assert_equal(OpenSSL::ASN1::UTF8String, value.class)
121
+ assert_equal("TestCA", value.value)
122
+
123
+ pkey = tbs_cert.value[6]
124
+ assert_equal(OpenSSL::ASN1::Sequence, pkey.class)
125
+ assert_equal(2, pkey.value.size)
126
+ assert_equal(OpenSSL::ASN1::Sequence, pkey.value[0].class)
127
+ assert_equal(2, pkey.value[0].value.size)
128
+ assert_equal(OpenSSL::ASN1::ObjectId, pkey.value[0].value[0].class)
129
+ assert_equal("1.2.840.113549.1.1.1", pkey.value[0].value[0].oid)
130
+ assert_equal(OpenSSL::ASN1::BitString, pkey.value[1].class)
131
+ assert_equal(0, pkey.value[1].unused_bits)
132
+ spkey = OpenSSL::ASN1.decode(pkey.value[1].value)
133
+ assert_equal(OpenSSL::ASN1::Sequence, spkey.class)
134
+ assert_equal(2, spkey.value.size)
135
+ assert_equal(OpenSSL::ASN1::Integer, spkey.value[0].class)
136
+ assert_equal(143085709396403084580358323862163416700436550432664688288860593156058579474547937626086626045206357324274536445865308750491138538454154232826011964045825759324933943290377903384882276841880081931690695505836279972214003660451338124170055999155993192881685495391496854691199517389593073052473319331505702779271, spkey.value[0].value)
137
+ assert_equal(OpenSSL::ASN1::Integer, spkey.value[1].class)
138
+ assert_equal(65537, spkey.value[1].value)
139
+
140
+ extensions = tbs_cert.value[7]
141
+ assert_equal(:CONTEXT_SPECIFIC, extensions.tag_class)
142
+ assert_equal(3, extensions.tag)
143
+ assert_equal(1, extensions.value.size)
144
+ assert_equal(OpenSSL::ASN1::Sequence, extensions.value[0].class)
145
+ assert_equal(3, extensions.value[0].value.size)
146
+
147
+ ext = extensions.value[0].value[0] # basicConstraints
148
+ assert_equal(OpenSSL::ASN1::Sequence, ext.class)
149
+ assert_equal(3, ext.value.size)
150
+ assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)
151
+ assert_equal("2.5.29.19", ext.value[0].oid)
152
+ assert_equal(OpenSSL::ASN1::Boolean, ext.value[1].class)
153
+ assert_equal(true, ext.value[1].value)
154
+ assert_equal(OpenSSL::ASN1::OctetString, ext.value[2].class)
155
+ extv = OpenSSL::ASN1.decode(ext.value[2].value)
156
+ assert_equal(OpenSSL::ASN1::Sequence, extv.class)
157
+ assert_equal(2, extv.value.size)
158
+ assert_equal(OpenSSL::ASN1::Boolean, extv.value[0].class)
159
+ assert_equal(true, extv.value[0].value)
160
+ assert_equal(OpenSSL::ASN1::Integer, extv.value[1].class)
161
+ assert_equal(1, extv.value[1].value)
162
+
163
+ ext = extensions.value[0].value[1] # keyUsage
164
+ assert_equal(OpenSSL::ASN1::Sequence, ext.class)
165
+ assert_equal(3, ext.value.size)
166
+ assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)
167
+ assert_equal("2.5.29.15", ext.value[0].oid)
168
+ assert_equal(OpenSSL::ASN1::Boolean, ext.value[1].class)
169
+ assert_equal(true, ext.value[1].value)
170
+ assert_equal(OpenSSL::ASN1::OctetString, ext.value[2].class)
171
+ extv = OpenSSL::ASN1.decode(ext.value[2].value)
172
+ assert_equal(OpenSSL::ASN1::BitString, extv.class)
173
+ str = "\000"; str[0] = 0b00000110
174
+ assert_equal(str, extv.value)
175
+
176
+ ext = extensions.value[0].value[2] # subjetKeyIdentifier
177
+ assert_equal(OpenSSL::ASN1::Sequence, ext.class)
178
+ assert_equal(2, ext.value.size)
179
+ assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)
180
+ assert_equal("2.5.29.14", ext.value[0].oid)
181
+ assert_equal(OpenSSL::ASN1::OctetString, ext.value[1].class)
182
+ extv = OpenSSL::ASN1.decode(ext.value[1].value)
183
+ assert_equal(OpenSSL::ASN1::OctetString, extv.class)
184
+ sha1 = OpenSSL::Digest::SHA1.new
185
+ sha1.update(pkey.value[1].value)
186
+ assert_equal(sha1.digest, extv.value)
187
+
188
+ assert_equal(OpenSSL::ASN1::Sequence, sig_alg.class)
189
+ assert_equal(2, sig_alg.value.size)
190
+ assert_equal(OpenSSL::ASN1::ObjectId, pkey.value[0].value[0].class)
191
+ assert_equal("1.2.840.113549.1.1.1", pkey.value[0].value[0].oid)
192
+ assert_equal(OpenSSL::ASN1::Null, pkey.value[0].value[1].class)
193
+
194
+ assert_equal(OpenSSL::ASN1::BitString, sig_val.class)
195
+
196
+ cululated_sig = key.sign(OpenSSL::Digest::SHA1.new, tbs_cert.to_der)
197
+ assert_equal(cululated_sig, sig_val.value)
198
+ end
199
+ end if defined?(OpenSSL)