r509 0.8
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 +447 -0
- data/Rakefile +38 -0
- data/bin/r509 +96 -0
- data/bin/r509-parse +35 -0
- data/doc/R509.html +154 -0
- data/doc/R509/Cert.html +3954 -0
- data/doc/R509/Cert/Extensions.html +360 -0
- data/doc/R509/Cert/Extensions/AuthorityInfoAccess.html +391 -0
- data/doc/R509/Cert/Extensions/AuthorityKeyIdentifier.html +148 -0
- data/doc/R509/Cert/Extensions/BasicConstraints.html +482 -0
- data/doc/R509/Cert/Extensions/CrlDistributionPoints.html +316 -0
- data/doc/R509/Cert/Extensions/ExtendedKeyUsage.html +780 -0
- data/doc/R509/Cert/Extensions/KeyUsage.html +1230 -0
- data/doc/R509/Cert/Extensions/SubjectAlternativeName.html +467 -0
- data/doc/R509/Cert/Extensions/SubjectKeyIdentifier.html +216 -0
- data/doc/R509/CertificateAuthority.html +126 -0
- data/doc/R509/CertificateAuthority/Signer.html +855 -0
- data/doc/R509/Config.html +127 -0
- data/doc/R509/Config/CaConfig.html +2144 -0
- data/doc/R509/Config/CaConfigPool.html +599 -0
- data/doc/R509/Config/CaProfile.html +656 -0
- data/doc/R509/Config/SubjectItemPolicy.html +578 -0
- data/doc/R509/Crl.html +126 -0
- data/doc/R509/Crl/Administrator.html +2077 -0
- data/doc/R509/Crl/Parser.html +1224 -0
- data/doc/R509/Csr.html +2248 -0
- data/doc/R509/IOHelpers.html +564 -0
- data/doc/R509/MessageDigest.html +396 -0
- data/doc/R509/NameSanitizer.html +319 -0
- data/doc/R509/Ocsp.html +128 -0
- data/doc/R509/Ocsp/Request.html +126 -0
- data/doc/R509/Ocsp/Request/Nonce.html +160 -0
- data/doc/R509/Ocsp/Response.html +837 -0
- data/doc/R509/OidMapper.html +393 -0
- data/doc/R509/PrivateKey.html +1647 -0
- data/doc/R509/R509Error.html +134 -0
- data/doc/R509/Spki.html +1424 -0
- data/doc/R509/Subject.html +836 -0
- data/doc/R509/Validity.html +160 -0
- data/doc/R509/Validity/Checker.html +320 -0
- data/doc/R509/Validity/DefaultChecker.html +283 -0
- data/doc/R509/Validity/DefaultWriter.html +330 -0
- data/doc/R509/Validity/Status.html +561 -0
- data/doc/R509/Validity/Writer.html +394 -0
- data/doc/_index.html +501 -0
- data/doc/class_list.html +53 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +328 -0
- data/doc/file.README.html +534 -0
- data/doc/file.r509.html +149 -0
- data/doc/file_list.html +58 -0
- data/doc/frames.html +28 -0
- data/doc/index.html +534 -0
- data/doc/js/app.js +208 -0
- data/doc/js/full_list.js +173 -0
- data/doc/js/jquery.js +4 -0
- data/doc/methods_list.html +1932 -0
- data/doc/top-level-namespace.html +112 -0
- data/lib/r509.rb +22 -0
- data/lib/r509/cert.rb +414 -0
- data/lib/r509/cert/extensions.rb +309 -0
- data/lib/r509/certificateauthority.rb +290 -0
- data/lib/r509/config.rb +407 -0
- data/lib/r509/crl.rb +379 -0
- data/lib/r509/csr.rb +324 -0
- data/lib/r509/exceptions.rb +5 -0
- data/lib/r509/io_helpers.rb +52 -0
- data/lib/r509/messagedigest.rb +49 -0
- data/lib/r509/ocsp.rb +85 -0
- data/lib/r509/oidmapper.rb +32 -0
- data/lib/r509/privatekey.rb +185 -0
- data/lib/r509/spki.rb +112 -0
- data/lib/r509/subject.rb +133 -0
- data/lib/r509/validity.rb +92 -0
- data/lib/r509/version.rb +4 -0
- data/r509.yaml +73 -0
- data/spec/cert/extensions_spec.rb +632 -0
- data/spec/cert_spec.rb +321 -0
- data/spec/certificate_authority_spec.rb +260 -0
- data/spec/config_spec.rb +349 -0
- data/spec/crl_spec.rb +215 -0
- data/spec/csr_spec.rb +302 -0
- data/spec/fixtures.rb +233 -0
- data/spec/fixtures/cert1.der +0 -0
- data/spec/fixtures/cert1.pem +24 -0
- data/spec/fixtures/cert1_public_key_modulus.txt +1 -0
- data/spec/fixtures/cert3.p12 +0 -0
- data/spec/fixtures/cert3.pem +28 -0
- data/spec/fixtures/cert3_key.pem +27 -0
- data/spec/fixtures/cert3_key_des3.pem +30 -0
- data/spec/fixtures/cert4.pem +14 -0
- data/spec/fixtures/cert5.pem +30 -0
- data/spec/fixtures/cert6.pem +26 -0
- data/spec/fixtures/cert_expired.pem +26 -0
- data/spec/fixtures/cert_not_yet_valid.pem +26 -0
- data/spec/fixtures/cert_san.pem +27 -0
- data/spec/fixtures/cert_san2.pem +22 -0
- data/spec/fixtures/config_pool_test_minimal.yaml +15 -0
- data/spec/fixtures/config_test.yaml +41 -0
- data/spec/fixtures/config_test_engine_key.yaml +7 -0
- data/spec/fixtures/config_test_engine_no_key_name.yaml +6 -0
- data/spec/fixtures/config_test_minimal.yaml +7 -0
- data/spec/fixtures/config_test_password.yaml +7 -0
- data/spec/fixtures/config_test_various.yaml +100 -0
- data/spec/fixtures/crl_list_file.txt +1 -0
- data/spec/fixtures/crl_with_reason.pem +17 -0
- data/spec/fixtures/csr1.der +0 -0
- data/spec/fixtures/csr1.pem +17 -0
- data/spec/fixtures/csr1_key.der +0 -0
- data/spec/fixtures/csr1_key.pem +27 -0
- data/spec/fixtures/csr1_key_encrypted_des3.pem +30 -0
- data/spec/fixtures/csr1_newlines.pem +32 -0
- data/spec/fixtures/csr1_no_begin_end.pem +15 -0
- data/spec/fixtures/csr1_public_key_modulus.txt +1 -0
- data/spec/fixtures/csr2.pem +15 -0
- data/spec/fixtures/csr2_key.pem +27 -0
- data/spec/fixtures/csr3.pem +16 -0
- data/spec/fixtures/csr4.pem +25 -0
- data/spec/fixtures/csr_dsa.pem +15 -0
- data/spec/fixtures/csr_invalid_signature.pem +13 -0
- data/spec/fixtures/dsa_key.pem +20 -0
- data/spec/fixtures/key4.pem +27 -0
- data/spec/fixtures/key4_encrypted_des3.pem +30 -0
- data/spec/fixtures/missing_key_identifier_ca.cer +21 -0
- data/spec/fixtures/missing_key_identifier_ca.key +27 -0
- data/spec/fixtures/ocsptest.r509.local.pem +27 -0
- data/spec/fixtures/ocsptest.r509.local_ocsp_request.der +0 -0
- data/spec/fixtures/ocsptest2.r509.local.pem +27 -0
- data/spec/fixtures/second_ca.cer +26 -0
- data/spec/fixtures/second_ca.key +27 -0
- data/spec/fixtures/spkac.der +0 -0
- data/spec/fixtures/spkac.txt +1 -0
- data/spec/fixtures/spkac_dsa.txt +1 -0
- data/spec/fixtures/stca.pem +22 -0
- data/spec/fixtures/stca_ocsp_request.der +0 -0
- data/spec/fixtures/stca_ocsp_response.der +0 -0
- data/spec/fixtures/test1.csr +17 -0
- data/spec/fixtures/test_ca.cer +22 -0
- data/spec/fixtures/test_ca.key +28 -0
- data/spec/fixtures/test_ca.p12 +0 -0
- data/spec/fixtures/test_ca_des3.key +30 -0
- data/spec/fixtures/test_ca_ocsp.cer +26 -0
- data/spec/fixtures/test_ca_ocsp.key +27 -0
- data/spec/fixtures/test_ca_ocsp.p12 +0 -0
- data/spec/fixtures/test_ca_ocsp_chain.txt +48 -0
- data/spec/fixtures/test_ca_ocsp_response.der +0 -0
- data/spec/fixtures/test_ca_subroot.cer +26 -0
- data/spec/fixtures/test_ca_subroot.key +27 -0
- data/spec/fixtures/test_ca_subroot_ocsp.cer +25 -0
- data/spec/fixtures/test_ca_subroot_ocsp.key +27 -0
- data/spec/fixtures/test_ca_subroot_ocsp_response.der +0 -0
- data/spec/fixtures/unknown_oid.csr +17 -0
- data/spec/message_digest_spec.rb +89 -0
- data/spec/ocsp_spec.rb +111 -0
- data/spec/oid_mapper_spec.rb +31 -0
- data/spec/privatekey_spec.rb +198 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/spki_spec.rb +157 -0
- data/spec/subject_spec.rb +203 -0
- data/spec/validity_spec.rb +98 -0
- metadata +257 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
|
|
3
|
+
#Module for holding classes for writing and reading certificate validity information (used for serving OCSP responses)
|
|
4
|
+
module R509::Validity
|
|
5
|
+
#mapping from OpenSSL
|
|
6
|
+
VALID = OpenSSL::OCSP::V_CERTSTATUS_GOOD
|
|
7
|
+
REVOKED = OpenSSL::OCSP::V_CERTSTATUS_REVOKED
|
|
8
|
+
UNKNOWN = OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
|
|
9
|
+
|
|
10
|
+
#data about the status of a certificate
|
|
11
|
+
class Status
|
|
12
|
+
attr_reader :status, :revocation_time, :revocation_reason
|
|
13
|
+
|
|
14
|
+
def initialize(options={})
|
|
15
|
+
@status = options[:status]
|
|
16
|
+
@revocation_time = options[:revocation_time] || nil
|
|
17
|
+
@revocation_reason = options[:revocation_reason] || 0
|
|
18
|
+
|
|
19
|
+
if (@status == R509::Validity::REVOKED and @revocation_time.nil?)
|
|
20
|
+
@revocation_time = Time.now.to_i
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @return [OpenSSL::OCSP::STATUS] OpenSSL status constants when passing R509 constants
|
|
25
|
+
def ocsp_status
|
|
26
|
+
case @status
|
|
27
|
+
when R509::Validity::VALID
|
|
28
|
+
OpenSSL::OCSP::V_CERTSTATUS_GOOD
|
|
29
|
+
when R509::Validity::REVOKED
|
|
30
|
+
OpenSSL::OCSP::V_CERTSTATUS_REVOKED
|
|
31
|
+
when R509::Validity::UNKNOWN
|
|
32
|
+
OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
|
|
33
|
+
else
|
|
34
|
+
OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
#abstract base class for a Writer
|
|
40
|
+
class Writer
|
|
41
|
+
def issue(issuer, serial)
|
|
42
|
+
raise NotImplementedError, "You must call #issue on a subclass of Writer"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def revoke(issuer, serial, reason)
|
|
46
|
+
raise NotImplementedError, "You must call #revoke on a subclass of Writer"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# is_available? is meant to be implemented to check if the backend store you choose to implement is currently working.
|
|
50
|
+
# see r509-ocsp-responder and r509-validity-redis for an example of use
|
|
51
|
+
def is_available?
|
|
52
|
+
raise NotImplementedError, "You must call #is_available? on a subclass of Writer"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
#abstract base class for a Checker
|
|
57
|
+
class Checker
|
|
58
|
+
def check(issuer, serial)
|
|
59
|
+
raise NotImplementedError, "You must call #check on a subclass of Checker"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# is_available? is meant to be implemented to check if the backend store you choose to implement is currently working.
|
|
63
|
+
# see r509-ocsp-responder and r509-validity-redis for an example of use
|
|
64
|
+
def is_available?
|
|
65
|
+
raise NotImplementedError, "You must call #is_available? on a subclass of Checker"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
#default implementaton of the Checker class. Used for tests. DO NOT USE OTHERWISE
|
|
70
|
+
class DefaultChecker < R509::Validity::Checker
|
|
71
|
+
def check(issuer, serial)
|
|
72
|
+
R509::Validity::Status.new(:status => R509::Validity::VALID)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def is_available?
|
|
76
|
+
true
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
#default implementaton of the Writer class. Does nothing (obviously)
|
|
81
|
+
class DefaultWriter < R509::Validity::Writer
|
|
82
|
+
def issue(issuer, serial)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def revoke(issuer, serial, reason)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def is_available?
|
|
89
|
+
true
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
data/lib/r509/version.rb
ADDED
data/r509.yaml
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
certificate_authorities: {
|
|
2
|
+
test_ca: {
|
|
3
|
+
ca_cert: {
|
|
4
|
+
cert: 'spec/fixtures/test_ca.cer',
|
|
5
|
+
key: 'spec/fixtures/test_ca.key'
|
|
6
|
+
},
|
|
7
|
+
ocsp_cert: {
|
|
8
|
+
:pkcs12: 'spec/fixtures/test_ca_ocsp.p12',
|
|
9
|
+
:password: 'r509'
|
|
10
|
+
},
|
|
11
|
+
ocsp_location: 'URI:http://ocsp.domain.com',
|
|
12
|
+
ocsp_chain: 'spec/fixtures/test_ca_ocsp_chain.txt',
|
|
13
|
+
ocsp_start_skew_seconds: 3600,
|
|
14
|
+
ocsp_validity_hours: 168,
|
|
15
|
+
cdp_location: 'URI:http://crl.domain.com/test_ca.crl',
|
|
16
|
+
crl_list: 'spec/fixtures/test_ca_crl_list.txt',
|
|
17
|
+
crl_number: 'spec/fixtures/test_ca_crl_number.txt',
|
|
18
|
+
crl_validity_hours: 168, #7 days
|
|
19
|
+
message_digest: 'SHA1', #SHA1, SHA256, SHA512 supported. MD5 too, but you really shouldn't use that unless you have a good reason
|
|
20
|
+
profiles: {
|
|
21
|
+
server: {
|
|
22
|
+
basic_constraints: "CA:FALSE",
|
|
23
|
+
key_usage: [digitalSignature,keyEncipherment],
|
|
24
|
+
extended_key_usage: [serverAuth],
|
|
25
|
+
certificate_policies: [ [ "policyIdentifier=2.16.840.1.9999999999.1.2.3.4.1", "CPS.1=http://example.com/cps"] ],
|
|
26
|
+
subject_item_policy: {
|
|
27
|
+
CN: "required",
|
|
28
|
+
O: "required",
|
|
29
|
+
OU: "optional",
|
|
30
|
+
ST: "required",
|
|
31
|
+
C: "required",
|
|
32
|
+
L: "required"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
client: {
|
|
36
|
+
basic_constraints: "CA:FALSE",
|
|
37
|
+
key_usage: [digitalSignature,keyEncipherment],
|
|
38
|
+
extended_key_usage: [clientAuth],
|
|
39
|
+
certificate_policies: [ [ "policyIdentifier=2.16.840.1.9999999999.1.2.3.4.2", "CPS.1=http://example.com/cps"] ]
|
|
40
|
+
},
|
|
41
|
+
email: {
|
|
42
|
+
basic_constraints: "CA:FALSE",
|
|
43
|
+
key_usage: [digitalSignature,keyEncipherment],
|
|
44
|
+
extended_key_usage: [emailProtection],
|
|
45
|
+
certificate_policies: [ [ "policyIdentifier=2.16.840.1.9999999999.1.2.3.4.3", "CPS.1=http://example.com/cps"] ]
|
|
46
|
+
},
|
|
47
|
+
clientserver: {
|
|
48
|
+
basic_constraints: "CA:FALSE",
|
|
49
|
+
key_usage: [digitalSignature,keyEncipherment],
|
|
50
|
+
extended_key_usage: [serverAuth,clientAuth],
|
|
51
|
+
certificate_policies: [ [ "policyIdentifier=2.16.840.1.9999999999.1.2.3.4.4", "CPS.1=http://example.com/cps"] ]
|
|
52
|
+
},
|
|
53
|
+
codesigning: {
|
|
54
|
+
basic_constraints: "CA:FALSE",
|
|
55
|
+
key_usage: [digitalSignature],
|
|
56
|
+
extended_key_usage: [codeSigning],
|
|
57
|
+
certificate_policies: [ [ "policyIdentifier=2.16.840.1.9999999999.1.2.3.4.5", "CPS.1=http://example.com/cps"] ]
|
|
58
|
+
},
|
|
59
|
+
timestamping: {
|
|
60
|
+
basic_constraints: "CA:FALSE",
|
|
61
|
+
key_usage: [digitalSignature],
|
|
62
|
+
extended_key_usage: [timeStamping],
|
|
63
|
+
certificate_policies: [ [ "policyIdentifier=2.16.840.1.9999999999.1.2.3.4.6", "CPS.1=http://example.com/cps"] ]
|
|
64
|
+
},
|
|
65
|
+
subroot: {
|
|
66
|
+
basic_constraints: "CA:TRUE,pathlen:0",
|
|
67
|
+
key_usage: [keyCertSign,cRLSign],
|
|
68
|
+
extended_key_usage: [],
|
|
69
|
+
certificate_policies: [ ]
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
include R509::Cert::Extensions
|
|
4
|
+
|
|
5
|
+
shared_examples_for "a correctly implemented wrap_openssl_extensions" do
|
|
6
|
+
before :each do
|
|
7
|
+
@r509_extensions = R509::Cert::Extensions.wrap_openssl_extensions( @openssl_extensions )
|
|
8
|
+
|
|
9
|
+
@r509_classes = [ BasicConstraints, KeyUsage, ExtendedKeyUsage,
|
|
10
|
+
SubjectKeyIdentifier, AuthorityKeyIdentifier,
|
|
11
|
+
SubjectAlternativeName, AuthorityInfoAccess,
|
|
12
|
+
CrlDistributionPoints ]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should not have returned values that aren't R509 extensions" do
|
|
16
|
+
classes = @r509_extensions.values.map { |ext| ext.class }
|
|
17
|
+
non_r509_classes = classes.reject { |ext_class| @r509_classes.include?(ext_class) }
|
|
18
|
+
non_r509_classes.should == []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should have returned the right number of extensions" do
|
|
22
|
+
@r509_extensions.count.should == @wrappable_extensions.count
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should not have returned keys improperly mapped to values" do
|
|
26
|
+
incorrect_mappings = @r509_extensions.select { |key_class,ext| ext.class != key_class }
|
|
27
|
+
incorrect_mappings = {} if incorrect_mappings == [] # compatibility for old versions of Ruby
|
|
28
|
+
incorrect_mappings.should == {}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should not have failed to map an implemented extension" do
|
|
32
|
+
missing_extensions = []
|
|
33
|
+
@wrappable_extensions.each do |openssl_ext|
|
|
34
|
+
if (@r509_extensions.select {|r509_class,r509_ext| r509_ext.oid == openssl_ext.oid}) == {}
|
|
35
|
+
missing_extensions << openssl_ext.oid
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
missing_extensions.should == []
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
shared_examples_for "a correctly implemented get_unknown_extensions" do
|
|
44
|
+
it "should not have returned values that are R509 extensions" do
|
|
45
|
+
R509::Cert::Extensions.get_unknown_extensions( @openssl_extensions ).should == @unknown_extensions
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
shared_examples_for "a correct R509 BasicConstraints object" do
|
|
50
|
+
before :all do
|
|
51
|
+
extension_name = "basicConstraints"
|
|
52
|
+
klass = BasicConstraints
|
|
53
|
+
openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
|
|
54
|
+
@r509_ext = klass.new( openssl_ext )
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "is_ca? should correctly report whether it's a CA certificate" do
|
|
58
|
+
@r509_ext.is_ca?.should == @is_ca
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "the path length should be correct" do
|
|
62
|
+
@r509_ext.path_length.should == @pathlen
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "allows_sub_ca? should correctly report whether its path length allows it to issue CA certs" do
|
|
66
|
+
@r509_ext.allows_sub_ca?.should == @allows_sub_ca
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
shared_examples_for "a correct R509 KeyUsage object" do
|
|
71
|
+
before :all do
|
|
72
|
+
extension_name = "keyUsage"
|
|
73
|
+
klass = KeyUsage
|
|
74
|
+
openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
|
|
75
|
+
@r509_ext = klass.new( openssl_ext )
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "allowed_uses should be non-nil" do
|
|
79
|
+
@r509_ext.allowed_uses.should_not == nil
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "allowed_uses should be correct" do
|
|
83
|
+
@r509_ext.allowed_uses.should == @allowed_uses
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "the individual allowed-use functions should be correct" do
|
|
87
|
+
@r509_ext.digital_signature?.should == @allowed_uses.include?( KeyUsage::AU_DIGITAL_SIGNATURE )
|
|
88
|
+
@r509_ext.non_repudiation?.should == @allowed_uses.include?( KeyUsage::AU_NON_REPUDIATION )
|
|
89
|
+
@r509_ext.key_encipherment?.should == @allowed_uses.include?( KeyUsage::AU_KEY_ENCIPHERMENT )
|
|
90
|
+
@r509_ext.data_encipherment?.should == @allowed_uses.include?( KeyUsage::AU_DATA_ENCIPHERMENT )
|
|
91
|
+
@r509_ext.key_agreement?.should == @allowed_uses.include?( KeyUsage::AU_KEY_AGREEMENT )
|
|
92
|
+
@r509_ext.certificate_sign?.should == @allowed_uses.include?( KeyUsage::AU_CERTIFICATE_SIGN )
|
|
93
|
+
@r509_ext.crl_sign?.should == @allowed_uses.include?( KeyUsage::AU_CRL_SIGN )
|
|
94
|
+
@r509_ext.encipher_only?.should == @allowed_uses.include?( KeyUsage::AU_ENCIPHER_ONLY )
|
|
95
|
+
@r509_ext.decipher_only?.should == @allowed_uses.include?( KeyUsage::AU_DECIPHER_ONLY )
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
shared_examples_for "a correct R509 ExtendedKeyUsage object" do
|
|
100
|
+
before :all do
|
|
101
|
+
extension_name = "extendedKeyUsage"
|
|
102
|
+
klass = ExtendedKeyUsage
|
|
103
|
+
openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
|
|
104
|
+
@r509_ext = klass.new( openssl_ext )
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "allowed_uses should be non-nil" do
|
|
108
|
+
@r509_ext.allowed_uses.should_not == nil
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "allowed_uses should be correct" do
|
|
112
|
+
@r509_ext.allowed_uses.should == @allowed_uses
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "the individual allowed-use functions should be correct" do
|
|
116
|
+
@r509_ext.web_server_authentication?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_WEB_SERVER_AUTH )
|
|
117
|
+
@r509_ext.web_client_authentication?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_WEB_CLIENT_AUTH )
|
|
118
|
+
@r509_ext.code_signing?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_CODE_SIGNING )
|
|
119
|
+
@r509_ext.email_protection?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_EMAIL_PROTECTION )
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
shared_examples_for "a correct R509 SubjectKeyIdentifier object" do
|
|
124
|
+
before :all do
|
|
125
|
+
extension_name = "subjectKeyIdentifier"
|
|
126
|
+
klass = SubjectKeyIdentifier
|
|
127
|
+
openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
|
|
128
|
+
@r509_ext = klass.new( openssl_ext )
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "key should be correct" do
|
|
132
|
+
@r509_ext.key.should == @key
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
shared_examples_for "a correct R509 AuthorityKeyIdentifier object" do
|
|
137
|
+
before :all do
|
|
138
|
+
extension_name = "authorityKeyIdentifier"
|
|
139
|
+
klass = AuthorityKeyIdentifier
|
|
140
|
+
openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
|
|
141
|
+
@r509_ext = klass.new( openssl_ext )
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
#TODO
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
shared_examples_for "a correct R509 SubjectAlternativeName object" do
|
|
148
|
+
before :all do
|
|
149
|
+
extension_name = "subjectAltName"
|
|
150
|
+
klass = SubjectAlternativeName
|
|
151
|
+
openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
|
|
152
|
+
@r509_ext = klass.new( openssl_ext )
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "dns_names should be correct" do
|
|
156
|
+
@r509_ext.dns_names.should == @dns_names
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "ip_addresses should be correct" do
|
|
160
|
+
@r509_ext.ip_addresses.should == @ip_addresses
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it "uris should be correct" do
|
|
164
|
+
@r509_ext.uris.should == @uris
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
shared_examples_for "a correct R509 AuthorityInfoAccess object" do
|
|
169
|
+
before :all do
|
|
170
|
+
extension_name = "authorityInfoAccess"
|
|
171
|
+
klass = AuthorityInfoAccess
|
|
172
|
+
openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
|
|
173
|
+
@r509_ext = klass.new( openssl_ext )
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "ca_issuers_uri should be correct" do
|
|
177
|
+
@r509_ext.ca_issuers_uris.should == @ca_issuers_uris
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "ocsp_uri should be correct" do
|
|
181
|
+
@r509_ext.ocsp_uris.should == @ocsp_uris
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
shared_examples_for "a correct R509 CrlDistributionPoints object" do
|
|
186
|
+
before :all do
|
|
187
|
+
extension_name = "crlDistributionPoints"
|
|
188
|
+
klass = CrlDistributionPoints
|
|
189
|
+
openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
|
|
190
|
+
@r509_ext = klass.new( openssl_ext )
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "crl_uri should be correct" do
|
|
194
|
+
@r509_ext.crl_uris.should == @crl_uris
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
describe R509::Cert::Extensions do
|
|
200
|
+
include R509::Cert::Extensions
|
|
201
|
+
|
|
202
|
+
context "Class functions" do
|
|
203
|
+
context "#wrap_openssl_extensions and #get_unknown_extensions" do
|
|
204
|
+
context "with no extensions" do
|
|
205
|
+
before :each do
|
|
206
|
+
@wrappable_extensions = []
|
|
207
|
+
@unknown_extensions = []
|
|
208
|
+
|
|
209
|
+
@openssl_extensions = @wrappable_extensions + @unknown_extensions
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it_should_behave_like "a correctly implemented wrap_openssl_extensions"
|
|
213
|
+
it_should_behave_like "a correctly implemented get_unknown_extensions"
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
context "with one implemented extension" do
|
|
217
|
+
before :each do
|
|
218
|
+
@wrappable_extensions = []
|
|
219
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
|
|
220
|
+
|
|
221
|
+
@unknown_extensions = []
|
|
222
|
+
|
|
223
|
+
@openssl_extensions = @wrappable_extensions + @unknown_extensions
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it_should_behave_like "a correctly implemented wrap_openssl_extensions"
|
|
227
|
+
it_should_behave_like "a correctly implemented get_unknown_extensions"
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
context "with all implemented extensions" do
|
|
231
|
+
before :each do
|
|
232
|
+
@wrappable_extensions = []
|
|
233
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
|
|
234
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "keyUsage", KeyUsage::AU_DIGITAL_SIGNATURE )
|
|
235
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "extendedKeyUsage", ExtendedKeyUsage::AU_WEB_SERVER_AUTH )
|
|
236
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "subjectKeyIdentifier", "00:11:22:33:44:55:66:77:88:99:00:AA:BB:CC:DD:EE:FF:00:11:22" )
|
|
237
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "authorityKeyIdentifier", "keyid:always" )
|
|
238
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "subjectAltName", "DNS:www.test.local" )
|
|
239
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "authorityInfoAccess", "CA Issuers - URI:http://www.test.local" )
|
|
240
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "crlDistributionPoints", "URI:http://www.test.local" )
|
|
241
|
+
|
|
242
|
+
@unknown_extensions = []
|
|
243
|
+
|
|
244
|
+
@openssl_extensions = @wrappable_extensions + @unknown_extensions
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
it_should_behave_like "a correctly implemented wrap_openssl_extensions"
|
|
248
|
+
it_should_behave_like "a correctly implemented get_unknown_extensions"
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
context "with an unimplemented extension" do
|
|
252
|
+
before :each do
|
|
253
|
+
@wrappable_extensions = []
|
|
254
|
+
|
|
255
|
+
@unknown_extensions = []
|
|
256
|
+
@unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
|
|
257
|
+
|
|
258
|
+
@openssl_extensions = @wrappable_extensions + @unknown_extensions
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it_should_behave_like "a correctly implemented wrap_openssl_extensions"
|
|
262
|
+
it_should_behave_like "a correctly implemented get_unknown_extensions"
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
context "with implemented and unimplemented extensions" do
|
|
266
|
+
before :each do
|
|
267
|
+
@wrappable_extensions = []
|
|
268
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
|
|
269
|
+
|
|
270
|
+
@unknown_extensions = []
|
|
271
|
+
@unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
|
|
272
|
+
|
|
273
|
+
@openssl_extensions = @wrappable_extensions + @unknown_extensions
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it_should_behave_like "a correctly implemented wrap_openssl_extensions"
|
|
277
|
+
it_should_behave_like "a correctly implemented get_unknown_extensions"
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
context "with multiple extensions of an implemented type" do
|
|
281
|
+
before :each do
|
|
282
|
+
@wrappable_extensions = []
|
|
283
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
|
|
284
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:1" )
|
|
285
|
+
|
|
286
|
+
@unknown_extensions = []
|
|
287
|
+
@unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
|
|
288
|
+
|
|
289
|
+
@openssl_extensions = @wrappable_extensions + @unknown_extensions
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
it "should raise an ArgumentError for #wrap_openssl_extensions" do
|
|
293
|
+
expect {
|
|
294
|
+
R509::Cert::Extensions.wrap_openssl_extensions( @openssl_extensions )
|
|
295
|
+
}.to raise_error(ArgumentError)
|
|
296
|
+
end
|
|
297
|
+
it_should_behave_like "a correctly implemented get_unknown_extensions"
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
context "with multiple extensions of an unimplemented type" do
|
|
301
|
+
before :each do
|
|
302
|
+
@wrappable_extensions = []
|
|
303
|
+
@wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
|
|
304
|
+
|
|
305
|
+
@unknown_extensions = []
|
|
306
|
+
@unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
|
|
307
|
+
@unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www2.test.local" )
|
|
308
|
+
|
|
309
|
+
@openssl_extensions = @wrappable_extensions + @unknown_extensions
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
it_should_behave_like "a correctly implemented wrap_openssl_extensions"
|
|
313
|
+
it_should_behave_like "a correctly implemented get_unknown_extensions"
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
context "BasicConstraints" do
|
|
319
|
+
context "with constraints for a CA certificate" do
|
|
320
|
+
before :all do
|
|
321
|
+
@extension_value = "CA:TRUE;pathlen:1"
|
|
322
|
+
@is_ca = true
|
|
323
|
+
@pathlen = 1
|
|
324
|
+
@allows_sub_ca = true
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
it_should_behave_like "a correct R509 BasicConstraints object"
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
context "with constraints for a sub-CA certificate" do
|
|
331
|
+
before :all do
|
|
332
|
+
@extension_value = "CA:TRUE;pathlen:0"
|
|
333
|
+
@is_ca = true
|
|
334
|
+
@pathlen = 0
|
|
335
|
+
@allows_sub_ca = false
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
it_should_behave_like "a correct R509 BasicConstraints object"
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
context "with constraints for a non-CA certificate" do
|
|
342
|
+
before :all do
|
|
343
|
+
@extension_value = "CA:FALSE"
|
|
344
|
+
@is_ca = false
|
|
345
|
+
@pathlen = nil
|
|
346
|
+
@allows_sub_ca = false
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
it_should_behave_like "a correct R509 BasicConstraints object"
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
context "KeyUsage" do
|
|
354
|
+
context "with one allowed use" do
|
|
355
|
+
before :all do
|
|
356
|
+
@allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE ]
|
|
357
|
+
@extension_value = @allowed_uses.join( ", " )
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
it_should_behave_like "a correct R509 KeyUsage object"
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
context "with some allowed uses" do
|
|
364
|
+
before :all do
|
|
365
|
+
# this spec and the one below alternate the uses
|
|
366
|
+
@allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE, KeyUsage::AU_KEY_ENCIPHERMENT, KeyUsage::AU_KEY_AGREEMENT, KeyUsage::AU_CRL_SIGN, KeyUsage::AU_DECIPHER_ONLY ]
|
|
367
|
+
@extension_value = @allowed_uses.join( ", " )
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
it_should_behave_like "a correct R509 KeyUsage object"
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
context "with some different allowed uses" do
|
|
374
|
+
before :all do
|
|
375
|
+
@allowed_uses = [ KeyUsage::AU_NON_REPUDIATION, KeyUsage::AU_DATA_ENCIPHERMENT, KeyUsage::AU_CERTIFICATE_SIGN, KeyUsage::AU_ENCIPHER_ONLY ]
|
|
376
|
+
@extension_value = @allowed_uses.join( ", " )
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
it_should_behave_like "a correct R509 KeyUsage object"
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
context "with all allowed uses" do
|
|
383
|
+
before :all do
|
|
384
|
+
@allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE, KeyUsage::AU_KEY_ENCIPHERMENT,
|
|
385
|
+
KeyUsage::AU_KEY_AGREEMENT, KeyUsage::AU_CRL_SIGN, KeyUsage::AU_DECIPHER_ONLY,
|
|
386
|
+
KeyUsage::AU_NON_REPUDIATION, KeyUsage::AU_DATA_ENCIPHERMENT,
|
|
387
|
+
KeyUsage::AU_CERTIFICATE_SIGN, KeyUsage::AU_ENCIPHER_ONLY ]
|
|
388
|
+
@extension_value = @allowed_uses.join( ", " )
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
it_should_behave_like "a correct R509 KeyUsage object"
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
context "ExtendedKeyUsage" do
|
|
396
|
+
context "with one allowed use" do
|
|
397
|
+
before :all do
|
|
398
|
+
@allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH ]
|
|
399
|
+
@extension_value = @allowed_uses.join( ", " )
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
it_should_behave_like "a correct R509 ExtendedKeyUsage object"
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
context "with some allowed uses" do
|
|
406
|
+
before :all do
|
|
407
|
+
# this spec and the one below alternate the uses
|
|
408
|
+
@allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH, ExtendedKeyUsage::AU_CODE_SIGNING ]
|
|
409
|
+
@extension_value = @allowed_uses.join( ", " )
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
it_should_behave_like "a correct R509 ExtendedKeyUsage object"
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
context "with some different allowed uses" do
|
|
416
|
+
before :all do
|
|
417
|
+
@allowed_uses = [ ExtendedKeyUsage::AU_WEB_CLIENT_AUTH, ExtendedKeyUsage::AU_EMAIL_PROTECTION ]
|
|
418
|
+
@extension_value = @allowed_uses.join( ", " )
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
it_should_behave_like "a correct R509 ExtendedKeyUsage object"
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
context "with all allowed uses" do
|
|
425
|
+
before :all do
|
|
426
|
+
@allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH, ExtendedKeyUsage::AU_CODE_SIGNING,
|
|
427
|
+
ExtendedKeyUsage::AU_WEB_CLIENT_AUTH, ExtendedKeyUsage::AU_EMAIL_PROTECTION ]
|
|
428
|
+
@extension_value = @allowed_uses.join( ", " )
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
it_should_behave_like "a correct R509 ExtendedKeyUsage object"
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
context "SubjectKeyIdentifier" do
|
|
436
|
+
before :all do
|
|
437
|
+
@extension_value = "00:11:22:33:44:55:66:77:88:99:00:AA:BB:CC:DD:EE:FF:00:11:22"
|
|
438
|
+
@key = @extension_value
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
it_should_behave_like "a correct R509 SubjectKeyIdentifier object"
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
context "AuthorityKeyIdentifier" do
|
|
445
|
+
before :all do
|
|
446
|
+
@extension_value = "keyid:always"
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
it_should_behave_like "a correct R509 AuthorityKeyIdentifier object"
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
context "SubjectAlternativeName" do
|
|
453
|
+
context "with a DNS alternative name only" do
|
|
454
|
+
before :all do
|
|
455
|
+
@dns_names = ["www.test.local"]
|
|
456
|
+
@ip_addresses = []
|
|
457
|
+
@uris = []
|
|
458
|
+
@extension_value = "DNS:#{@dns_names.join(",DNS:")}"
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
it_should_behave_like "a correct R509 SubjectAlternativeName object"
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
context "with multiple DNS alternative names only" do
|
|
465
|
+
before :all do
|
|
466
|
+
@dns_names = ["www.test.local", "www2.test.local"]
|
|
467
|
+
@ip_addresses = []
|
|
468
|
+
@uris = []
|
|
469
|
+
@extension_value = "DNS:#{@dns_names.join(",DNS:")}"
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
it_should_behave_like "a correct R509 SubjectAlternativeName object"
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
context "with an IP address alternative name only" do
|
|
476
|
+
before :all do
|
|
477
|
+
@dns_names = []
|
|
478
|
+
@ip_addresses = ["10.1.2.3"]
|
|
479
|
+
@uris = []
|
|
480
|
+
@extension_value = "IP:#{@ip_addresses.join(",IP:")}"
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
it_should_behave_like "a correct R509 SubjectAlternativeName object"
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
context "with multiple IP address alternative names only" do
|
|
487
|
+
before :all do
|
|
488
|
+
@dns_names = []
|
|
489
|
+
@ip_addresses = ["10.1.2.3", "10.1.2.4"]
|
|
490
|
+
@uris = []
|
|
491
|
+
@extension_value = "IP:#{@ip_addresses.join(",IP:")}"
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
it_should_behave_like "a correct R509 SubjectAlternativeName object"
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
context "with a URI alternative name only" do
|
|
498
|
+
before :all do
|
|
499
|
+
@dns_names = []
|
|
500
|
+
@ip_addresses = []
|
|
501
|
+
@uris = ["http://www.test.local"]
|
|
502
|
+
@extension_value = "URI:#{@uris.join(",URI:")}"
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
it_should_behave_like "a correct R509 SubjectAlternativeName object"
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
context "with multiple URI alternative names only" do
|
|
509
|
+
before :all do
|
|
510
|
+
@dns_names = []
|
|
511
|
+
@ip_addresses = []
|
|
512
|
+
@uris = ["http://www.test.local","http://www2.test.local"]
|
|
513
|
+
@extension_value = "URI:#{@uris.join(",URI:")}"
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
it_should_behave_like "a correct R509 SubjectAlternativeName object"
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
context "with multiple different alternative names" do
|
|
520
|
+
before :all do
|
|
521
|
+
@dns_names = ["www.test.local"]
|
|
522
|
+
@ip_addresses = ["10.1.2.3"]
|
|
523
|
+
@uris = ["http://www.test.local"]
|
|
524
|
+
@extension_value = "DNS:#{@dns_names.join(",DNS:")},IP:#{@ip_addresses.join(",IP:")},URI:#{@uris.join(",URI:")}"
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
it_should_behave_like "a correct R509 SubjectAlternativeName object"
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
context "with multiple different alternative names with trailing newlines" do
|
|
531
|
+
before :all do
|
|
532
|
+
@dns_names = ["www.test.local"]
|
|
533
|
+
@ip_addresses = ["10.1.2.3"]
|
|
534
|
+
@uris = ["http://www.test.local"]
|
|
535
|
+
@extension_value = "DNS:#{@dns_names.join("\n,DNS:")}\n,IP:#{@ip_addresses.join("\n,IP:")}\n,URI:#{@uris.join("\n,URI:")}\n"
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
it_should_behave_like "a correct R509 SubjectAlternativeName object"
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
context "AuthorityInfoAccess" do
|
|
542
|
+
context "with a CA Issuers URI only" do
|
|
543
|
+
before :all do
|
|
544
|
+
@ca_issuers_uris = ["http://www.test.local/ca.cert"]
|
|
545
|
+
@ocsp_uris = []
|
|
546
|
+
@extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join(",URI:")}"
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
it_should_behave_like "a correct R509 AuthorityInfoAccess object"
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
context "with multiple CA Issuers URIs only" do
|
|
553
|
+
before :all do
|
|
554
|
+
@ca_issuers_uris = ["http://www.test.local/ca.cert", "http://www.test.local/subca.cert"]
|
|
555
|
+
@ocsp_uris = []
|
|
556
|
+
@extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join(",CA Issuers - URI:")}"
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
it_should_behave_like "a correct R509 AuthorityInfoAccess object"
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
context "with an OCSP URI only" do
|
|
563
|
+
before :all do
|
|
564
|
+
@ca_issuers_uris = []
|
|
565
|
+
@ocsp_uris = ["http://www.test.local"]
|
|
566
|
+
@extension_value = "OCSP - URI:#{@ocsp_uris.join(",URI:")}"
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
it_should_behave_like "a correct R509 AuthorityInfoAccess object"
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
context "with multiple OCSP URIs only" do
|
|
573
|
+
before :all do
|
|
574
|
+
@ca_issuers_uris = []
|
|
575
|
+
@ocsp_uris = ["http://www.test.local", "http://www2.test.local"]
|
|
576
|
+
@extension_value = "OCSP - URI:#{@ocsp_uris.join(",OCSP - URI:")}"
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
it_should_behave_like "a correct R509 AuthorityInfoAccess object"
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
context "with both a CA Issuers URI and an OCSP URI" do
|
|
583
|
+
before :all do
|
|
584
|
+
@ca_issuers_uris = ["http://www.test.local/ca.cert"]
|
|
585
|
+
@ocsp_uris = ["http://www.test.local"]
|
|
586
|
+
@extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join(",CA Issuers - URI:")},OCSP - URI:#{@ocsp_uris.join(",URI:")}"
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
it_should_behave_like "a correct R509 AuthorityInfoAccess object"
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
context "with both a CA Issuers URI and an OCSP URI with trailing newlines" do
|
|
593
|
+
before :all do
|
|
594
|
+
@ca_issuers_uris = ["http://www.test.local/ca.cert"]
|
|
595
|
+
@ocsp_uris = ["http://www.test.local"]
|
|
596
|
+
@extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join("\n,CA Issuers - URI:")}\n,OCSP - URI:#{@ocsp_uris.join("\n,URI:")}\n"
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
it_should_behave_like "a correct R509 AuthorityInfoAccess object"
|
|
600
|
+
end
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
context "CrlDistributionPoints" do
|
|
604
|
+
context "wtih a single CRL URI" do
|
|
605
|
+
before :all do
|
|
606
|
+
@crl_uris = ["http://www.test.local/ca.crl"]
|
|
607
|
+
@extension_value = "URI:#{@crl_uris.join(",URI:")}"
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
it_should_behave_like "a correct R509 CrlDistributionPoints object"
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
context "wtih multiple CRL URIs" do
|
|
614
|
+
before :all do
|
|
615
|
+
@crl_uris = ["http://www.test.local/ca.crl", "http://www.test.local/subca.crl"]
|
|
616
|
+
@extension_value = "URI:#{@crl_uris.join(",URI:")}"
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
it_should_behave_like "a correct R509 CrlDistributionPoints object"
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
context "wtih multiple CRL URIs and trailing newlines" do
|
|
623
|
+
before :all do
|
|
624
|
+
@crl_uris = ["http://www.test.local/ca.crl", "http://www.test.local/subca.crl"]
|
|
625
|
+
@extension_value = "URI:#{@crl_uris.join("\n,URI:")}\n"
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
it_should_behave_like "a correct R509 CrlDistributionPoints object"
|
|
629
|
+
end
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
end
|