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
data/spec/oid_mapper_spec.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'r509/oid_mapper'
|
3
3
|
|
4
|
-
|
5
4
|
# NOTE
|
6
5
|
# The nature of OID registration means that the state does NOT get reset between
|
7
6
|
# each test. Accordingly, we MUST use OIDs (and short names) here that will not
|
@@ -9,34 +8,34 @@ require 'r509/oid_mapper'
|
|
9
8
|
|
10
9
|
describe R509::OIDMapper do
|
11
10
|
it "registers one new oid" do
|
12
|
-
subject = R509::Subject.new [['1.4.3.2.1.2.3.5.5.5.5.5','random_oid']]
|
13
|
-
subject['1.4.3.2.1.2.3.5.5.5.5.5'].
|
14
|
-
expect { R509::Subject.new [['myOIDName','random_oid']] }.to raise_error(OpenSSL::X509::NameError,'invalid field name')
|
11
|
+
subject = R509::Subject.new [['1.4.3.2.1.2.3.5.5.5.5.5', 'random_oid']]
|
12
|
+
expect(subject['1.4.3.2.1.2.3.5.5.5.5.5']).to eq('random_oid')
|
13
|
+
expect { R509::Subject.new [['myOIDName', 'random_oid']] }.to raise_error(OpenSSL::X509::NameError, 'invalid field name')
|
15
14
|
|
16
|
-
R509::OIDMapper.register('1.4.3.2.1.2.3.5.5.5.5.5','myOIDName').
|
17
|
-
subject_new = R509::Subject.new [['myOIDName','random_oid']]
|
18
|
-
subject_new['myOIDName'].
|
15
|
+
expect(R509::OIDMapper.register('1.4.3.2.1.2.3.5.5.5.5.5', 'myOIDName')).to eq(true)
|
16
|
+
subject_new = R509::Subject.new [['myOIDName', 'random_oid']]
|
17
|
+
expect(subject_new['myOIDName']).to eq('random_oid')
|
19
18
|
end
|
20
19
|
|
21
20
|
it "registers a batch of new oids" do
|
22
|
-
expect { R509::Subject.new [['testOIDName','random_oid']] }.to raise_error(OpenSSL::X509::NameError,'invalid field name')
|
23
|
-
expect { R509::Subject.new [['anotherOIDName','second_random']] }.to raise_error(OpenSSL::X509::NameError,'invalid field name')
|
21
|
+
expect { R509::Subject.new [['testOIDName', 'random_oid']] }.to raise_error(OpenSSL::X509::NameError, 'invalid field name')
|
22
|
+
expect { R509::Subject.new [['anotherOIDName', 'second_random']] }.to raise_error(OpenSSL::X509::NameError, 'invalid field name')
|
24
23
|
R509::OIDMapper.batch_register([
|
25
|
-
|
26
|
-
|
24
|
+
{ :oid => '1.4.3.2.1.2.3.4.4.4.4', :short_name => 'testOIDName' },
|
25
|
+
{ :oid => '1.4.3.2.1.2.5.4.4.4.4', :short_name => 'anotherOIDName' }
|
27
26
|
])
|
28
|
-
subject_new = R509::Subject.new [['testOIDName','random_oid'],['anotherOIDName','second_random']]
|
29
|
-
subject_new['testOIDName'].
|
30
|
-
subject_new['anotherOIDName'].
|
27
|
+
subject_new = R509::Subject.new [['testOIDName', 'random_oid'], ['anotherOIDName', 'second_random']]
|
28
|
+
expect(subject_new['testOIDName']).to eq('random_oid')
|
29
|
+
expect(subject_new['anotherOIDName']).to eq('second_random')
|
31
30
|
end
|
32
31
|
|
33
32
|
it "registers a batch of oids from YAML" do
|
34
|
-
expect { R509::Subject.new [['thirdOIDName','random_oid']] }.to raise_error(OpenSSL::X509::NameError,'invalid field name')
|
35
|
-
expect { R509::Subject.new [['fourthOIDName','second_random']] }.to raise_error(OpenSSL::X509::NameError,'invalid field name')
|
33
|
+
expect { R509::Subject.new [['thirdOIDName', 'random_oid']] }.to raise_error(OpenSSL::X509::NameError, 'invalid field name')
|
34
|
+
expect { R509::Subject.new [['fourthOIDName', 'second_random']] }.to raise_error(OpenSSL::X509::NameError, 'invalid field name')
|
36
35
|
yaml_data = "---\ncustom_oids:\n- :oid: 1.4.3.2.1.2.3.4.4.4.5\n :short_name: thirdOIDName\n- :oid: 1.4.3.2.1.2.5.4.4.4.5\n :short_name: fourthOIDName\n"
|
37
36
|
R509::OIDMapper.register_from_yaml("custom_oids", yaml_data)
|
38
|
-
subject_new = R509::Subject.new [['thirdOIDName','random_oid'],['fourthOIDName','second_random']]
|
39
|
-
subject_new['thirdOIDName'].
|
40
|
-
subject_new['fourthOIDName'].
|
37
|
+
subject_new = R509::Subject.new [['thirdOIDName', 'random_oid'], ['fourthOIDName', 'second_random']]
|
38
|
+
expect(subject_new['thirdOIDName']).to eq('random_oid')
|
39
|
+
expect(subject_new['fourthOIDName']).to eq('second_random')
|
41
40
|
end
|
42
41
|
end
|
data/spec/private_key_spec.rb
CHANGED
@@ -14,146 +14,146 @@ describe R509::PrivateKey do
|
|
14
14
|
@ec_key_encrypted = TestFixtures::EC_KEY1_ENCRYPTED
|
15
15
|
end
|
16
16
|
it "throws an exception when given a type other than DSA, RSA, or EC" do
|
17
|
-
expect { R509::PrivateKey.new(:type
|
17
|
+
expect { R509::PrivateKey.new(:type => :not_rsa_or_dsa) }.to raise_error(ArgumentError)
|
18
18
|
end
|
19
19
|
it "throws an exception when no hash is provided" do
|
20
|
-
expect { R509::PrivateKey.new('string') }.to raise_error(ArgumentError,'Must provide a hash of options')
|
20
|
+
expect { R509::PrivateKey.new('string') }.to raise_error(ArgumentError, 'Must provide a hash of options')
|
21
21
|
end
|
22
22
|
it "returns the right value for #rsa?" do
|
23
|
-
private_key = R509::PrivateKey.new(:key
|
24
|
-
private_key.dsa
|
25
|
-
private_key.ec
|
26
|
-
private_key.rsa
|
23
|
+
private_key = R509::PrivateKey.new(:key => @key_csr)
|
24
|
+
expect(private_key.dsa?).to eq(false)
|
25
|
+
expect(private_key.ec?).to eq(false)
|
26
|
+
expect(private_key.rsa?).to eq(true)
|
27
27
|
end
|
28
28
|
it "returns the right value for #dsa?" do
|
29
29
|
private_key = R509::PrivateKey.new(:key => @dsa_key)
|
30
|
-
private_key.rsa
|
31
|
-
private_key.ec
|
32
|
-
private_key.dsa
|
30
|
+
expect(private_key.rsa?).to eq(false)
|
31
|
+
expect(private_key.ec?).to eq(false)
|
32
|
+
expect(private_key.dsa?).to eq(true)
|
33
33
|
end
|
34
34
|
it "generates a default 2048-bit RSA key when nothing is passed to the constructor" do
|
35
35
|
private_key = R509::PrivateKey.new
|
36
|
-
private_key.rsa
|
37
|
-
private_key.bit_length.
|
38
|
-
private_key.bit_strength.
|
36
|
+
expect(private_key.rsa?).to eq(true)
|
37
|
+
expect(private_key.bit_length).to eq(2048)
|
38
|
+
expect(private_key.bit_strength).to eq(2048)
|
39
39
|
end
|
40
40
|
it "defaults to RSA" do
|
41
|
-
private_key = R509::PrivateKey.new(:bit_length=>1024)
|
42
|
-
private_key.key.
|
41
|
+
private_key = R509::PrivateKey.new(:bit_length => 1024)
|
42
|
+
expect(private_key.key.is_a?(OpenSSL::PKey::RSA)).to eq(true)
|
43
43
|
end
|
44
44
|
it "loads a pre-existing RSA key" do
|
45
|
-
private_key = R509::PrivateKey.new(:key
|
46
|
-
private_key.to_pem.
|
47
|
-
@key_csr.
|
45
|
+
private_key = R509::PrivateKey.new(:key => @key_csr)
|
46
|
+
expect(private_key.to_pem).to eq(@key_csr)
|
47
|
+
expect(@key_csr).not_to be_nil
|
48
48
|
end
|
49
49
|
it "generates an RSA key at the default bit length (2048)" do
|
50
50
|
private_key = R509::PrivateKey.new(:type => "rsa")
|
51
|
-
private_key.bit_length.
|
52
|
-
private_key.key.n.to_i.to_s(2).size.
|
51
|
+
expect(private_key.bit_length).to eq(2048)
|
52
|
+
expect(private_key.key.n.to_i.to_s(2).size).to eq(2048)
|
53
53
|
end
|
54
54
|
it "generates an RSA key at a custom bit length" do
|
55
55
|
private_key = R509::PrivateKey.new(:type => "rsa", :bit_length => 512)
|
56
|
-
private_key.bit_length.
|
57
|
-
private_key.key.n.to_i.to_s(2).size.
|
56
|
+
expect(private_key.bit_length).to eq(512)
|
57
|
+
expect(private_key.key.n.to_i.to_s(2).size).to eq(512)
|
58
58
|
end
|
59
59
|
it "loads a pre-existing DSA key" do
|
60
60
|
private_key = R509::PrivateKey.new(:key => @dsa_key)
|
61
|
-
private_key.key.
|
62
|
-
private_key.key.to_pem.
|
63
|
-
@dsa_key.
|
61
|
+
expect(private_key.key.is_a?(OpenSSL::PKey::DSA)).to eq(true)
|
62
|
+
expect(private_key.key.to_pem).to eq(@dsa_key)
|
63
|
+
expect(@dsa_key).not_to be_nil
|
64
64
|
end
|
65
65
|
it "generates a DSA key at the default bit length (2048)" do
|
66
66
|
private_key = R509::PrivateKey.new(:type => "dsa")
|
67
|
-
private_key.dsa
|
68
|
-
private_key.bit_length.
|
69
|
-
private_key.key.p.to_i.to_s(2).size.
|
67
|
+
expect(private_key.dsa?).to eq(true)
|
68
|
+
expect(private_key.bit_length).to eq(2048)
|
69
|
+
expect(private_key.key.p.to_i.to_s(2).size).to eq(2048)
|
70
70
|
end
|
71
71
|
it "generates a DSA key at a custom bit length" do
|
72
72
|
private_key = R509::PrivateKey.new(:type => "dsa", :bit_length => 512)
|
73
|
-
private_key.bit_length.
|
74
|
-
private_key.key.p.to_i.to_s(2).size.
|
73
|
+
expect(private_key.bit_length).to eq(512)
|
74
|
+
expect(private_key.key.p.to_i.to_s(2).size).to eq(512)
|
75
75
|
end
|
76
76
|
it "has an exponent of 65537 for new RSA keys" do
|
77
|
-
#this test actually checks ruby's underlying libs to make sure they're
|
78
|
-
#doing what they're supposed to be doing.
|
77
|
+
# this test actually checks ruby's underlying libs to make sure they're
|
78
|
+
# doing what they're supposed to be doing.
|
79
79
|
private_key = R509::PrivateKey.new(:type => "rsa", :bit_length => 512)
|
80
|
-
private_key.key.e.
|
80
|
+
expect(private_key.key.e).to eq(65537)
|
81
81
|
end
|
82
82
|
it "returns the public key" do
|
83
83
|
private_key = R509::PrivateKey.new(:key => @key_csr)
|
84
|
-
private_key.public_key.n.to_i.
|
84
|
+
expect(private_key.public_key.n.to_i).to eq(@csr_public_key_modulus.to_i)
|
85
85
|
end
|
86
86
|
it "returns pem" do
|
87
|
-
#load the DER, check that it matches the PEM on to_pem
|
87
|
+
# load the DER, check that it matches the PEM on to_pem
|
88
88
|
private_key = R509::PrivateKey.new(:key => @key_csr_der)
|
89
|
-
private_key.to_pem.
|
89
|
+
expect(private_key.to_pem).to eq(@key_csr)
|
90
90
|
end
|
91
91
|
it "returns der" do
|
92
|
-
#load the PEM, check that it matches the DER on to_der
|
92
|
+
# load the PEM, check that it matches the DER on to_der
|
93
93
|
private_key = R509::PrivateKey.new(:key => @key_csr)
|
94
|
-
private_key.to_der.
|
94
|
+
expect(private_key.to_der).to eq(@key_csr_der)
|
95
95
|
end
|
96
96
|
it "writes pem" do
|
97
97
|
private_key = R509::PrivateKey.new(:key => @key_csr)
|
98
98
|
sio = StringIO.new
|
99
99
|
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
100
100
|
private_key.write_pem(sio)
|
101
|
-
sio.string.
|
101
|
+
expect(sio.string).to eq(@key_csr)
|
102
102
|
end
|
103
103
|
it "writes der" do
|
104
104
|
private_key = R509::PrivateKey.new(:key => @key_csr_der)
|
105
105
|
sio = StringIO.new
|
106
106
|
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
107
107
|
private_key.write_der(sio)
|
108
|
-
sio.string.
|
108
|
+
expect(sio.string).to eq(@key_csr_der)
|
109
109
|
end
|
110
110
|
it "loads an encrypted private key with the right password" do
|
111
111
|
private_key = R509::PrivateKey.new(:key => @key_csr_encrypted, :password => 'Testing1')
|
112
|
-
private_key.public_key.n.to_i.
|
112
|
+
expect(private_key.public_key.n.to_i).to eq(@csr_public_key_modulus.to_i)
|
113
113
|
end
|
114
114
|
it "fails to load an encrypted private key with wrong password" do
|
115
|
-
expect { R509::PrivateKey.new(:key => @key_csr_encrypted, :password => 'wrongPassword') }.to raise_error(R509::R509Error,"Failed to load private key. Invalid key or incorrect password.")
|
115
|
+
expect { R509::PrivateKey.new(:key => @key_csr_encrypted, :password => 'wrongPassword') }.to raise_error(R509::R509Error, "Failed to load private key. Invalid key or incorrect password.")
|
116
116
|
end
|
117
117
|
it "returns an encrypted pem" do
|
118
118
|
private_key = R509::PrivateKey.new(:key => @key_csr)
|
119
|
-
encrypted_private_key = private_key.to_encrypted_pem('des3','Testing1')
|
119
|
+
encrypted_private_key = private_key.to_encrypted_pem('des3', 'Testing1')
|
120
120
|
decrypted_private_key = R509::PrivateKey.new(:key => encrypted_private_key, :password => 'Testing1')
|
121
|
-
private_key.to_pem.
|
121
|
+
expect(private_key.to_pem).to eq(decrypted_private_key.to_pem)
|
122
122
|
end
|
123
123
|
it "writes an encrypted pem" do
|
124
124
|
private_key = R509::PrivateKey.new(:key => @key_csr)
|
125
125
|
sio = StringIO.new
|
126
126
|
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
127
|
-
private_key.write_encrypted_pem(sio,'des3','Testing1')
|
128
|
-
sio.string.match(/Proc-Type: 4,ENCRYPTED/).
|
127
|
+
private_key.write_encrypted_pem(sio, 'des3', 'Testing1')
|
128
|
+
expect(sio.string.match(/Proc-Type: 4,ENCRYPTED/)).not_to be_nil
|
129
129
|
end
|
130
130
|
it "creates an encrypted private key with des3 cipher" do
|
131
131
|
private_key = R509::PrivateKey.new(:key => @key_csr)
|
132
132
|
sio = StringIO.new
|
133
133
|
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
134
|
-
private_key.write_encrypted_pem(sio,'des3','Testing1')
|
135
|
-
sio.string.match(/DES-EDE3-CBC/).
|
134
|
+
private_key.write_encrypted_pem(sio, 'des3', 'Testing1')
|
135
|
+
expect(sio.string.match(/DES-EDE3-CBC/)).not_to be_nil
|
136
136
|
end
|
137
137
|
it "creates an encrypted private key with aes128 cipher" do
|
138
138
|
private_key = R509::PrivateKey.new(:key => @key_csr)
|
139
139
|
sio = StringIO.new
|
140
140
|
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
141
|
-
private_key.write_encrypted_pem(sio,'aes128','Testing1')
|
142
|
-
sio.string.match(/AES-128-CBC/).
|
141
|
+
private_key.write_encrypted_pem(sio, 'aes128', 'Testing1')
|
142
|
+
expect(sio.string.match(/AES-128-CBC/)).not_to be_nil
|
143
143
|
end
|
144
144
|
it "returns false for in_hardware? when not using an engine" do
|
145
145
|
private_key = R509::PrivateKey.new(:key => @key_csr)
|
146
|
-
private_key.in_hardware
|
146
|
+
expect(private_key.in_hardware?).to eq(false)
|
147
147
|
end
|
148
148
|
it "returns true for in_hardware? when an engine is present" do
|
149
149
|
engine = double("engine")
|
150
|
-
engine.
|
150
|
+
expect(engine).to receive(:is_a?).with(OpenSSL::Engine).and_return(true)
|
151
151
|
key_name = "r509_key"
|
152
152
|
key = R509::PrivateKey.new(
|
153
153
|
:engine => engine,
|
154
154
|
:key_name => key_name
|
155
155
|
)
|
156
|
-
key.in_hardware
|
156
|
+
expect(key.in_hardware?).to eq(true)
|
157
157
|
end
|
158
158
|
it "raises an error if you provide engine and key" do
|
159
159
|
expect { R509::PrivateKey.new(:key => @key_csr, :engine => 'not really an engine') }.to raise_error(ArgumentError, "You can't pass both :key and :engine")
|
@@ -169,7 +169,7 @@ describe R509::PrivateKey do
|
|
169
169
|
end
|
170
170
|
it "raises an error if you call output methods (pem,der,write) when using a hardware key" do
|
171
171
|
engine = double("engine")
|
172
|
-
engine.
|
172
|
+
expect(engine).to receive(:is_a?).with(OpenSSL::Engine).and_return(true)
|
173
173
|
key_name = "r509_key"
|
174
174
|
key = R509::PrivateKey.new(
|
175
175
|
:engine => engine,
|
@@ -177,33 +177,33 @@ describe R509::PrivateKey do
|
|
177
177
|
)
|
178
178
|
expect { key.to_pem }.to raise_error(R509::R509Error, "This method cannot be called when using keys in hardware")
|
179
179
|
expect { key.to_der }.to raise_error(R509::R509Error, "This method cannot be called when using keys in hardware")
|
180
|
-
expect { key.to_encrypted_pem('aes256','password') }.to raise_error(R509::R509Error, "This method cannot be called when using keys in hardware")
|
181
|
-
expect { key.write_encrypted_pem('/dev/null','aes256','password') }.to raise_error(R509::R509Error, "This method cannot be called when using keys in hardware")
|
180
|
+
expect { key.to_encrypted_pem('aes256', 'password') }.to raise_error(R509::R509Error, "This method cannot be called when using keys in hardware")
|
181
|
+
expect { key.write_encrypted_pem('/dev/null', 'aes256', 'password') }.to raise_error(R509::R509Error, "This method cannot be called when using keys in hardware")
|
182
182
|
expect { key.write_der('/dev/null') }.to raise_error(R509::R509Error, "This method cannot be called when using keys in hardware")
|
183
183
|
end
|
184
184
|
it "loads a hardware key successfully" do
|
185
185
|
engine = double("engine")
|
186
|
-
engine.
|
186
|
+
expect(engine).to receive(:is_a?).with(OpenSSL::Engine).and_return(true)
|
187
187
|
faux_key = double("faux_key")
|
188
|
-
faux_key.
|
188
|
+
expect(faux_key).to receive(:public_key).and_return("returning public key")
|
189
189
|
key_name = "r509_key"
|
190
|
-
engine.
|
190
|
+
expect(engine).to receive(:load_private_key).twice.with(key_name).and_return(faux_key)
|
191
191
|
key = R509::PrivateKey.new(
|
192
192
|
:engine => engine,
|
193
193
|
:key_name => key_name
|
194
194
|
)
|
195
|
-
key.
|
196
|
-
key.public_key.
|
195
|
+
expect(key.is_a?(R509::PrivateKey)).to eq(true)
|
196
|
+
expect(key.public_key).to eq("returning public key")
|
197
197
|
end
|
198
198
|
it "loads a private key with load_from_file" do
|
199
199
|
path = File.dirname(__FILE__) + '/fixtures/key4.pem'
|
200
200
|
key = R509::PrivateKey.load_from_file path
|
201
|
-
key.rsa
|
201
|
+
expect(key.rsa?).to eq(true)
|
202
202
|
end
|
203
203
|
it "loads a private key with load_from_file with password" do
|
204
204
|
path = File.dirname(__FILE__) + '/fixtures/key4_encrypted_des3.pem'
|
205
|
-
key = R509::PrivateKey.load_from_file(
|
206
|
-
key.rsa
|
205
|
+
key = R509::PrivateKey.load_from_file(path, 'r509')
|
206
|
+
expect(key.rsa?).to eq(true)
|
207
207
|
end
|
208
208
|
|
209
209
|
it "returns an error for curve_name for dsa/rsa" do
|
@@ -214,63 +214,61 @@ describe R509::PrivateKey do
|
|
214
214
|
context "elliptic curves", :ec => true do
|
215
215
|
it "loads a pre-existing EC key" do
|
216
216
|
private_key = R509::PrivateKey.new(:key => @ec_key_pem)
|
217
|
-
private_key.to_pem.
|
218
|
-
@ec_key_pem.
|
217
|
+
expect(private_key.to_pem).to eq(@ec_key_pem)
|
218
|
+
expect(@ec_key_pem).not_to be_nil
|
219
219
|
end
|
220
220
|
|
221
221
|
it "loads an encrypted private key with the right password" do
|
222
222
|
private_key = R509::PrivateKey.new(:key => @ec_key_encrypted, :password => 'Testing1')
|
223
|
-
private_key.to_pem.
|
224
|
-
@ec_key_encrypted.
|
225
|
-
@ec_key_pem.
|
223
|
+
expect(private_key.to_pem).to eq(@ec_key_pem)
|
224
|
+
expect(@ec_key_encrypted).not_to be_nil
|
225
|
+
expect(@ec_key_pem).not_to be_nil
|
226
226
|
end
|
227
227
|
|
228
228
|
it "returns the right value for #ec?" do
|
229
229
|
path = File.dirname(__FILE__) + '/fixtures/ec_key1.der'
|
230
230
|
private_key = R509::PrivateKey.load_from_file path
|
231
|
-
private_key.rsa
|
232
|
-
private_key.dsa
|
233
|
-
private_key.ec
|
231
|
+
expect(private_key.rsa?).to eq(false)
|
232
|
+
expect(private_key.dsa?).to eq(false)
|
233
|
+
expect(private_key.ec?).to eq(true)
|
234
234
|
end
|
235
235
|
|
236
236
|
it "returns the curve_name" do
|
237
237
|
private_key = R509::PrivateKey.new(:key => @ec_key_pem)
|
238
|
-
private_key.curve_name.
|
238
|
+
expect(private_key.curve_name).to eq('secp384r1')
|
239
239
|
end
|
240
240
|
|
241
241
|
it "generates an elliptic curve key using the default curve (secp384r1)" do
|
242
242
|
private_key = R509::PrivateKey.new(:type => "ec")
|
243
|
-
private_key.curve_name.
|
243
|
+
expect(private_key.curve_name).to eq('secp384r1')
|
244
244
|
end
|
245
245
|
|
246
246
|
it "generates an elliptic curve key using a specified curve" do
|
247
247
|
private_key = R509::PrivateKey.new(:type => "ec", :curve_name => 'sect283r1')
|
248
|
-
private_key.curve_name.
|
248
|
+
expect(private_key.curve_name).to eq('sect283r1')
|
249
249
|
end
|
250
250
|
|
251
251
|
it "returns the public key" do
|
252
252
|
private_key = R509::PrivateKey.new(:key => @ec_key_pem)
|
253
253
|
public_key = private_key.public_key
|
254
|
-
public_key.public_key
|
255
|
-
public_key.private_key
|
254
|
+
expect(public_key.public_key?).to eq(true)
|
255
|
+
expect(public_key.private_key?).to eq(false)
|
256
256
|
end
|
257
257
|
|
258
258
|
it "returns the pem" do
|
259
259
|
private_key = R509::PrivateKey.new(:key => @ec_key_pem)
|
260
|
-
private_key.to_pem.
|
260
|
+
expect(private_key.to_pem).to eq(@ec_key_pem)
|
261
261
|
end
|
262
262
|
|
263
263
|
it "returns the der" do
|
264
264
|
private_key = R509::PrivateKey.new(:key => @ec_key_pem)
|
265
|
-
private_key.to_der.
|
265
|
+
expect(private_key.to_der).to eq(@ec_key_der)
|
266
266
|
end
|
267
267
|
|
268
268
|
it "returns error for bit_length" do
|
269
269
|
private_key = R509::PrivateKey.new(:key => @ec_key_pem)
|
270
|
-
expect { private_key.bit_length }.to raise_error(R509::R509Error,'Bit length is not available for EC at this time.')
|
270
|
+
expect { private_key.bit_length }.to raise_error(R509::R509Error, 'Bit length is not available for EC at this time.')
|
271
271
|
end
|
272
272
|
|
273
|
-
|
274
273
|
end
|
275
274
|
end
|
276
|
-
|
data/spec/r509_spec.rb
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
def capture_stdout
|
3
|
+
def capture_stdout
|
4
4
|
original_stdout = $stdout
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
$stdout = fake = StringIO.new
|
6
|
+
begin
|
7
|
+
yield
|
8
|
+
ensure
|
9
|
+
$stdout = original_stdout
|
10
|
+
end
|
11
|
+
fake.string
|
12
12
|
end
|
13
13
|
|
14
14
|
describe R509 do
|
15
15
|
it "prints version and feature info with ::print_debug" do
|
16
16
|
output = capture_stdout { R509.print_debug }
|
17
|
-
output.
|
18
|
-
output.
|
19
|
-
output.
|
20
|
-
output.
|
17
|
+
expect(output).to match(/^r509 v/)
|
18
|
+
expect(output).to match(/^OpenSSL/)
|
19
|
+
expect(output).to match(/^Ruby/)
|
20
|
+
expect(output).to match(/^Elliptic/)
|
21
21
|
end
|
22
22
|
it "checks if ec is supported", :ec => true do
|
23
|
-
R509.ec_supported
|
23
|
+
expect(R509.ec_supported?).to eq(true)
|
24
24
|
end
|
25
25
|
it "checks if EC is unsupported" do
|
26
|
-
ec = OpenSSL::PKey.send(:remove_const
|
26
|
+
ec = OpenSSL::PKey.send(:remove_const, :EC) # remove EC support for test!
|
27
27
|
load('r509/ec-hack.rb')
|
28
|
-
R509.ec_supported
|
28
|
+
expect(R509.ec_supported?).to eq(false)
|
29
29
|
expect { OpenSSL::PKey::EC.new }.to raise_error(R509::R509Error)
|
30
|
-
OpenSSL::PKey.send(:remove_const
|
30
|
+
OpenSSL::PKey.send(:remove_const, :EC) # remove stubbed EC
|
31
31
|
OpenSSL::PKey::EC = ec # add the real one back
|
32
32
|
# this pretty fragile. if the expectation fails then we don't fix the EC class assignment
|
33
33
|
# so any spec called after this will fail improperly.
|
data/spec/spec_helper.rb
CHANGED
@@ -6,15 +6,15 @@ begin
|
|
6
6
|
rescue LoadError
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
|
10
|
+
$LOAD_PATH.unshift File.expand_path("../", __FILE__)
|
11
11
|
require 'rubygems'
|
12
12
|
require 'fixtures'
|
13
13
|
require 'rspec'
|
14
14
|
require 'r509'
|
15
15
|
|
16
16
|
# exclude EC specific tests if it's unsupported
|
17
|
-
|
17
|
+
unless R509.ec_supported?
|
18
18
|
puts "\e[#{31}mWARNING: NOT RUNNING EC TESTS BECAUSE EC IS UNSUPPORTED ON YOUR RUBY INSTALLATION\e[0m"
|
19
19
|
R509.print_debug
|
20
20
|
RSpec.configure do |c|
|