|
3 | 3 |
|
4 | 4 | class TestASN1 < TestCase
|
5 | 5 |
|
| 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 | + assert_equal(cululated_sig, sig_val.value) |
| 192 | + end |
| 193 | + |
6 | 194 | def test_encode_boolean
|
7 | 195 | encode_decode_test(OpenSSL::ASN1::Boolean, [true, false])
|
8 | 196 | end
|
|
0 commit comments