r509 0.10.0 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.mdown +2 -2
- data/Rakefile +2 -3
- data/bin/r509 +77 -80
- data/bin/r509-parse +4 -4
- data/doc/R509.html +60 -60
- data/doc/R509/ASN1.html +158 -48
- data/doc/R509/ASN1/GeneralName.html +157 -154
- data/doc/R509/ASN1/GeneralNames.html +246 -237
- data/doc/R509/CRL.html +41 -39
- data/doc/R509/CRL/Administrator.html +105 -100
- data/doc/R509/CRL/FileReaderWriter.html +146 -98
- data/doc/R509/CRL/ReaderWriter.html +57 -54
- data/doc/R509/CRL/SQLiteReaderWriter.html +727 -0
- data/doc/R509/CRL/SignedList.html +83 -80
- data/doc/R509/CSR.html +184 -162
- data/doc/R509/Cert.html +271 -269
- data/doc/R509/Cert/Extensions.html +62 -63
- data/doc/R509/Cert/Extensions/AuthorityInfoAccess.html +138 -108
- data/doc/R509/Cert/Extensions/AuthorityKeyIdentifier.html +100 -84
- data/doc/R509/Cert/Extensions/BasicConstraints.html +89 -88
- data/doc/R509/Cert/Extensions/CRLDistributionPoints.html +87 -83
- data/doc/R509/Cert/Extensions/CertificatePolicies.html +78 -76
- data/doc/R509/Cert/Extensions/ExtendedKeyUsage.html +128 -125
- data/doc/R509/Cert/Extensions/GeneralNamesMixin.html +83 -78
- data/doc/R509/Cert/Extensions/InhibitAnyPolicy.html +69 -67
- data/doc/R509/Cert/Extensions/KeyUsage.html +138 -135
- data/doc/R509/Cert/Extensions/NameConstraints.html +82 -81
- data/doc/R509/Cert/Extensions/NoticeReference.html +59 -56
- data/doc/R509/Cert/Extensions/OCSPNoCheck.html +70 -69
- data/doc/R509/Cert/Extensions/PolicyConstraints.html +71 -69
- data/doc/R509/Cert/Extensions/PolicyInformation.html +63 -60
- data/doc/R509/Cert/Extensions/PolicyQualifiers.html +60 -57
- data/doc/R509/Cert/Extensions/SubjectAlternativeName.html +91 -87
- data/doc/R509/Cert/Extensions/SubjectKeyIdentifier.html +72 -71
- data/doc/R509/Cert/Extensions/UserNotice.html +60 -57
- data/doc/R509/Cert/Extensions/ValidationMixin.html +43 -40
- data/doc/R509/CertificateAuthority.html +39 -37
- data/doc/R509/CertificateAuthority/OptionsBuilder.html +58 -55
- data/doc/R509/CertificateAuthority/Signer.html +277 -60
- data/doc/R509/Config.html +40 -38
- data/doc/R509/Config/CAConfig.html +255 -188
- data/doc/R509/Config/CAConfigPool.html +64 -61
- data/doc/R509/Config/CertProfile.html +119 -116
- data/doc/R509/Config/SubjectItemPolicy.html +94 -93
- data/doc/R509/Engine.html +60 -56
- data/doc/R509/Helpers.html +99 -96
- data/doc/R509/MessageDigest.html +69 -68
- data/doc/R509/NameSanitizer.html +51 -48
- data/doc/R509/OCSP.html +39 -37
- data/doc/R509/OCSP/Request.html +39 -37
- data/doc/R509/OCSP/Request/Nonce.html +67 -67
- data/doc/R509/OCSP/Response.html +93 -90
- data/doc/R509/OIDMapper.html +48 -46
- data/doc/R509/PrivateKey.html +170 -169
- data/doc/R509/R509Error.html +45 -42
- data/doc/R509/SPKI.html +99 -89
- data/doc/R509/Subject.html +86 -83
- data/doc/R509/Validity.html +57 -57
- data/doc/R509/Validity/Checker.html +63 -93
- data/doc/R509/Validity/DefaultChecker.html +58 -55
- data/doc/R509/Validity/DefaultWriter.html +62 -59
- data/doc/R509/Validity/Status.html +77 -74
- data/doc/R509/Validity/Writer.html +75 -123
- data/doc/_index.html +37 -31
- data/doc/class_list.html +25 -27
- data/doc/css/full_list.css +32 -31
- data/doc/css/style.css +221 -78
- data/doc/file.CONTRIBUTING.html +29 -30
- data/doc/file.LICENSE.html +29 -30
- data/doc/file.README.html +31 -32
- data/doc/file.YAML.html +33 -34
- data/doc/file.r509.html +39 -48
- data/doc/file_list.html +39 -30
- data/doc/frames.html +10 -21
- data/doc/index.html +31 -32
- data/doc/js/app.js +100 -71
- data/doc/js/full_list.js +168 -130
- data/doc/method_list.html +1788 -1119
- data/doc/top-level-namespace.html +45 -49
- data/lib/r509.rb +21 -7
- data/lib/r509/asn1.rb +45 -32
- data/lib/r509/cert.rb +45 -51
- data/lib/r509/cert/extensions/authority_info_access.rb +49 -23
- data/lib/r509/cert/extensions/authority_key_identifier.rb +16 -11
- data/lib/r509/cert/extensions/base.rb +22 -23
- data/lib/r509/cert/extensions/basic_constraints.rb +11 -12
- data/lib/r509/cert/extensions/certificate_policies.rb +26 -26
- data/lib/r509/cert/extensions/crl_distribution_points.rb +5 -7
- data/lib/r509/cert/extensions/extended_key_usage.rb +5 -5
- data/lib/r509/cert/extensions/inhibit_any_policy.rb +4 -3
- data/lib/r509/cert/extensions/key_usage.rb +5 -5
- data/lib/r509/cert/extensions/name_constraints.rb +16 -16
- data/lib/r509/cert/extensions/ocsp_no_check.rb +3 -3
- data/lib/r509/cert/extensions/policy_constraints.rb +8 -8
- data/lib/r509/cert/extensions/subject_alternative_name.rb +5 -4
- data/lib/r509/cert/extensions/subject_key_identifier.rb +5 -5
- data/lib/r509/cert/extensions/validation_mixin.rb +11 -10
- data/lib/r509/certificate_authority/options_builder.rb +19 -21
- data/lib/r509/certificate_authority/signer.rb +26 -27
- data/lib/r509/config.rb +1 -0
- data/lib/r509/config/ca_config.rb +70 -75
- data/lib/r509/config/cert_profile.rb +9 -8
- data/lib/r509/config/subject_item_policy.rb +25 -28
- data/lib/r509/crl/administrator.rb +19 -20
- data/lib/r509/crl/reader_writer.rb +10 -8
- data/lib/r509/crl/signed_list.rb +4 -4
- data/lib/r509/crl/sqlite_reader_writer.rb +75 -0
- data/lib/r509/csr.rb +54 -60
- data/lib/r509/ec-hack.rb +3 -2
- data/lib/r509/engine.rb +5 -6
- data/lib/r509/exceptions.rb +1 -1
- data/lib/r509/helpers.rb +11 -14
- data/lib/r509/io_helpers.rb +7 -7
- data/lib/r509/message_digest.rb +5 -6
- data/lib/r509/ocsp.rb +11 -13
- data/lib/r509/oid_mapper.rb +2 -2
- data/lib/r509/private_key.rb +28 -32
- data/lib/r509/spki.rb +17 -20
- data/lib/r509/subject.rb +26 -27
- data/lib/r509/trollop.rb +1 -0
- data/lib/r509/validity.rb +30 -21
- data/lib/r509/version.rb +4 -2
- data/r509.yaml +9 -17
- data/spec/asn1_spec.rb +145 -146
- data/spec/cert/extensions/authority_info_access_spec.rb +41 -41
- data/spec/cert/extensions/authority_key_identifier_spec.rb +29 -23
- data/spec/cert/extensions/base_spec.rb +38 -34
- data/spec/cert/extensions/basic_constraints_spec.rb +21 -21
- data/spec/cert/extensions/certificate_policies_spec.rb +99 -87
- data/spec/cert/extensions/crl_distribution_points_spec.rb +24 -25
- data/spec/cert/extensions/extended_key_usage_spec.rb +40 -36
- data/spec/cert/extensions/inhibit_any_policy_spec.rb +12 -12
- data/spec/cert/extensions/key_usage_spec.rb +44 -39
- data/spec/cert/extensions/name_constraints_spec.rb +83 -83
- data/spec/cert/extensions/ocsp_no_check_spec.rb +10 -10
- data/spec/cert/extensions/policy_constraints_spec.rb +19 -19
- data/spec/cert/extensions/subject_alternative_name_spec.rb +46 -47
- data/spec/cert/extensions/subject_key_identifier_spec.rb +10 -10
- data/spec/cert_spec.rb +105 -101
- data/spec/certificate_authority/options_builder_spec.rb +90 -90
- data/spec/certificate_authority/signer_spec.rb +41 -41
- data/spec/config/ca_config_spec.rb +169 -119
- data/spec/config/cert_profile_spec.rb +33 -33
- data/spec/config/subject_item_policy_spec.rb +22 -22
- data/spec/crl/administrator_spec.rb +65 -65
- data/spec/crl/reader_writer_spec.rb +20 -19
- data/spec/crl/signed_list_spec.rb +26 -26
- data/spec/crl/sqlite_reader_writer_spec.rb +42 -0
- data/spec/csr_spec.rb +149 -145
- data/spec/engine_spec.rb +14 -14
- data/spec/fixtures.rb +56 -39
- data/spec/fixtures/crl_list.sql +13 -0
- data/spec/fixtures/csr1.der +0 -0
- data/spec/fixtures/csr1.pem +6 -6
- data/spec/message_digest_spec.rb +43 -43
- data/spec/ocsp_spec.rb +25 -25
- data/spec/oid_mapper_spec.rb +18 -19
- data/spec/private_key_spec.rb +79 -81
- data/spec/r509_spec.rb +16 -16
- data/spec/spec_helper.rb +3 -3
- data/spec/spki_spec.rb +94 -94
- data/spec/subject_spec.rb +107 -107
- data/spec/validity_spec.rb +25 -25
- metadata +113 -111
- metadata.gz.sig +0 -0
@@ -34,50 +34,51 @@ describe R509::CRL::FileReaderWriter do
|
|
34
34
|
|
35
35
|
it "handles nil crl_list_file in read_list" do
|
36
36
|
@rw.crl_list_file = nil
|
37
|
-
@rw.read_list
|
37
|
+
expect(@rw.read_list).to be_nil
|
38
38
|
end
|
39
39
|
|
40
40
|
it "handles nil crl_list_file in write_list_entry" do
|
41
41
|
@rw.crl_list_file = nil
|
42
|
-
@rw.write_list_entry(1,1,nil).
|
42
|
+
expect(@rw.write_list_entry(1, 1, nil)).to be_nil
|
43
43
|
end
|
44
44
|
|
45
45
|
it "handles nil crl_number_file in read_number" do
|
46
46
|
@rw.crl_number_file = nil
|
47
|
-
@rw.read_number.
|
47
|
+
expect(@rw.read_number).to eq(0)
|
48
48
|
end
|
49
49
|
|
50
50
|
it "handles nil crl_number_file in write_number" do
|
51
51
|
@rw.crl_number_file = nil
|
52
|
-
@rw.write_number(0).
|
52
|
+
expect(@rw.write_number(0)).to be_nil
|
53
53
|
end
|
54
54
|
|
55
55
|
it "reads a crl list" do
|
56
56
|
@rw.crl_list_file = TestFixtures::CRL_LIST_FILE
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
expect { |b| @rw.read_list(&b) }.to yield_successive_args(
|
58
|
+
[12345, 0, 1323983885],
|
59
|
+
[12346, nil, 1323983885]
|
60
|
+
)
|
61
|
+
|
61
62
|
end
|
62
63
|
|
63
64
|
it "writes a crl list entry" do
|
64
65
|
sio = StringIO.new
|
65
66
|
@rw.crl_list_file = sio
|
66
|
-
@rw.write_list_entry(1,1,nil)
|
67
|
-
sio.string.
|
68
|
-
@rw.write_list_entry(2,2,1)
|
69
|
-
sio.string.
|
67
|
+
@rw.write_list_entry(1, 1, nil)
|
68
|
+
expect(sio.string).to eq("1,1,\n")
|
69
|
+
@rw.write_list_entry(2, 2, 1)
|
70
|
+
expect(sio.string).to eq("1,1,\n2,2,1\n")
|
70
71
|
end
|
71
72
|
|
72
73
|
it "removes a crl list entry" do
|
73
74
|
sio = StringIO.new
|
74
75
|
@rw.crl_list_file = sio
|
75
|
-
@rw.write_list_entry(1,1,nil)
|
76
|
-
sio.string.
|
77
|
-
@rw.write_list_entry(2,2,1)
|
78
|
-
sio.string.
|
76
|
+
@rw.write_list_entry(1, 1, nil)
|
77
|
+
expect(sio.string).to eq("1,1,\n")
|
78
|
+
@rw.write_list_entry(2, 2, 1)
|
79
|
+
expect(sio.string).to eq("1,1,\n2,2,1\n")
|
79
80
|
@rw.remove_list_entry(2)
|
80
|
-
sio.string.
|
81
|
+
expect(sio.string).to eq("1,1,\n")
|
81
82
|
end
|
82
83
|
|
83
84
|
it "reads a number" do
|
@@ -85,13 +86,13 @@ describe R509::CRL::FileReaderWriter do
|
|
85
86
|
sio.write("500")
|
86
87
|
sio.rewind # rewind the pointer to the beginning so the next read catche the 500
|
87
88
|
@rw.crl_number_file = sio
|
88
|
-
@rw.read_number.
|
89
|
+
expect(@rw.read_number).to eq(500)
|
89
90
|
end
|
90
91
|
|
91
92
|
it "writes a crl number" do
|
92
93
|
sio = StringIO.new
|
93
94
|
@rw.crl_number_file = sio
|
94
95
|
@rw.write_number(30)
|
95
|
-
@rw.crl_number_file.string.
|
96
|
+
expect(@rw.crl_number_file.string).to eq("30")
|
96
97
|
end
|
97
98
|
end
|
@@ -11,74 +11,74 @@ describe R509::CRL::SignedList do
|
|
11
11
|
it "loads a crl with load_from_file" do
|
12
12
|
path = File.dirname(__FILE__) + '/../fixtures/crl_with_reason.pem'
|
13
13
|
crl = R509::CRL::SignedList.load_from_file path
|
14
|
-
crl.revoked[12345].
|
14
|
+
expect(crl.revoked[12345]).not_to be_nil
|
15
15
|
end
|
16
16
|
|
17
17
|
it "returns issuer" do
|
18
|
-
@crl.issuer.to_s.
|
18
|
+
expect(@crl.issuer.to_s).to eq("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA")
|
19
19
|
end
|
20
20
|
|
21
21
|
it "returns last_update" do
|
22
|
-
@crl.last_update.
|
22
|
+
expect(@crl.last_update).to eq(Time.at(1327446093))
|
23
23
|
end
|
24
24
|
|
25
25
|
it "returns next_update" do
|
26
|
-
@crl.next_update.
|
26
|
+
expect(@crl.next_update).to eq(Time.at(1328054493))
|
27
27
|
end
|
28
28
|
|
29
29
|
it "returns signature_algorithm" do
|
30
|
-
@crl.signature_algorithm.
|
30
|
+
expect(@crl.signature_algorithm).to eq("sha1WithRSAEncryption")
|
31
31
|
end
|
32
32
|
|
33
33
|
it "verifies the CRL signature" do
|
34
34
|
cert = R509::Cert.new(:cert => @test_ca_cert)
|
35
|
-
@crl.verify(cert.public_key).
|
35
|
+
expect(@crl.verify(cert.public_key)).to eq(true)
|
36
36
|
end
|
37
37
|
|
38
38
|
it "checks if a serial is revoked?" do
|
39
|
-
@crl.revoked?(111111).
|
40
|
-
@crl.revoked?('111111').
|
41
|
-
@crl.revoked?(12345).
|
42
|
-
@crl.revoked?('12345').
|
39
|
+
expect(@crl.revoked?(111111)).to eq(false)
|
40
|
+
expect(@crl.revoked?('111111')).to eq(false)
|
41
|
+
expect(@crl.revoked?(12345)).to eq(true)
|
42
|
+
expect(@crl.revoked?('12345')).to eq(true)
|
43
43
|
end
|
44
44
|
|
45
45
|
it "returns a hash of all revoked certs" do
|
46
|
-
@crl.revoked[12345][:time].
|
47
|
-
@crl.revoked[12345][:reason].
|
48
|
-
@crl.revoked[123456][:time].
|
49
|
-
@crl.revoked[123456][:reason].
|
50
|
-
@crl.revoked[1234567][:time].
|
51
|
-
@crl.revoked[1234567][:reason].
|
52
|
-
@crl.revoked[12345678].
|
46
|
+
expect(@crl.revoked[12345][:time]).to eq(Time.at(1327449693))
|
47
|
+
expect(@crl.revoked[12345][:reason]).to eq("Key Compromise")
|
48
|
+
expect(@crl.revoked[123456][:time]).to eq(Time.at(1327449693))
|
49
|
+
expect(@crl.revoked[123456][:reason]).to eq("Unspecified")
|
50
|
+
expect(@crl.revoked[1234567][:time]).to eq(Time.at(1327449693))
|
51
|
+
expect(@crl.revoked[1234567][:reason]).to eq("Unspecified")
|
52
|
+
expect(@crl.revoked[12345678]).to be_nil
|
53
53
|
end
|
54
54
|
|
55
55
|
it "returns revocation information for a serial" do
|
56
|
-
@crl.revoked_cert(11111).
|
56
|
+
expect(@crl.revoked_cert(11111)).to be_nil
|
57
57
|
revoked_info = @crl.revoked_cert(12345)
|
58
|
-
revoked_info[:time].
|
59
|
-
revoked_info[:reason].
|
58
|
+
expect(revoked_info[:time]).to eq(Time.at(1327449693))
|
59
|
+
expect(revoked_info[:reason]).to eq("Key Compromise")
|
60
60
|
end
|
61
61
|
|
62
62
|
it "returns der" do
|
63
|
-
@crl.to_der.
|
63
|
+
expect(@crl.to_der).not_to be_nil
|
64
64
|
end
|
65
65
|
it "returns pem" do
|
66
|
-
@crl.to_pem.
|
66
|
+
expect(@crl.to_pem).not_to be_nil
|
67
67
|
end
|
68
68
|
it "writes to pem" do
|
69
69
|
sio = StringIO.new
|
70
70
|
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
71
71
|
@crl.write_pem(sio)
|
72
72
|
parsed_crl = R509::CRL::SignedList.new(sio.string)
|
73
|
-
parsed_crl.issuer.to_s.
|
74
|
-
parsed_crl.issuer.CN.
|
73
|
+
expect(parsed_crl.issuer.to_s).to eq('/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA')
|
74
|
+
expect(parsed_crl.issuer.CN).to eq('Test CA')
|
75
75
|
end
|
76
76
|
it "writes to der" do
|
77
77
|
sio = StringIO.new
|
78
78
|
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
79
79
|
@crl.write_der(sio)
|
80
80
|
parsed_crl = R509::CRL::SignedList.new(sio.string)
|
81
|
-
parsed_crl.issuer.to_s.
|
82
|
-
parsed_crl.issuer.CN.
|
81
|
+
expect(parsed_crl.issuer.to_s).to eq('/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA')
|
82
|
+
expect(parsed_crl.issuer.CN).to eq('Test CA')
|
83
83
|
end
|
84
84
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'r509/crl/sqlite_reader_writer'
|
3
|
+
|
4
|
+
describe R509::CRL::SQLiteReaderWriter do
|
5
|
+
|
6
|
+
let(:empty_db) { SQLite3::Database.new ':memory:' }
|
7
|
+
let(:db) do
|
8
|
+
db = SQLite3::Database.new ':memory:'
|
9
|
+
db.execute_batch TestFixtures::CRL_LIST_SQLITE
|
10
|
+
db
|
11
|
+
end
|
12
|
+
let(:rw) { R509::CRL::SQLiteReaderWriter.new db }
|
13
|
+
|
14
|
+
it 'creates the schema automatically if its missing' do
|
15
|
+
R509::CRL::SQLiteReaderWriter.new empty_db
|
16
|
+
expect(db.execute('SELECT * FROM sqlite_master')).not_to be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'reads a crl list' do
|
20
|
+
expect { |b| rw.read_list(&b) }.to yield_successive_args([12345, 0, 1323983885], [12346, nil, 1323983885])
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'writes a crl list entry' do
|
24
|
+
rw.write_list_entry(1, 1, nil)
|
25
|
+
expect(db.execute("SELECT * FROM revoked_serials WHERE serial='1' AND revoked_at=1 AND reason is null")).not_to be_empty
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'removes a crl list entry' do
|
29
|
+
rw.remove_list_entry(12345)
|
30
|
+
expect(db.execute("SELECT * FROM revoked_serials WHERE serial='12345'")).to be_empty
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'reads a number' do
|
34
|
+
db.execute("UPDATE crl_number set number=5")
|
35
|
+
expect(rw.read_number).to eq(5)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'writes a crl number' do
|
39
|
+
rw.write_number 6
|
40
|
+
expect(db.get_first_value("SELECT number from crl_number")).to eq(6)
|
41
|
+
end
|
42
|
+
end
|
data/spec/csr_spec.rb
CHANGED
@@ -2,7 +2,6 @@ require 'spec_helper'
|
|
2
2
|
require 'stringio'
|
3
3
|
require 'r509/csr'
|
4
4
|
|
5
|
-
|
6
5
|
describe R509::CSR do
|
7
6
|
before :all do
|
8
7
|
@csr = TestFixtures::CSR
|
@@ -28,326 +27,331 @@ describe R509::CSR do
|
|
28
27
|
expect { R509::CSR.new('invalid') }.to raise_error(ArgumentError, 'Must provide a hash of options')
|
29
28
|
end
|
30
29
|
it "key creation defaults to RSA when no type or key is passed" do
|
31
|
-
csr = R509::CSR.new(:subject => [['CN','testing.rsa']], :bit_length => 1024)
|
32
|
-
csr.rsa
|
33
|
-
csr.dsa
|
34
|
-
csr.ec
|
30
|
+
csr = R509::CSR.new(:subject => [['CN', 'testing.rsa']], :bit_length => 1024)
|
31
|
+
expect(csr.rsa?).to eq(true)
|
32
|
+
expect(csr.dsa?).to eq(false)
|
33
|
+
expect(csr.ec?).to eq(false)
|
35
34
|
end
|
36
35
|
it "returns expected value for to_der" do
|
37
36
|
csr = R509::CSR.new(:csr => @csr)
|
38
|
-
csr.to_der.
|
37
|
+
expect(csr.to_der).to eq(@csr_der)
|
39
38
|
end
|
40
39
|
it "loads a csr with extraneous newlines" do
|
41
40
|
csr = R509::CSR.new(:csr => @csr_newlines)
|
42
|
-
csr.to_pem.
|
41
|
+
expect(csr.to_pem).to match(/-----BEGIN CERTIFICATE REQUEST-----/)
|
43
42
|
end
|
44
43
|
it "loads a csr with no begin/end lines" do
|
45
44
|
csr = R509::CSR.new(:csr => @csr_no_begin_end)
|
46
|
-
csr.to_pem.
|
45
|
+
expect(csr.to_pem).to match(/-----BEGIN CERTIFICATE REQUEST-----/)
|
47
46
|
end
|
48
47
|
it "returns true from #has_private_key? when private key is present" do
|
49
|
-
csr = R509::CSR.new(:bit_length => 512, :subject => [['CN','private-key-check.com']])
|
50
|
-
csr.has_private_key
|
48
|
+
csr = R509::CSR.new(:bit_length => 512, :subject => [['CN', 'private-key-check.com']])
|
49
|
+
expect(csr.has_private_key?).to eq(true)
|
51
50
|
end
|
52
51
|
it "returns false from #has_private_key? when private key is not present" do
|
53
52
|
csr = R509::CSR.new(:csr => @csr)
|
54
|
-
csr.has_private_key
|
53
|
+
expect(csr.has_private_key?).to eq(false)
|
55
54
|
end
|
56
55
|
it "key creation defaults to 2048 when no bit length or key is passed" do
|
57
|
-
csr = R509::CSR.new(:subject => [['CN','testing2048.rsa']])
|
58
|
-
csr.bit_length.
|
56
|
+
csr = R509::CSR.new(:subject => [['CN', 'testing2048.rsa']])
|
57
|
+
expect(csr.bit_length).to eq(2048)
|
59
58
|
end
|
60
59
|
it "creates a CSR when a key is provided" do
|
61
|
-
csr = R509::CSR.new(:key => @key3, :subject => [['CN','pregenerated.com']], :bit_length => 1024)
|
62
|
-
csr.to_pem.
|
63
|
-
#validate the CSR matches the key
|
64
|
-
csr.req.verify(csr.key.public_key).
|
60
|
+
csr = R509::CSR.new(:key => @key3, :subject => [['CN', 'pregenerated.com']], :bit_length => 1024)
|
61
|
+
expect(csr.to_pem).to match(/CERTIFICATE REQUEST/)
|
62
|
+
# validate the CSR matches the key
|
63
|
+
expect(csr.req.verify(csr.key.public_key)).to eq(true)
|
65
64
|
end
|
66
65
|
it "loads successfully when an R509::PrivateKey is provided" do
|
67
66
|
key = R509::PrivateKey.new(:key => @key3)
|
68
|
-
expect { R509::CSR.new(:key => key, :csr => @csr3)}.to_not raise_error
|
67
|
+
expect { R509::CSR.new(:key => key, :csr => @csr3) }.to_not raise_error
|
69
68
|
end
|
70
69
|
it "raises an exception when you pass :subject and :csr" do
|
71
|
-
expect { R509::CSR.new(:subject => [['CN','error.com']], :csr => @csr) }.to raise_error(ArgumentError,'You must provide :subject or :csr, not both')
|
70
|
+
expect { R509::CSR.new(:subject => [['CN', 'error.com']], :csr => @csr) }.to raise_error(ArgumentError, 'You must provide :subject or :csr, not both')
|
72
71
|
end
|
73
72
|
it "raises an exception for not providing valid type when key is nil" do
|
74
|
-
expect { R509::CSR.new(:subject => [['CN','error.com']], :type => :invalid_symbol) }.to raise_error(ArgumentError,"Must provide #{R509::PrivateKey::KNOWN_TYPES.join(", ")} as type when key is nil")
|
73
|
+
expect { R509::CSR.new(:subject => [['CN', 'error.com']], :type => :invalid_symbol) }.to raise_error(ArgumentError, "Must provide #{R509::PrivateKey::KNOWN_TYPES.join(", ")} as type when key is nil")
|
75
74
|
end
|
76
75
|
it "raises an exception when you don't provide :subject or :csr" do
|
77
|
-
expect { R509::CSR.new(:bit_length => 1024) }.to raise_error(ArgumentError,'You must provide :subject or :csr')
|
76
|
+
expect { R509::CSR.new(:bit_length => 1024) }.to raise_error(ArgumentError, 'You must provide :subject or :csr')
|
78
77
|
end
|
79
78
|
it "raises an exception if you provide a list of domains with an existing CSR" do
|
80
|
-
expect { R509::CSR.new(:csr => @csr, :san_names => ['moredomainsiwanttoadd.com']) }.to raise_error(ArgumentError,'You can\'t add domains to an existing CSR')
|
79
|
+
expect { R509::CSR.new(:csr => @csr, :san_names => ['moredomainsiwanttoadd.com']) }.to raise_error(ArgumentError, 'You can\'t add domains to an existing CSR')
|
81
80
|
end
|
82
81
|
it "changes the message_digest to DSS1 when passed a DSA key" do
|
83
|
-
csr = R509::CSR.new(:subject => [["CN","dsasigned.com"]], :key => @dsa_key)
|
84
|
-
csr.message_digest.name.
|
85
|
-
csr.signature_algorithm.
|
86
|
-
#dss1 is actually the same as SHA1
|
87
|
-
#Yes this is confusing
|
88
|
-
#see http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/PKey/DSA.html
|
82
|
+
csr = R509::CSR.new(:subject => [["CN", "dsasigned.com"]], :key => @dsa_key)
|
83
|
+
expect(csr.message_digest.name).to eq('dss1')
|
84
|
+
expect(csr.signature_algorithm).to eq('dsaWithSHA1')
|
85
|
+
# dss1 is actually the same as SHA1
|
86
|
+
# Yes this is confusing
|
87
|
+
# see http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/PKey/DSA.html
|
89
88
|
end
|
90
89
|
it "changes the message_digest to DSS1 when creating a DSA key" do
|
91
|
-
csr = R509::CSR.new(:subject => [["CN","dsasigned.com"]], :type => "dsa", :bit_length => 512)
|
92
|
-
csr.message_digest.name.
|
93
|
-
csr.signature_algorithm.
|
94
|
-
#dss1 is actually the same as SHA1
|
95
|
-
#Yes this is confusing
|
96
|
-
#see http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/PKey/DSA.html
|
90
|
+
csr = R509::CSR.new(:subject => [["CN", "dsasigned.com"]], :type => "dsa", :bit_length => 512)
|
91
|
+
expect(csr.message_digest.name).to eq('dss1')
|
92
|
+
expect(csr.signature_algorithm).to eq('dsaWithSHA1')
|
93
|
+
# dss1 is actually the same as SHA1
|
94
|
+
# Yes this is confusing
|
95
|
+
# see http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/PKey/DSA.html
|
97
96
|
end
|
98
97
|
it "signs a CSR properly when passed a DSA key" do
|
99
|
-
csr = R509::CSR.new(:subject => [["CN","dsasigned.com"]], :key => @dsa_key)
|
100
|
-
csr.verify_signature.
|
98
|
+
csr = R509::CSR.new(:subject => [["CN", "dsasigned.com"]], :key => @dsa_key)
|
99
|
+
expect(csr.verify_signature).to eq(true)
|
101
100
|
end
|
102
101
|
it "signs a CSR properly when creating a DSA key" do
|
103
|
-
csr = R509::CSR.new(:subject => [["CN","dsasigned.com"]], :type => "dsa", :bit_length => 512)
|
104
|
-
csr.verify_signature.
|
102
|
+
csr = R509::CSR.new(:subject => [["CN", "dsasigned.com"]], :type => "dsa", :bit_length => 512)
|
103
|
+
expect(csr.verify_signature).to eq(true)
|
105
104
|
end
|
106
105
|
it "writes to pem" do
|
107
106
|
csr = R509::CSR.new(:csr => @csr)
|
108
107
|
sio = StringIO.new
|
109
108
|
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
110
109
|
csr.write_pem(sio)
|
111
|
-
sio.string.
|
110
|
+
expect(sio.string).to eq(@csr)
|
112
111
|
end
|
113
112
|
it "writes to der" do
|
114
113
|
sio = StringIO.new
|
115
114
|
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
116
115
|
csr = R509::CSR.new(:csr => @csr)
|
117
116
|
csr.write_der(sio)
|
118
|
-
sio.string.
|
117
|
+
expect(sio.string).to eq(@csr_der)
|
119
118
|
end
|
120
119
|
it "duplicate SAN names should be removed" do
|
121
|
-
csr = R509::CSR.new(
|
122
|
-
csr.san.dns_names.
|
120
|
+
csr = R509::CSR.new(:bit_length => 512, :subject => [['CN', 'test2345.com']], :san_names => ["test2.local", "test.local", "test.local"])
|
121
|
+
expect(csr.san.dns_names).to eq(["test2.local", "test.local"])
|
123
122
|
end
|
124
123
|
it "existing GeneralNames object passed to CSR should be used" do
|
125
124
|
gn = R509::ASN1::GeneralNames.new
|
126
125
|
gn.create_item(:type => 'dNSName', :value => '127.0.0.1')
|
127
126
|
gn.create_item(:type => 'dNSName', :value => '127.0.0.2')
|
128
|
-
csr = R509::CSR.new(
|
129
|
-
csr.san.dns_names.
|
127
|
+
csr = R509::CSR.new(:bit_length => 512, :subject => [['CN', 'test2345.com']], :san_names => gn)
|
128
|
+
expect(csr.san.dns_names).to eq(["127.0.0.1", "127.0.0.2"])
|
130
129
|
end
|
131
130
|
it "san is nil when there are no SAN names" do
|
132
|
-
csr = R509::CSR.new(
|
133
|
-
csr.san.nil
|
131
|
+
csr = R509::CSR.new(:subject => [['CN', 'langui.sh'], ['emailAddress', 'ca@langui.sh']], :bit_length => 512)
|
132
|
+
expect(csr.san.nil?).to eq(true)
|
134
133
|
end
|
135
134
|
context "when initialized" do
|
136
135
|
it "raises exception when providing invalid csr" do
|
137
|
-
expect { R509::CSR.new(
|
136
|
+
expect { R509::CSR.new(:csr => 'invalid csr') }.to raise_error(OpenSSL::X509::RequestError)
|
138
137
|
end
|
139
138
|
it "raises exception when providing invalid key" do
|
140
|
-
expect { R509::CSR.new(
|
139
|
+
expect { R509::CSR.new(:csr => @csr, :key => 'invalid key') }.to raise_error(R509::R509Error, "Failed to load private key. Invalid key or incorrect password.")
|
141
140
|
end
|
142
141
|
end
|
143
142
|
context "when passing a subject array" do
|
144
143
|
it "generates a matching CSR" do
|
145
|
-
csr = R509::CSR.new(
|
146
|
-
csr.subject.to_s.
|
144
|
+
csr = R509::CSR.new(:subject => [['CN', 'langui.sh'], ['ST', 'Illinois'], ['L', 'Chicago'], ['C', 'US'], ['emailAddress', 'ca@langui.sh']], :bit_length => 1024)
|
145
|
+
expect(csr.subject.to_s).to eq('/CN=langui.sh/ST=Illinois/L=Chicago/C=US/emailAddress=ca@langui.sh')
|
147
146
|
end
|
148
147
|
it "generates a matching csr when supplying raw oids" do
|
149
|
-
csr = R509::CSR.new(
|
150
|
-
csr.subject.to_s.
|
148
|
+
csr = R509::CSR.new(:subject => [['2.5.4.3', 'common name'], ['2.5.4.15', 'business category'], ['2.5.4.7', 'locality'], ['1.3.6.1.4.1.311.60.2.1.3', 'jurisdiction oid openssl typically does not know']], :bit_length => 1024)
|
149
|
+
expect(csr.subject.to_s).to eq("/CN=common name/businessCategory=business category/L=locality/jurisdictionOfIncorporationCountryName=jurisdiction oid openssl typically does not know")
|
151
150
|
end
|
152
151
|
it "adds SAN names to a generated CSR" do
|
153
|
-
csr = R509::CSR.new(
|
154
|
-
csr.san.ip_addresses.
|
155
|
-
csr.san.dns_names.
|
156
|
-
csr.san.uris.
|
157
|
-
csr.san.rfc_822_names.
|
158
|
-
csr.san.directory_names.size.
|
159
|
-
csr.san.directory_names[0].to_s.
|
152
|
+
csr = R509::CSR.new(:subject => [['CN', 'test']], :bit_length => 1024, :san_names => ['1.2.3.4', 'http://langui.sh', 'email@address.local', 'domain.internal', '2.3.4.5', [['CN', 'dirnametest']]])
|
153
|
+
expect(csr.san.ip_addresses).to eq(['1.2.3.4', '2.3.4.5'])
|
154
|
+
expect(csr.san.dns_names).to eq(['domain.internal'])
|
155
|
+
expect(csr.san.uris).to eq(['http://langui.sh'])
|
156
|
+
expect(csr.san.rfc_822_names).to eq(['email@address.local'])
|
157
|
+
expect(csr.san.directory_names.size).to eq(1)
|
158
|
+
expect(csr.san.directory_names[0].to_s).to eq('/CN=dirnametest')
|
160
159
|
end
|
161
160
|
end
|
162
161
|
context "when supplying an existing csr" do
|
163
162
|
it "populates the bit_length" do
|
164
|
-
csr = R509::CSR.new(
|
165
|
-
csr.bit_length.
|
163
|
+
csr = R509::CSR.new(:csr => @csr)
|
164
|
+
expect(csr.bit_length).to eq(2048)
|
166
165
|
end
|
167
166
|
it "populates the subject" do
|
168
|
-
csr = R509::CSR.new(
|
169
|
-
csr.subject.to_s.
|
167
|
+
csr = R509::CSR.new(:csr => @csr)
|
168
|
+
expect(csr.subject.to_s).to eq('/CN=test.local/O=Testing CSR')
|
170
169
|
end
|
171
170
|
it "parses the san names" do
|
172
|
-
csr = R509::CSR.new(
|
173
|
-
csr.san.dns_names.
|
171
|
+
csr = R509::CSR.new(:csr => @csr)
|
172
|
+
expect(csr.san.dns_names).to eq(["test.local", "additionaldomains.com", "saniam.com"])
|
174
173
|
end
|
175
174
|
it "parses san names when there are multiple non-SAN attributes" do
|
176
|
-
csr = R509::CSR.new(
|
177
|
-
csr.san.dns_names.
|
175
|
+
csr = R509::CSR.new(:csr => @csr4_multiple_attrs)
|
176
|
+
expect(csr.san.dns_names).to eq(["adomain.com", "anotherdomain.com", "justanexample.com"])
|
178
177
|
end
|
179
178
|
it "fetches a subject component" do
|
180
|
-
csr = R509::CSR.new(
|
181
|
-
csr.subject_component('CN').to_s.
|
179
|
+
csr = R509::CSR.new(:csr => @csr)
|
180
|
+
expect(csr.subject_component('CN').to_s).to eq('test.local')
|
182
181
|
end
|
183
182
|
it "returns nil when subject component not found" do
|
184
|
-
csr = R509::CSR.new(
|
185
|
-
csr.subject_component('OU').
|
183
|
+
csr = R509::CSR.new(:csr => @csr)
|
184
|
+
expect(csr.subject_component('OU')).to be_nil
|
186
185
|
end
|
187
186
|
it "returns the signature algorithm" do
|
188
|
-
csr = R509::CSR.new(
|
189
|
-
csr.signature_algorithm.
|
187
|
+
csr = R509::CSR.new(:csr => @csr)
|
188
|
+
expect(csr.signature_algorithm).to eq('sha256WithRSAEncryption')
|
190
189
|
end
|
191
190
|
it "returns RSA key algorithm for RSA CSR" do
|
192
|
-
csr = R509::CSR.new(
|
193
|
-
csr.key_algorithm.
|
191
|
+
csr = R509::CSR.new(:csr => @csr)
|
192
|
+
expect(csr.key_algorithm).to eq("RSA")
|
194
193
|
end
|
195
194
|
it "returns DSA key algorithm for DSA CSR" do
|
196
|
-
csr = R509::CSR.new(
|
197
|
-
csr.key_algorithm.
|
195
|
+
csr = R509::CSR.new(:csr => @csr_dsa)
|
196
|
+
expect(csr.key_algorithm).to eq("DSA")
|
198
197
|
end
|
199
198
|
it "returns the public key" do
|
200
|
-
#this is more complex than it should have to be. diff versions of openssl
|
201
|
-
#return subtly diff PEM encodings so we need to look at the modulus (n)
|
202
|
-
#but beware, because n is not present for DSA certificates
|
203
|
-
csr = R509::CSR.new(
|
204
|
-
csr.public_key.n.to_i.
|
199
|
+
# this is more complex than it should have to be. diff versions of openssl
|
200
|
+
# return subtly diff PEM encodings so we need to look at the modulus (n)
|
201
|
+
# but beware, because n is not present for DSA certificates
|
202
|
+
csr = R509::CSR.new(:csr => @csr)
|
203
|
+
expect(csr.public_key.n.to_i).to eq(@csr_public_key_modulus.to_i)
|
205
204
|
end
|
206
205
|
it "returns true with valid signature" do
|
207
|
-
csr = R509::CSR.new(
|
208
|
-
csr.verify_signature.
|
206
|
+
csr = R509::CSR.new(:csr => @csr)
|
207
|
+
expect(csr.verify_signature).to eq(true)
|
209
208
|
end
|
210
209
|
it "returns false on invalid signature" do
|
211
|
-
csr = R509::CSR.new(
|
212
|
-
csr.verify_signature.
|
210
|
+
csr = R509::CSR.new(:csr => @csr_invalid_signature)
|
211
|
+
expect(csr.verify_signature).to eq(false)
|
213
212
|
end
|
214
213
|
it "works when the CSR has unknown OIDs" do
|
215
214
|
csr = R509::CSR.new(:csr => @csr_unknown_oid)
|
216
|
-
csr.subject["1.2.3.4.5.6.7.8.9.8.7.6.5.4.3.2.1.0.0"].
|
217
|
-
csr.subject["1.3.3.543.567.32.43.335.1.1.1"].
|
215
|
+
expect(csr.subject["1.2.3.4.5.6.7.8.9.8.7.6.5.4.3.2.1.0.0"]).to eq("random oid!")
|
216
|
+
expect(csr.subject["1.3.3.543.567.32.43.335.1.1.1"]).to eq("another random oid!")
|
218
217
|
end
|
219
218
|
end
|
220
219
|
context "when supplying a key with csr" do
|
221
220
|
it "raises exception on non-matching key" do
|
222
|
-
expect { R509::CSR.new(
|
221
|
+
expect { R509::CSR.new(:csr => @csr, :key => @key_csr2) }.to raise_error(R509::R509Error, 'Key does not match request.')
|
223
222
|
end
|
224
223
|
it "accepts matching key" do
|
225
|
-
csr = R509::CSR.new(
|
226
|
-
csr.to_pem.
|
224
|
+
csr = R509::CSR.new(:csr => @csr2, :key => @key_csr2)
|
225
|
+
expect(csr.to_pem).to eq(@csr2)
|
227
226
|
end
|
228
227
|
end
|
229
228
|
context "when setting alternate signature algorithms" do
|
230
|
-
it "sets
|
231
|
-
csr = R509::CSR.new(:message_digest => 'sha88', :bit_length => 512, :subject => [['CN','langui.sh']])
|
232
|
-
csr.message_digest.name.
|
233
|
-
csr.signature_algorithm.
|
229
|
+
it "sets sha256 if you pass an invalid message digest" do
|
230
|
+
csr = R509::CSR.new(:message_digest => 'sha88', :bit_length => 512, :subject => [['CN', 'langui.sh']])
|
231
|
+
expect(csr.message_digest.name).to eq('sha256')
|
232
|
+
expect(csr.signature_algorithm).to eq("sha256WithRSAEncryption")
|
233
|
+
end
|
234
|
+
it "sets sha1 properly" do
|
235
|
+
csr = R509::CSR.new(:message_digest => 'sha1', :bit_length => 512, :subject => [['CN', 'sha1-signature-alg.test']])
|
236
|
+
expect(csr.message_digest.name).to eq('sha1')
|
237
|
+
expect(csr.signature_algorithm).to eq("sha1WithRSAEncryption")
|
234
238
|
end
|
235
239
|
it "sets sha224 properly" do
|
236
|
-
csr = R509::CSR.new(:message_digest => 'sha224', :bit_length => 512, :subject => [['CN','sha224-signature-alg.test']])
|
237
|
-
csr.message_digest.name.
|
238
|
-
csr.signature_algorithm.
|
240
|
+
csr = R509::CSR.new(:message_digest => 'sha224', :bit_length => 512, :subject => [['CN', 'sha224-signature-alg.test']])
|
241
|
+
expect(csr.message_digest.name).to eq('sha224')
|
242
|
+
expect(csr.signature_algorithm).to eq("sha224WithRSAEncryption")
|
239
243
|
end
|
240
244
|
it "sets sha256 properly" do
|
241
|
-
csr = R509::CSR.new(:message_digest => 'sha256', :bit_length => 512, :subject => [['CN','sha256-signature-alg.test']])
|
242
|
-
csr.message_digest.name.
|
243
|
-
csr.signature_algorithm.
|
245
|
+
csr = R509::CSR.new(:message_digest => 'sha256', :bit_length => 512, :subject => [['CN', 'sha256-signature-alg.test']])
|
246
|
+
expect(csr.message_digest.name).to eq('sha256')
|
247
|
+
expect(csr.signature_algorithm).to eq("sha256WithRSAEncryption")
|
244
248
|
end
|
245
249
|
it "sets sha384 properly" do
|
246
|
-
csr = R509::CSR.new(:message_digest => 'sha384', :bit_length => 768, :subject => [['CN','sha384-signature-alg.test']])
|
247
|
-
csr.message_digest.name.
|
248
|
-
csr.signature_algorithm.
|
250
|
+
csr = R509::CSR.new(:message_digest => 'sha384', :bit_length => 768, :subject => [['CN', 'sha384-signature-alg.test']])
|
251
|
+
expect(csr.message_digest.name).to eq('sha384')
|
252
|
+
expect(csr.signature_algorithm).to eq("sha384WithRSAEncryption")
|
249
253
|
end
|
250
254
|
it "sets sha512 properly" do
|
251
|
-
csr = R509::CSR.new(:message_digest => 'sha512', :bit_length => 1024, :subject => [['CN','sha512-signature-alg.test']])
|
252
|
-
csr.message_digest.name.
|
253
|
-
csr.signature_algorithm.
|
255
|
+
csr = R509::CSR.new(:message_digest => 'sha512', :bit_length => 1024, :subject => [['CN', 'sha512-signature-alg.test']])
|
256
|
+
expect(csr.message_digest.name).to eq('sha512')
|
257
|
+
expect(csr.signature_algorithm).to eq("sha512WithRSAEncryption")
|
254
258
|
end
|
255
259
|
it "sets md5 properly" do
|
256
|
-
csr = R509::CSR.new(:message_digest => 'md5', :bit_length => 512, :subject => [['CN','md5-signature-alg.test']])
|
257
|
-
csr.message_digest.name.
|
258
|
-
csr.signature_algorithm.
|
260
|
+
csr = R509::CSR.new(:message_digest => 'md5', :bit_length => 512, :subject => [['CN', 'md5-signature-alg.test']])
|
261
|
+
expect(csr.message_digest.name).to eq('md5')
|
262
|
+
expect(csr.signature_algorithm).to eq("md5WithRSAEncryption")
|
259
263
|
end
|
260
264
|
end
|
261
265
|
it "checks rsa?" do
|
262
|
-
csr = R509::CSR.new(
|
263
|
-
csr.rsa
|
264
|
-
csr.ec
|
265
|
-
csr.dsa
|
266
|
+
csr = R509::CSR.new(:csr => @csr)
|
267
|
+
expect(csr.rsa?).to eq(true)
|
268
|
+
expect(csr.ec?).to eq(false)
|
269
|
+
expect(csr.dsa?).to eq(false)
|
266
270
|
end
|
267
271
|
it "gets RSA bit length" do
|
268
|
-
csr = R509::CSR.new(
|
269
|
-
csr.bit_length.
|
272
|
+
csr = R509::CSR.new(:csr => @csr)
|
273
|
+
expect(csr.bit_length).to eq(2048)
|
270
274
|
end
|
271
275
|
it "returns an error for curve_name for dsa/rsa CSRs" do
|
272
276
|
csr = R509::CSR.new(:csr => @csr)
|
273
277
|
expect { csr.curve_name }.to raise_error(R509::R509Error, 'Curve name is only available with EC')
|
274
278
|
end
|
275
279
|
it "checks dsa?" do
|
276
|
-
csr = R509::CSR.new(
|
277
|
-
csr.rsa
|
278
|
-
csr.ec
|
279
|
-
csr.dsa
|
280
|
+
csr = R509::CSR.new(:csr => @csr_dsa)
|
281
|
+
expect(csr.rsa?).to eq(false)
|
282
|
+
expect(csr.ec?).to eq(false)
|
283
|
+
expect(csr.dsa?).to eq(true)
|
280
284
|
end
|
281
285
|
it "gets DSA bit length" do
|
282
|
-
csr = R509::CSR.new(
|
283
|
-
csr.bit_length.
|
286
|
+
csr = R509::CSR.new(:csr => @csr_dsa)
|
287
|
+
expect(csr.bit_length).to eq(1024)
|
284
288
|
end
|
285
289
|
|
286
290
|
it "loads a csr with load_from_file" do
|
287
291
|
path = File.dirname(__FILE__) + '/fixtures/csr1.pem'
|
288
292
|
csr = R509::CSR.load_from_file path
|
289
|
-
csr.message_digest.name.
|
293
|
+
expect(csr.message_digest.name).to eq('sha256')
|
290
294
|
end
|
291
295
|
|
292
296
|
context "when using elliptic curves", :ec => true do
|
293
297
|
it "loads a pre-existing EC CSR" do
|
294
298
|
csr = R509::CSR.new(:csr => @ec_csr2_pem)
|
295
|
-
csr.to_der.
|
299
|
+
expect(csr.to_der).to eq(@ec_csr2_der)
|
296
300
|
end
|
297
301
|
it "returns the curve name" do
|
298
302
|
csr = R509::CSR.new(:csr => @ec_csr2_pem)
|
299
|
-
csr.curve_name.
|
303
|
+
expect(csr.curve_name).to eq("secp384r1")
|
300
304
|
end
|
301
305
|
it "generates a CSR with default curve" do
|
302
|
-
csr = R509::CSR.new(:type => "EC", :subject => [["CN","ec-test.local"]])
|
303
|
-
csr.curve_name.
|
306
|
+
csr = R509::CSR.new(:type => "EC", :subject => [["CN", "ec-test.local"]])
|
307
|
+
expect(csr.curve_name).to eq("secp384r1")
|
304
308
|
end
|
305
309
|
it "generates a CSR with explicit curve" do
|
306
|
-
csr = R509::CSR.new(:type => "EC", :curve_name => "sect283r1", :subject => [["CN","ec-test.local"]])
|
307
|
-
csr.curve_name.
|
310
|
+
csr = R509::CSR.new(:type => "EC", :curve_name => "sect283r1", :subject => [["CN", "ec-test.local"]])
|
311
|
+
expect(csr.curve_name).to eq("sect283r1")
|
308
312
|
end
|
309
313
|
it "raises error on bit length" do
|
310
314
|
csr = R509::CSR.new(:csr => @ec_csr2_der)
|
311
|
-
expect { csr.bit_length }.to raise_error(R509::R509Error,'Bit length is not available for EC at this time.')
|
315
|
+
expect { csr.bit_length }.to raise_error(R509::R509Error, 'Bit length is not available for EC at this time.')
|
312
316
|
end
|
313
317
|
it "returns the key algorithm" do
|
314
318
|
csr = R509::CSR.new(:csr => @ec_csr2_pem)
|
315
|
-
csr.key_algorithm.
|
319
|
+
expect(csr.key_algorithm).to eq("EC")
|
316
320
|
end
|
317
321
|
it "returns the public key" do
|
318
322
|
csr = R509::CSR.new(:csr => @ec_csr2_pem)
|
319
|
-
csr.public_key.private_key
|
320
|
-
csr.public_key.public_key
|
323
|
+
expect(csr.public_key.private_key?).to eq(false)
|
324
|
+
expect(csr.public_key.public_key?).to eq(true)
|
321
325
|
end
|
322
326
|
it "checks ec?" do
|
323
327
|
csr = R509::CSR.new(:csr => @ec_csr2_pem)
|
324
|
-
csr.ec
|
328
|
+
expect(csr.ec?).to eq(true)
|
325
329
|
end
|
326
330
|
it "sets alternate signature properly for EC" do
|
327
|
-
csr = R509::CSR.new(:message_digest => 'sha256', :type => "EC", :subject => [["CN","ec-signature-alg.test"]])
|
328
|
-
csr.message_digest.name.
|
329
|
-
csr.signature_algorithm.
|
331
|
+
csr = R509::CSR.new(:message_digest => 'sha256', :type => "EC", :subject => [["CN", "ec-signature-alg.test"]])
|
332
|
+
expect(csr.message_digest.name).to eq('sha256')
|
333
|
+
expect(csr.signature_algorithm).to eq('ecdsa-with-SHA256')
|
330
334
|
end
|
331
335
|
end
|
332
336
|
|
333
337
|
context "when elliptic curve support is unavailable" do
|
334
338
|
before :all do
|
335
|
-
@ec = OpenSSL::PKey.send(:remove_const
|
339
|
+
@ec = OpenSSL::PKey.send(:remove_const, :EC) # remove EC support for test!
|
336
340
|
load('r509/ec-hack.rb')
|
337
341
|
end
|
338
342
|
after :all do
|
339
|
-
OpenSSL::PKey.send(:remove_const
|
343
|
+
OpenSSL::PKey.send(:remove_const, :EC) # remove stubbed EC
|
340
344
|
OpenSSL::PKey::EC = @ec # add the real one back
|
341
345
|
end
|
342
346
|
it "checks rsa?" do
|
343
|
-
csr = R509::CSR.new(
|
344
|
-
csr.rsa
|
345
|
-
csr.ec
|
346
|
-
csr.dsa
|
347
|
+
csr = R509::CSR.new(:csr => @csr)
|
348
|
+
expect(csr.rsa?).to eq(true)
|
349
|
+
expect(csr.ec?).to eq(false)
|
350
|
+
expect(csr.dsa?).to eq(false)
|
347
351
|
end
|
348
352
|
it "returns RSA key algorithm for RSA CSR" do
|
349
|
-
csr = R509::CSR.new(
|
350
|
-
csr.key_algorithm.
|
353
|
+
csr = R509::CSR.new(:csr => @csr)
|
354
|
+
expect(csr.key_algorithm).to eq("RSA")
|
351
355
|
end
|
352
356
|
end
|
353
357
|
|