certificate_authority 0.1.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +26 -0
- data/.gitignore +6 -0
- data/.rspec +3 -0
- data/Gemfile +2 -8
- data/Gemfile.lock +71 -27
- data/README.rdoc +91 -2
- data/Rakefile +6 -41
- data/certificate_authority.gemspec +22 -83
- data/lib/certificate_authority/certificate.rb +139 -49
- data/lib/certificate_authority/certificate_revocation_list.rb +34 -14
- data/lib/certificate_authority/core_extensions.rb +46 -0
- data/lib/certificate_authority/distinguished_name.rb +64 -16
- data/lib/certificate_authority/extensions.rb +417 -45
- data/lib/certificate_authority/key_material.rb +30 -9
- data/lib/certificate_authority/ocsp_handler.rb +75 -5
- data/lib/certificate_authority/pkcs11_key_material.rb +0 -2
- data/lib/certificate_authority/revocable.rb +14 -0
- data/lib/certificate_authority/serial_number.rb +15 -2
- data/lib/certificate_authority/signing_request.rb +91 -0
- data/lib/certificate_authority/validations.rb +31 -0
- data/lib/certificate_authority/version.rb +3 -0
- data/lib/certificate_authority.rb +6 -5
- metadata +76 -71
- data/VERSION.yml +0 -5
- data/spec/spec_helper.rb +0 -4
- data/spec/units/certificate_authority_spec.rb +0 -4
- data/spec/units/certificate_revocation_list_spec.rb +0 -68
- data/spec/units/certificate_spec.rb +0 -428
- data/spec/units/distinguished_name_spec.rb +0 -59
- data/spec/units/extensions_spec.rb +0 -115
- data/spec/units/key_material_spec.rb +0 -100
- data/spec/units/ocsp_handler_spec.rb +0 -104
- data/spec/units/pkcs11_key_material_spec.rb +0 -41
- data/spec/units/serial_number_spec.rb +0 -20
- data/spec/units/signing_entity_spec.rb +0 -4
- data/spec/units/units_helper.rb +0 -1
@@ -1,100 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/units_helper'
|
2
|
-
|
3
|
-
describe CertificateAuthority::KeyMaterial do
|
4
|
-
[CertificateAuthority::MemoryKeyMaterial, CertificateAuthority::SigningRequestKeyMaterial].each do |key_material_class|
|
5
|
-
before do
|
6
|
-
@key_material = key_material_class.new
|
7
|
-
end
|
8
|
-
|
9
|
-
it "#{key_material_class} should know if a key is in memory or hardware" do
|
10
|
-
@key_material.is_in_hardware?.should_not be_nil
|
11
|
-
@key_material.is_in_memory?.should_not be_nil
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should use memory by default" do
|
15
|
-
@key_material.is_in_memory?.should be_true
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe CertificateAuthority::MemoryKeyMaterial do
|
21
|
-
before(:each) do
|
22
|
-
@key_material = CertificateAuthority::MemoryKeyMaterial.new
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should be able to generate an RSA key" do
|
26
|
-
@key_material.generate_key(1024).should_not be_nil
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should generate a proper OpenSSL::PKey::RSA" do
|
30
|
-
@key_material.generate_key(1024).class.should == OpenSSL::PKey::RSA
|
31
|
-
end
|
32
|
-
|
33
|
-
it "should be able to specify the size of the modulus to generate" do
|
34
|
-
@key_material.generate_key(1024).should_not be_nil
|
35
|
-
end
|
36
|
-
|
37
|
-
describe "with generated key" do
|
38
|
-
before(:all) do
|
39
|
-
@key_material_in_memory = CertificateAuthority::MemoryKeyMaterial.new
|
40
|
-
@key_material_in_memory.generate_key(1024)
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should be able to retrieve the private key" do
|
44
|
-
@key_material_in_memory.private_key.should_not be_nil
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should be able to retrieve the public key" do
|
48
|
-
@key_material_in_memory.public_key.should_not be_nil
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
it "should not validate without public and private keys" do
|
53
|
-
@key_material.valid?.should be_false
|
54
|
-
@key_material.generate_key(1024)
|
55
|
-
@key_material.valid?.should be_true
|
56
|
-
pub = @key_material.public_key
|
57
|
-
@key_material.public_key = nil
|
58
|
-
@key_material.valid?.should be_false
|
59
|
-
@key_material.public_key = pub
|
60
|
-
@key_material.private_key = nil
|
61
|
-
@key_material.valid?.should be_false
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe CertificateAuthority::SigningRequestKeyMaterial do
|
66
|
-
before(:each) do
|
67
|
-
@request = OpenSSL::X509::Request.new <<CSR
|
68
|
-
-----BEGIN CERTIFICATE REQUEST-----
|
69
|
-
MIIBjTCB9wIBADBOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEU
|
70
|
-
MBIGA1UEBxMLQmVyc2Vya2VsZXkxFDASBgNVBAoTC0NlcnRzICdSIFVzMIGfMA0G
|
71
|
-
CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaGiBcv++581KYt6y2NNcUaZNPPeNZ0UkX
|
72
|
-
ujzZQQllx7PlYmsKTE6ZzfTUc0AJvDBIuACg03eagaEaBZtUFbsLkSOLJyYiIfF5
|
73
|
-
f9PuXImz2RDzBJQ/+u82gQAcvPhm94xK8jeNPcn0Ege7Y7SRK4YYonX+0ZveP02L
|
74
|
-
FjuEfrZcZQIDAQABoAAwDQYJKoZIhvcNAQEFBQADgYEAecOQz0RfnmSxxzOyHZ1e
|
75
|
-
Wo2hQqPOmkfIbvL2l1Ml+HybJQJn6OpLmeveyU48SI2M7UqeNkHtsogMljy3re4L
|
76
|
-
QlwK7lNd6SymdfSCPjUcdoLOaHolZXYNvCHltTc5skRHG7ti5yv4cu0ItIcCS0yp
|
77
|
-
7L3maDEbTLsDdouHeFfbLWA=
|
78
|
-
-----END CERTIFICATE REQUEST-----
|
79
|
-
CSR
|
80
|
-
@key_material = CertificateAuthority::SigningRequestKeyMaterial.new @request
|
81
|
-
end
|
82
|
-
|
83
|
-
it "should generate from a CSR" do
|
84
|
-
@key_material.should_not be_nil
|
85
|
-
end
|
86
|
-
|
87
|
-
it "should be able to expose a public key" do
|
88
|
-
@key_material.public_key.should_not be_nil
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should not have a private key" do
|
92
|
-
@key_material.private_key.should be_nil
|
93
|
-
end
|
94
|
-
|
95
|
-
it "should raise when signature does not verify" do
|
96
|
-
invalid = @request
|
97
|
-
invalid.public_key = OpenSSL::PKey::RSA.new 512
|
98
|
-
lambda { CertificateAuthority::SigningRequestKeyMaterial.new invalid }.should raise_error
|
99
|
-
end
|
100
|
-
end
|
@@ -1,104 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/units_helper'
|
2
|
-
|
3
|
-
describe CertificateAuthority::OCSPHandler do
|
4
|
-
before(:each) do
|
5
|
-
@ocsp_handler = CertificateAuthority::OCSPHandler.new
|
6
|
-
|
7
|
-
@root_certificate = CertificateAuthority::Certificate.new
|
8
|
-
@root_certificate.signing_entity = true
|
9
|
-
@root_certificate.subject.common_name = "OCSP Root"
|
10
|
-
@root_certificate.key_material.generate_key(1024)
|
11
|
-
@root_certificate.serial_number.number = 1
|
12
|
-
@root_certificate.sign!
|
13
|
-
|
14
|
-
@certificate = CertificateAuthority::Certificate.new
|
15
|
-
@certificate.key_material.generate_key(1024)
|
16
|
-
@certificate.subject.common_name = "http://questionablesite.com"
|
17
|
-
@certificate.parent = @root_certificate
|
18
|
-
@certificate.serial_number.number = 2
|
19
|
-
@certificate.sign!
|
20
|
-
|
21
|
-
@ocsp_request = OpenSSL::OCSP::Request.new
|
22
|
-
openssl_cert_issuer = OpenSSL::X509::Certificate.new(@root_certificate.to_pem)
|
23
|
-
openssl_cert_subject = OpenSSL::X509::Certificate.new(@certificate.to_pem)
|
24
|
-
|
25
|
-
cert_id = OpenSSL::OCSP::CertificateId.new(openssl_cert_subject, openssl_cert_issuer)
|
26
|
-
@ocsp_request.add_certid(cert_id)
|
27
|
-
@ocsp_handler.ocsp_request = @ocsp_request.to_der
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should be able to accept an OCSP Request" do
|
31
|
-
@ocsp_handler.ocsp_request = @ocsp_request
|
32
|
-
@ocsp_handler.ocsp_request.should_not be_nil
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should raise an error if you try and extract certificates without a raw request" do
|
36
|
-
@ocsp_handler.extract_certificate_serials
|
37
|
-
@ocsp_handler.ocsp_request = nil
|
38
|
-
lambda {@ocsp_handler.extract_certificate_serials}.should raise_error
|
39
|
-
end
|
40
|
-
|
41
|
-
it "should return a hash of extracted certificates from OCSP requests" do
|
42
|
-
result = @ocsp_handler.extract_certificate_serials
|
43
|
-
result.size.should == 1
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should be able to generate an OCSP response" do
|
47
|
-
@ocsp_handler.extract_certificate_serials
|
48
|
-
@ocsp_handler << @certificate
|
49
|
-
@ocsp_handler.parent = @root_certificate
|
50
|
-
@ocsp_handler.response
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should require a 'parent' entity for signing" do
|
54
|
-
@ocsp_handler.parent = @root_certificate
|
55
|
-
@ocsp_handler.parent.should_not be_nil
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should raise an error if you ask for the signed OCSP response without generating it" do
|
59
|
-
@ocsp_handler.extract_certificate_serials
|
60
|
-
@ocsp_handler << @certificate
|
61
|
-
@ocsp_handler.parent = @root_certificate
|
62
|
-
lambda { @ocsp_handler.to_der }.should raise_error
|
63
|
-
@ocsp_handler.response
|
64
|
-
@ocsp_handler.to_der.should_not be_nil
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should raise an error if you generate a response without adding all certificates in request" do
|
68
|
-
@ocsp_handler.extract_certificate_serials
|
69
|
-
@ocsp_handler.parent = @root_certificate
|
70
|
-
lambda { @ocsp_handler.response }.should raise_error
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should raise an error if you generate a response without adding a parent signing entity" do
|
74
|
-
@ocsp_handler.extract_certificate_serials
|
75
|
-
@ocsp_handler << @certificate
|
76
|
-
lambda { @ocsp_handler.response }.should raise_error
|
77
|
-
end
|
78
|
-
|
79
|
-
describe "Response" do
|
80
|
-
before(:each) do
|
81
|
-
@ocsp_handler.extract_certificate_serials
|
82
|
-
@ocsp_handler << @certificate
|
83
|
-
@ocsp_handler.parent = @root_certificate
|
84
|
-
@ocsp_handler.response
|
85
|
-
|
86
|
-
@openssl_ocsp_response = OpenSSL::OCSP::Response.new(@ocsp_handler.to_der)
|
87
|
-
end
|
88
|
-
|
89
|
-
it "should have a correct status/status string" do
|
90
|
-
@openssl_ocsp_response.status_string.should == "successful"
|
91
|
-
@openssl_ocsp_response.status.should == 0
|
92
|
-
end
|
93
|
-
|
94
|
-
it "should have an embedded BasicResponse with certificate statuses" do
|
95
|
-
# [#<OpenSSL::OCSP::CertificateId:0x000001020ecad8>, 0, 1, nil, 2011-04-15 23:29:47 UTC, 2011-04-15 23:30:17 UTC, []]
|
96
|
-
@openssl_ocsp_response.basic.status.first[1].should == 0 # Everything is OK
|
97
|
-
end
|
98
|
-
|
99
|
-
it "should have a next_update time" do
|
100
|
-
@openssl_ocsp_response.basic.status.first[5].should_not be_nil
|
101
|
-
@openssl_ocsp_response.basic.status.first[5].class.should == Time
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/units_helper'
|
2
|
-
|
3
|
-
## Anything that requires crypto hardware needs to be tagged as 'pkcs11'
|
4
|
-
describe CertificateAuthority::Pkcs11KeyMaterial, :pkcs11 => true do
|
5
|
-
before(:each) do
|
6
|
-
@key_material_in_hardware = CertificateAuthority::Pkcs11KeyMaterial.new
|
7
|
-
@key_material_in_hardware.token_id = "46"
|
8
|
-
@key_material_in_hardware.pkcs11_lib = "/usr/lib/libeTPkcs11.so"
|
9
|
-
@key_material_in_hardware.openssl_pkcs11_engine_lib = "/usr/lib/engines/engine_pkcs11.so"
|
10
|
-
@key_material_in_hardware.pin = "11111111"
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should identify as being in hardware", :pkcs11 => true do
|
14
|
-
@key_material_in_hardware.is_in_hardware?.should be_true
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should return a Pkey ref if the private key is requested", :pkcs11 => true do
|
18
|
-
@key_material_in_hardware.private_key.class.should == OpenSSL::PKey::RSA
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should return a Pkey ref if the public key is requested", :pkcs11 => true do
|
22
|
-
@key_material_in_hardware.public_key.class.should == OpenSSL::PKey::RSA
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should accept an ID for on-token objects", :pkcs11 => true do
|
26
|
-
@key_material_in_hardware.respond_to?(:token_id).should be_true
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should accept a path to a shared library for a PKCS11 driver", :pkcs11 => true do
|
30
|
-
@key_material_in_hardware.respond_to?(:pkcs11_lib).should be_true
|
31
|
-
end
|
32
|
-
|
33
|
-
it "should accept a path to OpenSSL's dynamic PKCS11 engine (provided by libengine-pkcs11-openssl)", :pkcs11 => true do
|
34
|
-
@key_material_in_hardware.respond_to?(:openssl_pkcs11_engine_lib).should be_true
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should accept an optional PIN to authenticate to the token", :pkcs11 => true do
|
38
|
-
@key_material_in_hardware.respond_to?(:pin).should be_true
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/units_helper'
|
2
|
-
|
3
|
-
describe CertificateAuthority::SerialNumber do
|
4
|
-
before(:each) do
|
5
|
-
@serial_number = CertificateAuthority::SerialNumber.new
|
6
|
-
end
|
7
|
-
|
8
|
-
it "should support basic integer serial numbers", :rfc3280 => true do
|
9
|
-
@serial_number.number = 25
|
10
|
-
@serial_number.should be_valid
|
11
|
-
@serial_number.number = "abc"
|
12
|
-
@serial_number.should_not be_valid
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should not allow negative serial numbers", :rfc3280 => true do
|
16
|
-
@serial_number.number = -5
|
17
|
-
@serial_number.should_not be_valid
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
data/spec/units/units_helper.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper'
|