r509 0.8.1 → 0.9
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.
- data/README.md +343 -151
- data/Rakefile +26 -23
- data/bin/r509 +126 -112
- data/bin/r509-parse +24 -24
- data/doc/R509.html +169 -7
- data/doc/R509/ASN1.html +370 -0
- data/doc/R509/ASN1/GeneralName.html +1121 -0
- data/doc/R509/ASN1/GeneralNames.html +843 -0
- data/doc/R509/ASN1/NoticeReference.html +392 -0
- data/doc/R509/ASN1/PolicyInformation.html +387 -0
- data/doc/R509/ASN1/PolicyQualifiers.html +455 -0
- data/doc/R509/ASN1/UserNotice.html +386 -0
- data/doc/R509/{Crl.html → CRL.html} +7 -7
- data/doc/R509/CRL/Administrator.html +1559 -0
- data/doc/R509/{Crl/Parser.html → CRL/SignedList.html} +501 -210
- data/doc/R509/{Csr.html → CSR.html} +444 -314
- data/doc/R509/Cert.html +866 -617
- data/doc/R509/Cert/Extensions.html +52 -41
- data/doc/R509/Cert/Extensions/AuthorityInfoAccess.html +70 -35
- data/doc/R509/Cert/Extensions/AuthorityKeyIdentifier.html +387 -4
- data/doc/R509/Cert/Extensions/BasicConstraints.html +61 -25
- data/doc/R509/Cert/Extensions/CRLDistributionPoints.html +354 -0
- data/doc/R509/Cert/Extensions/CertificatePolicies.html +340 -0
- data/doc/R509/Cert/Extensions/ExtendedKeyUsage.html +440 -49
- data/doc/R509/Cert/Extensions/{CrlDistributionPoints.html → InhibitAnyPolicy.html} +52 -35
- data/doc/R509/Cert/Extensions/KeyUsage.html +247 -121
- data/doc/R509/Cert/Extensions/NameConstraints.html +445 -0
- data/doc/R509/Cert/Extensions/OCSPNoCheck.html +239 -0
- data/doc/R509/Cert/Extensions/PolicyConstraints.html +424 -0
- data/doc/R509/Cert/Extensions/SubjectAlternativeName.html +437 -62
- data/doc/R509/Cert/Extensions/SubjectKeyIdentifier.html +52 -10
- data/doc/R509/CertificateAuthority.html +4 -4
- data/doc/R509/CertificateAuthority/Signer.html +154 -187
- data/doc/R509/Config.html +6 -6
- data/doc/R509/Config/{CaConfig.html → CAConfig.html} +451 -348
- data/doc/R509/Config/{CaConfigPool.html → CAConfigPool.html} +47 -47
- data/doc/R509/Config/CAProfile.html +1015 -0
- data/doc/R509/Config/SubjectItemPolicy.html +86 -86
- data/doc/R509/IOHelpers.html +22 -22
- data/doc/R509/MessageDigest.html +14 -14
- data/doc/R509/NameSanitizer.html +53 -53
- data/doc/R509/{Ocsp.html → OCSP.html} +9 -9
- data/doc/R509/{Ocsp → OCSP}/Request.html +7 -7
- data/doc/R509/{Ocsp → OCSP}/Request/Nonce.html +56 -11
- data/doc/R509/{Ocsp → OCSP}/Response.html +44 -44
- data/doc/R509/{OidMapper.html → OIDMapper.html} +23 -39
- data/doc/R509/PrivateKey.html +415 -168
- data/doc/R509/R509Error.html +3 -3
- data/doc/R509/{Spki.html → SPKI.html} +354 -192
- data/doc/R509/Subject.html +224 -113
- data/doc/R509/Validity.html +27 -5
- data/doc/R509/Validity/Checker.html +13 -13
- data/doc/R509/Validity/DefaultChecker.html +13 -13
- data/doc/R509/Validity/DefaultWriter.html +14 -14
- data/doc/R509/Validity/Status.html +39 -39
- data/doc/R509/Validity/Writer.html +18 -18
- data/doc/_index.html +138 -35
- data/doc/class_list.html +1 -1
- data/doc/css/style.css +10 -0
- data/doc/file.README.html +368 -171
- data/doc/file.r509.html +92 -69
- data/doc/frames.html +1 -1
- data/doc/index.html +368 -171
- data/doc/method_list.html +910 -390
- data/doc/top-level-namespace.html +3 -3
- data/lib/r509.rb +32 -16
- data/lib/r509/asn1.rb +375 -0
- data/lib/r509/cert.rb +381 -364
- data/lib/r509/cert/extensions.rb +443 -76
- data/lib/r509/certificate_authority.rb +407 -0
- data/lib/r509/config.rb +547 -351
- data/lib/r509/crl.rb +336 -366
- data/lib/r509/csr.rb +278 -289
- data/lib/r509/ec-hack.rb +37 -0
- data/lib/r509/exceptions.rb +3 -3
- data/lib/r509/io_helpers.rb +44 -44
- data/lib/r509/message_digest.rb +53 -0
- data/lib/r509/ocsp.rb +80 -70
- data/lib/r509/oid_mapper.rb +32 -0
- data/lib/r509/private_key.rb +228 -0
- data/lib/r509/spki.rb +145 -93
- data/lib/r509/subject.rb +203 -110
- data/lib/r509/validity.rb +70 -68
- data/lib/r509/version.rb +2 -2
- data/r509.yaml +92 -69
- data/spec/asn1_spec.rb +402 -0
- data/spec/cert/extensions_spec.rb +957 -494
- data/spec/cert_spec.rb +382 -307
- data/spec/certificate_authority_spec.rb +668 -250
- data/spec/config_spec.rb +515 -302
- data/spec/crl_spec.rb +197 -198
- data/spec/csr_spec.rb +334 -289
- data/spec/fixtures.rb +247 -171
- data/spec/fixtures/cert1.der +0 -0
- data/spec/fixtures/cert1.pem +0 -0
- data/spec/fixtures/cert1_public_key_modulus.txt +0 -0
- data/spec/fixtures/cert3.p12 +0 -0
- data/spec/fixtures/cert3.pem +0 -0
- data/spec/fixtures/cert3_key.pem +0 -0
- data/spec/fixtures/cert3_key_des3.pem +0 -0
- data/spec/fixtures/cert4.pem +0 -0
- data/spec/fixtures/cert5.pem +0 -0
- data/spec/fixtures/cert6.pem +0 -0
- data/spec/fixtures/cert_expired.pem +0 -0
- data/spec/fixtures/cert_inhibit.pem +24 -0
- data/spec/fixtures/cert_name_constraints.pem +29 -0
- data/spec/fixtures/cert_not_yet_valid.pem +0 -0
- data/spec/fixtures/cert_ocsp_no_check.pem +18 -0
- data/spec/fixtures/cert_policy_constraints.pem +31 -0
- data/spec/fixtures/cert_san.pem +0 -0
- data/spec/fixtures/cert_san2.pem +0 -0
- data/spec/fixtures/cert_unknown_extension.pem +28 -0
- data/spec/fixtures/config_pool_test_minimal.yaml +11 -11
- data/spec/fixtures/config_test.yaml +54 -36
- data/spec/fixtures/config_test_dsa.yaml +35 -0
- data/spec/fixtures/config_test_ec.yaml +35 -0
- data/spec/fixtures/config_test_engine_key.yaml +5 -5
- data/spec/fixtures/config_test_engine_no_key_name.yaml +4 -4
- data/spec/fixtures/config_test_minimal.yaml +4 -4
- data/spec/fixtures/config_test_password.yaml +5 -5
- data/spec/fixtures/config_test_various.yaml +111 -74
- data/spec/fixtures/crl_list_file.txt +0 -0
- data/spec/fixtures/crl_with_reason.pem +0 -0
- data/spec/fixtures/csr1.der +0 -0
- data/spec/fixtures/csr1.pem +0 -0
- data/spec/fixtures/csr1_key.der +0 -0
- data/spec/fixtures/csr1_key.pem +0 -0
- data/spec/fixtures/csr1_key_encrypted_des3.pem +0 -0
- data/spec/fixtures/csr1_newlines.pem +0 -0
- data/spec/fixtures/csr1_no_begin_end.pem +0 -0
- data/spec/fixtures/csr1_public_key_modulus.txt +0 -0
- data/spec/fixtures/csr2.pem +0 -0
- data/spec/fixtures/csr2_key.pem +0 -0
- data/spec/fixtures/csr3.pem +0 -0
- data/spec/fixtures/csr4.pem +0 -0
- data/spec/fixtures/csr_dsa.pem +0 -0
- data/spec/fixtures/csr_invalid_signature.pem +0 -0
- data/spec/fixtures/dsa_key.pem +0 -0
- data/spec/fixtures/dsa_root.cer +28 -0
- data/spec/fixtures/dsa_root.key +20 -0
- data/spec/fixtures/ec_csr2.der +0 -0
- data/spec/fixtures/ec_csr2.pem +8 -0
- data/spec/fixtures/ec_key1.der +0 -0
- data/spec/fixtures/ec_key1.pem +6 -0
- data/spec/fixtures/ec_key1_encrypted.pem +9 -0
- data/spec/fixtures/ec_key2.pem +6 -0
- data/spec/fixtures/hmacsha1.sig +1 -0
- data/spec/fixtures/hmacsha512.sig +1 -0
- data/spec/fixtures/key4.pem +0 -0
- data/spec/fixtures/key4_encrypted_des3.pem +0 -0
- data/spec/fixtures/missing_key_identifier_ca.cer +0 -0
- data/spec/fixtures/missing_key_identifier_ca.key +0 -0
- data/spec/fixtures/ocsptest.r509.local.pem +0 -0
- data/spec/fixtures/ocsptest.r509.local_ocsp_request.der +0 -0
- data/spec/fixtures/ocsptest2.r509.local.pem +0 -0
- data/spec/fixtures/second_ca.cer +0 -0
- data/spec/fixtures/second_ca.key +0 -0
- data/spec/fixtures/spkac.der +0 -0
- data/spec/fixtures/spkac.txt +0 -0
- data/spec/fixtures/spkac_dsa.txt +1 -1
- data/spec/fixtures/spkac_dsa_no_verify.txt +1 -0
- data/spec/fixtures/spkac_ec.txt +1 -0
- data/spec/fixtures/spkac_rsa_newlines.txt +13 -0
- data/spec/fixtures/stca.pem +0 -0
- data/spec/fixtures/stca_ocsp_request.der +0 -0
- data/spec/fixtures/stca_ocsp_response.der +0 -0
- data/spec/fixtures/test1.csr +0 -0
- data/spec/fixtures/test_ca.cer +0 -0
- data/spec/fixtures/test_ca.key +0 -0
- data/spec/fixtures/test_ca.p12 +0 -0
- data/spec/fixtures/test_ca_des3.key +0 -0
- data/spec/fixtures/test_ca_ec.cer +14 -0
- data/spec/fixtures/test_ca_ec.key +6 -0
- data/spec/fixtures/test_ca_ec_ee.cer +22 -0
- data/spec/fixtures/test_ca_ec_ee.key +6 -0
- data/spec/fixtures/test_ca_ocsp.cer +0 -0
- data/spec/fixtures/test_ca_ocsp.key +0 -0
- data/spec/fixtures/test_ca_ocsp.p12 +0 -0
- data/spec/fixtures/test_ca_ocsp_chain.txt +0 -0
- data/spec/fixtures/test_ca_ocsp_response.der +0 -0
- data/spec/fixtures/test_ca_subroot.cer +0 -0
- data/spec/fixtures/test_ca_subroot.key +0 -0
- data/spec/fixtures/test_ca_subroot_ocsp.cer +0 -0
- data/spec/fixtures/test_ca_subroot_ocsp.key +0 -0
- data/spec/fixtures/test_ca_subroot_ocsp_response.der +0 -0
- data/spec/fixtures/unknown_oid.csr +0 -0
- data/spec/message_digest_spec.rb +104 -84
- data/spec/ocsp_spec.rb +105 -105
- data/spec/oid_mapper_spec.rb +21 -21
- data/spec/private_key_spec.rb +275 -0
- data/spec/r509_spec.rb +35 -0
- data/spec/spec_helper.rb +15 -6
- data/spec/spki_spec.rb +221 -142
- data/spec/subject_spec.rb +232 -164
- data/spec/validity_spec.rb +91 -91
- metadata +79 -25
- data/doc/R509/Config/CaProfile.html +0 -651
- data/doc/R509/Crl/Administrator.html +0 -2073
- data/lib/r509/certificateauthority.rb +0 -290
- data/lib/r509/messagedigest.rb +0 -49
- data/lib/r509/oidmapper.rb +0 -32
- data/lib/r509/privatekey.rb +0 -185
- data/spec/privatekey_spec.rb +0 -198
data/spec/cert_spec.rb
CHANGED
@@ -1,321 +1,396 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe R509::Cert do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
4
|
+
before :all do
|
5
|
+
@cert = TestFixtures::CERT
|
6
|
+
@cert_public_key_modulus = TestFixtures::CERT_PUBLIC_KEY_MODULUS
|
7
|
+
@cert3 = TestFixtures::CERT3
|
8
|
+
@cert_ocsp_no_check = TestFixtures::CERT_OCSP_NO_CHECK
|
9
|
+
@cert_der = TestFixtures::CERT_DER
|
10
|
+
@cert_san = TestFixtures::CERT_SAN
|
11
|
+
@cert_san2 = TestFixtures::CERT_SAN2
|
12
|
+
@key3 = TestFixtures::KEY3
|
13
|
+
@cert3_p12 = TestFixtures::CERT3_P12
|
14
|
+
@cert4 = TestFixtures::CERT4
|
15
|
+
@key3_encrypted = TestFixtures::KEY3_ENCRYPTED
|
16
|
+
@cert5 = TestFixtures::CERT5
|
17
|
+
@cert6 = TestFixtures::CERT6
|
18
|
+
@test_ca_cert = TestFixtures::TEST_CA_CERT
|
19
|
+
@cert_expired = TestFixtures::CERT_EXPIRED
|
20
|
+
@cert_not_yet_valid = TestFixtures::CERT_NOT_YET_VALID
|
21
|
+
@cert_inhibit = TestFixtures::CERT_INHIBIT
|
22
|
+
@cert_policy_constraints = TestFixtures::CERT_POLICY_CONSTRAINTS
|
23
|
+
@cert_name_constraints = TestFixtures::CERT_NAME_CONSTRAINTS
|
24
|
+
end
|
25
|
+
it "raises error when no hash supplied" do
|
26
|
+
expect { R509::Cert.new('no hash')}.to raise_error(ArgumentError, 'Must provide a hash of options')
|
27
|
+
end
|
28
|
+
it "raises error when no :cert supplied" do
|
29
|
+
expect { R509::Cert.new(:key => "random")}.to raise_error(ArgumentError, 'Must provide :cert or :pkcs12')
|
30
|
+
end
|
31
|
+
it "raises error when a csr is supplied to :cert" do
|
32
|
+
expect { R509::Cert.new(:cert => TestFixtures::CSR)}.to raise_error(ArgumentError, "Cert provided is actually a certificate signing request.")
|
33
|
+
end
|
34
|
+
it "raises error when :cert and :pkcs12 are both provided" do
|
35
|
+
expect { R509::Cert.new(
|
36
|
+
:key => @key3,
|
37
|
+
:pkcs12 => @cert3_p12,
|
38
|
+
:password => 'whatever'
|
39
|
+
) }.to raise_error(ArgumentError, 'When providing pkcs12, do not pass cert or key')
|
40
|
+
end
|
41
|
+
it "raises error when :key and :pkcs12 are both provided" do
|
42
|
+
expect { R509::Cert.new(
|
43
|
+
:cert => @cert,
|
44
|
+
:pkcs12 => @cert3_p12,
|
45
|
+
:password => 'whatever'
|
46
|
+
) }.to raise_error(ArgumentError, 'When providing pkcs12, do not pass cert or key')
|
47
|
+
end
|
48
|
+
it "has a public_key" do
|
49
|
+
cert = R509::Cert.new(:cert => @cert)
|
50
|
+
#this is more complex than it should have to be. diff versions of openssl
|
51
|
+
#return subtly diff PEM encodings so we need to look at the modulus (n)
|
52
|
+
#but beware, because n is not present for DSA certificates
|
53
|
+
cert.public_key.n.to_i.should == @cert_public_key_modulus.to_i
|
54
|
+
end
|
55
|
+
it "returns bit strength" do
|
56
|
+
cert = R509::Cert.new(:cert => @cert)
|
57
|
+
cert.bit_strength.should == 2048
|
58
|
+
end
|
59
|
+
it "has the right issuer" do
|
60
|
+
cert = R509::Cert.new(:cert => @cert)
|
61
|
+
cert.issuer.to_s.should == "/C=US/O=SecureTrust Corporation/CN=SecureTrust CA"
|
62
|
+
end
|
63
|
+
it "generates certificate fingerprints" do
|
64
|
+
cert = R509::Cert.new(:cert => @cert)
|
65
|
+
cert.fingerprint.should == '863bbb58877b426eb10ccfd34d3056b8c961f627'
|
66
|
+
cert.fingerprint('sha256').should == '65d624f5a6937c3005d78b3f4ff09164649dd5aeb3fd8a93d6fd420e8b587fa2'
|
67
|
+
cert.fingerprint('sha512').should == 'a07d87f04161f52ef671c9d616530d07ebadef9c93c0470091617363c9ce8618dcb7931414e599d25cb032d68597111719e76d7de4bb7a92bf5ca7c08c36cf12'
|
68
|
+
cert.fingerprint('md5').should == 'aa78501c41b19252dfbe8ba509cc21f4'
|
69
|
+
end
|
70
|
+
it "returns true from has_private_key? when a key is present" do
|
71
|
+
cert = R509::Cert.new(:cert => @cert3, :key => @key3)
|
72
|
+
cert.has_private_key?.should == true
|
73
|
+
end
|
74
|
+
it "returns false from has_private_key? when a key is not present" do
|
75
|
+
cert = R509::Cert.new(:cert => @cert)
|
76
|
+
cert.has_private_key?.should == false
|
77
|
+
end
|
78
|
+
it "loads encrypted private key with cert" do
|
79
|
+
expect { R509::Cert.new(:cert => @cert3, :key => @key3_encrypted, :password => "r509") }.to_not raise_error
|
80
|
+
end
|
81
|
+
it "loads pkcs12" do
|
82
|
+
cert = R509::Cert.new(:pkcs12 => @cert3_p12, :password => "r509")
|
83
|
+
cert.has_private_key?.should == true
|
84
|
+
cert.subject.to_s.should == '/CN=futurama.com/O=Farnsworth Enterprises'
|
85
|
+
end
|
86
|
+
it "has the right not_before" do
|
87
|
+
cert = R509::Cert.new(:cert => @cert)
|
88
|
+
cert.not_before.to_i.should == 1282659002
|
89
|
+
end
|
90
|
+
it "has the right not_after" do
|
91
|
+
cert = R509::Cert.new(:cert => @cert)
|
92
|
+
cert.not_after.to_i.should == 1377267002
|
93
|
+
end
|
94
|
+
it "returns signature algorithm" do
|
95
|
+
cert = R509::Cert.new(:cert => @cert)
|
96
|
+
cert.signature_algorithm.should == 'sha1WithRSAEncryption'
|
97
|
+
end
|
98
|
+
it "returns the RSA key algorithm" do
|
99
|
+
cert = R509::Cert.new(:cert => @cert)
|
100
|
+
cert.key_algorithm.should == :rsa
|
101
|
+
end
|
102
|
+
it "returns the DSA key algorithm" do
|
103
|
+
cert = R509::Cert.new(:cert => @cert6)
|
104
|
+
cert.key_algorithm.should == :dsa
|
105
|
+
end
|
106
|
+
it "returns list of san names when it is a san cert" do
|
107
|
+
cert = R509::Cert.new(:cert => @cert_san)
|
108
|
+
cert.san.dns_names.should == ['langui.sh']
|
109
|
+
end
|
110
|
+
it "#san returns nil when it is not a san cert" do
|
111
|
+
cert = R509::Cert.new(:cert => @cert)
|
112
|
+
cert.san.should be_nil
|
113
|
+
end
|
114
|
+
it "#all_names should return a list of san names in addition to the CN" do
|
115
|
+
cert = R509::Cert.new(:cert => @cert_san2)
|
116
|
+
cert.all_names.should == ["cn.langui.sh", "san1.langui.sh",
|
117
|
+
"san2.langui.sh", "san3.langui.sh"]
|
118
|
+
end
|
119
|
+
it "#all_names should not have duplicates" do
|
120
|
+
cert = R509::Cert.new(:cert => @cert_san)
|
121
|
+
cert.all_names.should == ["langui.sh"]
|
122
|
+
end
|
123
|
+
it "#all_names should return the CN in the array even if there are no SANs" do
|
124
|
+
cert = R509::Cert.new(:cert => @cert)
|
125
|
+
cert.all_names.should == ["langui.sh"]
|
126
|
+
end
|
127
|
+
it "raises exception when providing invalid cert" do
|
128
|
+
expect { R509::Cert.new(:cert => "invalid cert") }.to raise_error(OpenSSL::X509::CertificateError)
|
129
|
+
end
|
130
|
+
it "raises exception when providing invalid key" do
|
131
|
+
expect { R509::Cert.new(:cert => @cert, :key => 'invalid key') }.to raise_error(R509::R509Error, 'Failed to load private key. Invalid key or incorrect password.')
|
132
|
+
end
|
133
|
+
it "raises exception on non-matching key" do
|
134
|
+
expect { R509::Cert.new(:cert => @cert, :key => @key3) }.to raise_error(R509::R509Error, 'Key does not match cert.')
|
135
|
+
end
|
136
|
+
it "return normal object on matching key/cert pair" do
|
137
|
+
expect { R509::Cert.new(:cert => @cert3, :key => @key3) }.to_not raise_error
|
138
|
+
end
|
139
|
+
it "loads properly when an R509::PrivateKey is provided" do
|
140
|
+
key = R509::PrivateKey.new(:key => @key3)
|
141
|
+
expect { R509::Cert.new(:key => key, :cert => @cert3)}.to_not raise_error
|
142
|
+
end
|
143
|
+
it "writes to pem" do
|
144
|
+
cert = R509::Cert.new(:cert => @cert)
|
145
|
+
sio = StringIO.new
|
146
|
+
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
147
|
+
cert.write_pem(sio)
|
148
|
+
sio.string.should == @cert + "\n"
|
149
|
+
end
|
150
|
+
it "writes to der" do
|
151
|
+
cert = R509::Cert.new(:cert => @cert)
|
152
|
+
sio = StringIO.new
|
153
|
+
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
154
|
+
cert.write_der(sio)
|
155
|
+
sio.string.should == @cert_der
|
156
|
+
end
|
157
|
+
it "writes to pkcs12 when key/cert are present" do
|
158
|
+
cert = R509::Cert.new(:cert => @cert3, :key => @key3)
|
159
|
+
sio = StringIO.new
|
160
|
+
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
161
|
+
cert.write_pkcs12(sio,'r509_password')
|
162
|
+
expect { R509::Cert.new(:pkcs12 => sio.string, :password => 'r509_password') }.to_not raise_error
|
163
|
+
end
|
164
|
+
it "raises error when writing to pkcs12 if key is not present" do
|
165
|
+
cert = R509::Cert.new(:cert => @cert3)
|
166
|
+
expect { cert.write_pkcs12('/dev/null','password') }.to raise_error(R509::R509Error, "Writing a PKCS12 requires both key and cert")
|
167
|
+
end
|
168
|
+
it "parses san extension" do
|
169
|
+
cert = R509::Cert.new(:cert => @cert_san)
|
170
|
+
cert.san.dns_names.should == ["langui.sh"]
|
171
|
+
end
|
172
|
+
context "when initialized with an OpenSSL::X509::Certificate" do
|
173
|
+
it "returns pem on to_pem" do
|
174
|
+
test_cert = OpenSSL::X509::Certificate.new(@cert)
|
175
|
+
cert = R509::Cert.new(:cert => test_cert)
|
176
|
+
cert.to_pem.should == @cert
|
177
|
+
end
|
178
|
+
it "returns der on to_der" do
|
179
|
+
test_cert = OpenSSL::X509::Certificate.new(@cert)
|
180
|
+
cert = R509::Cert.new(:cert => test_cert)
|
181
|
+
cert.to_der.should == @cert_der
|
182
|
+
end
|
183
|
+
it "returns pem on to_s" do
|
184
|
+
test_cert = OpenSSL::X509::Certificate.new(@cert)
|
185
|
+
cert = R509::Cert.new(:cert => test_cert)
|
186
|
+
cert.to_s.should == @cert
|
187
|
+
end
|
188
|
+
end
|
189
|
+
context "when initialized with a pem" do
|
190
|
+
it "returns on to_pem" do
|
191
|
+
cert = R509::Cert.new(:cert => @cert)
|
192
|
+
cert.to_pem.should == @cert
|
193
|
+
end
|
194
|
+
it "returns der on to_der" do
|
195
|
+
cert = R509::Cert.new(:cert => @cert)
|
196
|
+
cert.to_der.should == @cert_der
|
197
|
+
end
|
198
|
+
it "returns pem on to_s" do
|
199
|
+
cert = R509::Cert.new(:cert => @cert)
|
200
|
+
cert.to_s.should == @cert
|
201
|
+
end
|
202
|
+
end
|
203
|
+
it "gets the right object from #basic_constraints" do
|
204
|
+
cert = R509::Cert.new(:cert => @cert)
|
205
|
+
cert.basic_constraints.class.should == R509::Cert::Extensions::BasicConstraints
|
206
|
+
end
|
207
|
+
it "gets the right object from #key_usage" do
|
208
|
+
cert = R509::Cert.new(:cert => @cert)
|
209
|
+
cert.key_usage.class.should == R509::Cert::Extensions::KeyUsage
|
210
|
+
end
|
211
|
+
it "gets the right object from #key_usage" do
|
212
|
+
cert = R509::Cert.new(:cert => @cert)
|
213
|
+
cert.extended_key_usage.class.should == R509::Cert::Extensions::ExtendedKeyUsage
|
214
|
+
end
|
215
|
+
it "gets the right object from #subject_key_identifier" do
|
216
|
+
cert = R509::Cert.new(:cert => @cert)
|
217
|
+
cert.subject_key_identifier.class.should == R509::Cert::Extensions::SubjectKeyIdentifier
|
218
|
+
end
|
219
|
+
it "gets the right object from #authority_key_identifier" do
|
220
|
+
cert = R509::Cert.new(:cert => @cert)
|
221
|
+
cert.authority_key_identifier.class.should == R509::Cert::Extensions::AuthorityKeyIdentifier
|
222
|
+
end
|
223
|
+
it "gets the right object from #subject_alternative_name" do
|
224
|
+
cert = R509::Cert.new(:cert => @cert5)
|
225
|
+
cert.subject_alternative_name.class.should == R509::Cert::Extensions::SubjectAlternativeName
|
226
|
+
end
|
227
|
+
it "gets the right object from #authority_info_access" do
|
228
|
+
cert = R509::Cert.new(:cert => @cert5)
|
229
|
+
cert.authority_info_access.class.should == R509::Cert::Extensions::AuthorityInfoAccess
|
230
|
+
end
|
231
|
+
it "gets the right object from #crl_distribution_points" do
|
232
|
+
cert = R509::Cert.new(:cert => @cert)
|
233
|
+
cert.crl_distribution_points.class.should == R509::Cert::Extensions::CRLDistributionPoints
|
234
|
+
end
|
235
|
+
it "gets the right object from #certificate_policies" do
|
236
|
+
cert = R509::Cert.new(:cert => @cert)
|
237
|
+
cert.certificate_policies.class.should == R509::Cert::Extensions::CertificatePolicies
|
238
|
+
end
|
239
|
+
it "gets the right object from #inhibit_any_policy" do
|
240
|
+
cert = R509::Cert.new(:cert => @cert_inhibit)
|
241
|
+
cert.inhibit_any_policy.class.should == R509::Cert::Extensions::InhibitAnyPolicy
|
242
|
+
end
|
243
|
+
it "gets the right object from #policy_constraints" do
|
244
|
+
cert = R509::Cert.new(:cert => @cert_policy_constraints)
|
245
|
+
cert.policy_constraints.class.should == R509::Cert::Extensions::PolicyConstraints
|
246
|
+
end
|
247
|
+
it "gets the right object from #name_constraints" do
|
248
|
+
cert = R509::Cert.new(:cert => @cert_name_constraints)
|
249
|
+
cert.name_constraints.class.should == R509::Cert::Extensions::NameConstraints
|
250
|
+
end
|
251
|
+
it "returns true from #ocsp_no_check? when the extension is present" do
|
252
|
+
cert = R509::Cert.new(:cert => @cert_ocsp_no_check)
|
253
|
+
cert.ocsp_no_check?.should == true
|
254
|
+
end
|
255
|
+
it "returns false from #ocsp_no_check? when the extension is not present" do
|
256
|
+
cert = R509::Cert.new(:cert => @cert)
|
257
|
+
cert.ocsp_no_check?.should == false
|
258
|
+
end
|
101
259
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
260
|
+
it "checks rsa?" do
|
261
|
+
cert = R509::Cert.new(:cert => @cert)
|
262
|
+
cert.rsa?.should == true
|
263
|
+
cert.ec?.should == false
|
264
|
+
cert.dsa?.should == false
|
265
|
+
end
|
266
|
+
it "gets RSA bit strength" do
|
267
|
+
cert = R509::Cert.new(:cert => @cert)
|
268
|
+
cert.bit_strength.should == 2048
|
269
|
+
end
|
270
|
+
it "returns an error for curve_name for DSA/RSA" do
|
271
|
+
cert = R509::Cert.new(:cert => @cert)
|
272
|
+
expect { cert.curve_name }.to raise_error(R509::R509Error, 'Curve name is only available with EC certs')
|
273
|
+
end
|
274
|
+
it "checks dsa?" do
|
275
|
+
cert = R509::Cert.new(:cert => @cert6)
|
276
|
+
cert.rsa?.should == false
|
277
|
+
cert.ec?.should == false
|
278
|
+
cert.dsa?.should == true
|
279
|
+
end
|
280
|
+
it "gets DSA bit strength" do
|
281
|
+
cert = R509::Cert.new(:cert => @cert6)
|
282
|
+
cert.bit_strength.should == 1024
|
283
|
+
end
|
284
|
+
it "gets serial of cert" do
|
285
|
+
cert = R509::Cert.new(:cert => @cert6)
|
286
|
+
cert.serial.should == 951504
|
287
|
+
end
|
288
|
+
it "gets hexserial of cert" do
|
289
|
+
cert = R509::Cert.new(:cert => @cert6)
|
290
|
+
cert.hexserial.should == "0E84D0"
|
291
|
+
end
|
292
|
+
it "checks a cert that is not yet valid" do
|
293
|
+
cert = R509::Cert.new(:cert => @cert_not_yet_valid)
|
294
|
+
cert.valid?.should == false
|
295
|
+
end
|
296
|
+
it "checks a cert that is in validity range" do
|
297
|
+
cert = R509::Cert.new(:cert => @test_ca_cert)
|
298
|
+
cert.valid?.should == true
|
299
|
+
end
|
300
|
+
it "checks a cert that is expired" do
|
301
|
+
cert = R509::Cert.new(:cert => @cert_expired)
|
302
|
+
cert.valid?.should == false
|
303
|
+
end
|
304
|
+
it "checks expired_at?" do
|
305
|
+
cert = R509::Cert.new(:cert => @cert_expired)
|
306
|
+
cert.valid_at?(Time.utc(2009,1,1)).should == false
|
307
|
+
cert.valid_at?(Time.utc(2011,3,1)).should == true
|
308
|
+
cert.valid_at?(1298959200).should == true
|
309
|
+
cert.valid_at?(Time.utc(2012,1,1)).should == false
|
310
|
+
end
|
311
|
+
it "is revoked by crl" do
|
312
|
+
cert = R509::Cert.new(:cert => @cert3)
|
313
|
+
crl_admin = R509::CRL::Administrator.new(TestFixtures.test_ca_config)
|
314
|
+
crl_admin.revoke_cert(1425751142578902223005775172931960716533532010870)
|
315
|
+
cert.is_revoked_by_crl?(crl_admin.crl).should == true
|
316
|
+
end
|
317
|
+
it "is not revoked by crl" do
|
318
|
+
cert = R509::Cert.new(:cert => @cert3)
|
319
|
+
crl_admin = R509::CRL::Administrator.new(TestFixtures.test_ca_config)
|
320
|
+
cert.is_revoked_by_crl?(crl_admin.crl).should == false
|
321
|
+
end
|
322
|
+
it "loads a cert with load_from_file" do
|
323
|
+
path = File.dirname(__FILE__) + '/fixtures/cert1.pem'
|
324
|
+
cert = R509::Cert.load_from_file path
|
325
|
+
cert.serial.to_i.should == 211653423715
|
326
|
+
end
|
327
|
+
it "returns a hash for #extensions" do
|
328
|
+
cert = R509::Cert.new(:cert => @cert3)
|
329
|
+
cert.extensions.kind_of?(Hash).should == true
|
330
|
+
end
|
331
|
+
it "returns an array for #unknown_extensions" do
|
332
|
+
cert = R509::Cert.new(:cert => @cert3)
|
333
|
+
cert.unknown_extensions.should == []
|
334
|
+
end
|
335
|
+
|
336
|
+
context "elliptic curve certs", :ec => true do
|
337
|
+
before :all do
|
338
|
+
@cert_ec = TestFixtures::EC_EE_CERT
|
339
|
+
@key_ec = TestFixtures::EC_EE_KEY
|
164
340
|
end
|
165
|
-
it "
|
166
|
-
|
167
|
-
sio = StringIO.new
|
168
|
-
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
169
|
-
cert.write_der(sio)
|
170
|
-
sio.string.should == @cert_der
|
341
|
+
it "loads a cert" do
|
342
|
+
expect { R509::Cert.new(:cert => @cert_ec) }.to_not raise_error
|
171
343
|
end
|
172
344
|
it "writes to pkcs12 when key/cert are present" do
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
end
|
179
|
-
it "raises error
|
180
|
-
|
181
|
-
|
182
|
-
end
|
183
|
-
it "
|
184
|
-
|
185
|
-
|
186
|
-
end
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
end
|
204
|
-
context "when initialized with a pem" do
|
205
|
-
it "returns on to_pem" do
|
206
|
-
cert = R509::Cert.new(:cert => @cert)
|
207
|
-
cert.to_pem.should == @cert
|
208
|
-
end
|
209
|
-
it "returns der on to_der" do
|
210
|
-
cert = R509::Cert.new(:cert => @cert)
|
211
|
-
cert.to_der.should == @cert_der
|
212
|
-
end
|
213
|
-
it "returns pem on to_s" do
|
214
|
-
cert = R509::Cert.new(:cert => @cert)
|
215
|
-
cert.to_s.should == @cert
|
216
|
-
end
|
217
|
-
end
|
218
|
-
it "gets key usage from the extensions array" do
|
219
|
-
cert = R509::Cert.new(:cert => @cert)
|
220
|
-
cert.extensions["keyUsage"].nil?.should == false
|
221
|
-
cert.extensions["keyUsage"]["value"].should == "Digital Signature, Key Encipherment"
|
222
|
-
end
|
223
|
-
it "gets extended key usage from the extensions array" do
|
224
|
-
cert = R509::Cert.new(:cert => @cert)
|
225
|
-
cert.extensions["extendedKeyUsage"].nil?.should == false
|
226
|
-
cert.extensions["extendedKeyUsage"]["value"].should == "TLS Web Server Authentication"
|
227
|
-
end
|
345
|
+
cert = R509::Cert.new(:cert => @cert_ec, :key => @key_ec)
|
346
|
+
sio = StringIO.new
|
347
|
+
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
348
|
+
cert.write_pkcs12(sio,'r509_password')
|
349
|
+
expect { R509::Cert.new(:pkcs12 => sio.string, :password => 'r509_password') }.to_not raise_error
|
350
|
+
end
|
351
|
+
it "raises error on bit strength" do
|
352
|
+
cert = R509::Cert.new(:cert => @cert_ec)
|
353
|
+
expect { cert.bit_strength }.to raise_error(R509::R509Error,'Bit strength is not available for EC at this time.')
|
354
|
+
end
|
355
|
+
it "returns curve name" do
|
356
|
+
cert = R509::Cert.new(:cert => @cert_ec)
|
357
|
+
cert.curve_name.should == 'secp384r1'
|
358
|
+
end
|
359
|
+
it "checks ec?" do
|
360
|
+
cert = R509::Cert.new(:cert => @cert_ec)
|
361
|
+
cert.rsa?.should == false
|
362
|
+
cert.dsa?.should == false
|
363
|
+
cert.ec?.should == true
|
364
|
+
end
|
365
|
+
it "returns the public key" do
|
366
|
+
cert = R509::Cert.new(:cert => @cert_ec)
|
367
|
+
private_key = R509::PrivateKey.new(:key => @key_ec)
|
368
|
+
cert.public_key.to_der.should == private_key.public_key.to_der
|
369
|
+
end
|
370
|
+
it "returns the key algorithm" do
|
371
|
+
cert = R509::Cert.new(:cert => @cert_ec)
|
372
|
+
cert.key_algorithm.should == :ec
|
373
|
+
end
|
374
|
+
end
|
228
375
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
it "gets the right object from #key_usage" do
|
234
|
-
cert = R509::Cert.new(:cert => @cert)
|
235
|
-
cert.key_usage.class.should == R509::Cert::Extensions::KeyUsage
|
236
|
-
end
|
237
|
-
it "gets the right object from #key_usage" do
|
238
|
-
cert = R509::Cert.new(:cert => @cert)
|
239
|
-
cert.extended_key_usage.class.should == R509::Cert::Extensions::ExtendedKeyUsage
|
240
|
-
end
|
241
|
-
it "gets the right object from #subject_key_identifier" do
|
242
|
-
cert = R509::Cert.new(:cert => @cert)
|
243
|
-
cert.subject_key_identifier.class.should == R509::Cert::Extensions::SubjectKeyIdentifier
|
244
|
-
end
|
245
|
-
it "gets the right object from #authority_key_identifier" do
|
246
|
-
cert = R509::Cert.new(:cert => @cert)
|
247
|
-
cert.authority_key_identifier.class.should == R509::Cert::Extensions::AuthorityKeyIdentifier
|
248
|
-
end
|
249
|
-
it "gets the right object from #subject_alternative_name" do
|
250
|
-
cert = R509::Cert.new(:cert => @cert5)
|
251
|
-
cert.subject_alternative_name.class.should == R509::Cert::Extensions::SubjectAlternativeName
|
252
|
-
end
|
253
|
-
it "gets the right object from #authority_info_access" do
|
254
|
-
cert = R509::Cert.new(:cert => @cert5)
|
255
|
-
cert.authority_info_access.class.should == R509::Cert::Extensions::AuthorityInfoAccess
|
376
|
+
context "when elliptic curve support is unavailable" do
|
377
|
+
before :all do
|
378
|
+
@ec = OpenSSL::PKey.send(:remove_const,:EC) # remove EC support for test!
|
379
|
+
load('r509/ec-hack.rb')
|
256
380
|
end
|
257
|
-
|
258
|
-
|
259
|
-
|
381
|
+
after :all do
|
382
|
+
OpenSSL::PKey.send(:remove_const,:EC) # remove stubbed EC
|
383
|
+
OpenSSL::PKey::EC = @ec # add the real one back
|
260
384
|
end
|
261
|
-
|
262
385
|
it "checks rsa?" do
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
it "gets RSA bit strength" do
|
268
|
-
cert = R509::Cert.new(:cert => @cert)
|
269
|
-
cert.bit_strength.should == 2048
|
270
|
-
end
|
271
|
-
it "checks dsa?" do
|
272
|
-
cert = R509::Cert.new(:cert => @cert6)
|
273
|
-
cert.rsa?.should == false
|
274
|
-
cert.dsa?.should == true
|
275
|
-
end
|
276
|
-
it "gets DSA bit strength" do
|
277
|
-
cert = R509::Cert.new(:cert => @cert6)
|
278
|
-
cert.bit_strength.should == 1024
|
279
|
-
end
|
280
|
-
it "gets serial of cert" do
|
281
|
-
cert = R509::Cert.new(:cert => @cert6)
|
282
|
-
cert.serial.should == 951504
|
283
|
-
end
|
284
|
-
it "checks a cert that is not yet valid" do
|
285
|
-
cert = R509::Cert.new(:cert => @cert_not_yet_valid)
|
286
|
-
cert.valid?.should == false
|
287
|
-
end
|
288
|
-
it "checks a cert that is in validity range" do
|
289
|
-
cert = R509::Cert.new(:cert => @test_ca_cert)
|
290
|
-
cert.valid?.should == true
|
291
|
-
end
|
292
|
-
it "checks a cert that is expired" do
|
293
|
-
cert = R509::Cert.new(:cert => @cert_expired)
|
294
|
-
cert.valid?.should == false
|
295
|
-
end
|
296
|
-
it "checks expired_at?" do
|
297
|
-
cert = R509::Cert.new(:cert => @cert_expired)
|
298
|
-
cert.valid_at?(Time.utc(2009,1,1)).should == false
|
299
|
-
cert.valid_at?(Time.utc(2011,3,1)).should == true
|
300
|
-
cert.valid_at?(1298959200).should == true
|
301
|
-
cert.valid_at?(Time.utc(2012,1,1)).should == false
|
302
|
-
end
|
303
|
-
it "is revoked by crl" do
|
304
|
-
cert = R509::Cert.new(:cert => @cert3)
|
305
|
-
crl_admin = R509::Crl::Administrator.new(TestFixtures.test_ca_config)
|
306
|
-
crl_admin.revoke_cert(1425751142578902223005775172931960716533532010870)
|
307
|
-
crl = crl_admin.to_crl
|
308
|
-
cert.is_revoked_by_crl?(crl).should == true
|
309
|
-
end
|
310
|
-
it "is not revoked by crl" do
|
311
|
-
cert = R509::Cert.new(:cert => @cert3)
|
312
|
-
crl_admin = R509::Crl::Administrator.new(TestFixtures.test_ca_config)
|
313
|
-
crl = crl_admin.to_crl
|
314
|
-
cert.is_revoked_by_crl?(crl).should == false
|
386
|
+
cert = R509::Cert.new(:cert => @cert)
|
387
|
+
cert.rsa?.should == true
|
388
|
+
cert.ec?.should == false
|
389
|
+
cert.dsa?.should == false
|
315
390
|
end
|
316
|
-
it "
|
317
|
-
|
318
|
-
|
319
|
-
cert.serial.to_i.should == 211653423715
|
391
|
+
it "returns RSA key algorithm for RSA CSR" do
|
392
|
+
cert = R509::Cert.new(:cert => @cert)
|
393
|
+
cert.key_algorithm.should == :rsa
|
320
394
|
end
|
395
|
+
end
|
321
396
|
end
|