JRuby-OpenSSL 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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)