spec/cert/extensions_spec.rb in r509-0.8.1 vs spec/cert/extensions_spec.rb in r509-0.9
- old
+ new
@@ -2,631 +2,1094 @@
include R509::Cert::Extensions
shared_examples_for "a correctly implemented wrap_openssl_extensions" do
before :each do
- @r509_extensions = R509::Cert::Extensions.wrap_openssl_extensions( @openssl_extensions )
-
- @r509_classes = [ BasicConstraints, KeyUsage, ExtendedKeyUsage,
- SubjectKeyIdentifier, AuthorityKeyIdentifier,
- SubjectAlternativeName, AuthorityInfoAccess,
- CrlDistributionPoints ]
+ @r509_extensions = R509::Cert::Extensions.wrap_openssl_extensions( @openssl_extensions )
+
+ @r509_classes = [ BasicConstraints, KeyUsage, ExtendedKeyUsage,
+ SubjectKeyIdentifier, AuthorityKeyIdentifier,
+ SubjectAlternativeName, AuthorityInfoAccess,
+ CRLDistributionPoints, OCSPNoCheck ]
end
-
+
it "should not have returned values that aren't R509 extensions" do
- classes = @r509_extensions.values.map { |ext| ext.class }
- non_r509_classes = classes.reject { |ext_class| @r509_classes.include?(ext_class) }
- non_r509_classes.should == []
+ classes = @r509_extensions.values.map { |ext| ext.class }
+ non_r509_classes = classes.reject { |ext_class| @r509_classes.include?(ext_class) }
+ non_r509_classes.should == []
end
-
+
it "should have returned the right number of extensions" do
- @r509_extensions.count.should == @wrappable_extensions.count
+ @r509_extensions.count.should == @wrappable_extensions.count
end
-
+
it "should not have returned keys improperly mapped to values" do
- incorrect_mappings = @r509_extensions.select { |key_class,ext| ext.class != key_class }
- incorrect_mappings = {} if incorrect_mappings == [] # compatibility for old versions of Ruby
- incorrect_mappings.should == {}
+ incorrect_mappings = @r509_extensions.select { |key_class,ext| ext.class != key_class }
+ incorrect_mappings = {} if incorrect_mappings == [] # compatibility for old versions of Ruby
+ incorrect_mappings.should == {}
end
-
+
it "should not have failed to map an implemented extension" do
- missing_extensions = []
- @wrappable_extensions.each do |openssl_ext|
- if (@r509_extensions.select {|r509_class,r509_ext| r509_ext.oid == openssl_ext.oid}) == {}
- missing_extensions << openssl_ext.oid
- end
+ missing_extensions = []
+ @wrappable_extensions.each do |openssl_ext|
+ if (@r509_extensions.select {|r509_class,r509_ext| r509_ext.oid == openssl_ext.oid}) == {}
+ missing_extensions << openssl_ext.oid
end
-
- missing_extensions.should == []
+ end
+
+ missing_extensions.should == []
end
end
shared_examples_for "a correctly implemented get_unknown_extensions" do
it "should not have returned values that are R509 extensions" do
- R509::Cert::Extensions.get_unknown_extensions( @openssl_extensions ).should == @unknown_extensions
+ R509::Cert::Extensions.get_unknown_extensions( @openssl_extensions ).should == @unknown_extensions
end
end
-shared_examples_for "a correct R509 BasicConstraints object" do
- before :all do
- extension_name = "basicConstraints"
- klass = BasicConstraints
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
- @r509_ext = klass.new( openssl_ext )
- end
+shared_examples_for "a correct R509 BasicConstraints object" do |critical|
+ before :all do
+ extension_name = "basicConstraints"
+ klass = BasicConstraints
+ ef = OpenSSL::X509::ExtensionFactory.new
+ openssl_ext = ef.create_extension( extension_name, @extension_value , critical)
+ @r509_ext = klass.new( openssl_ext )
+ end
- it "is_ca? should correctly report whether it's a CA certificate" do
- @r509_ext.is_ca?.should == @is_ca
- end
+ it "is_ca? should correctly report whether it's a CA certificate (critical:#{critical})" do
+ @r509_ext.is_ca?.should == @is_ca
+ end
- it "the path length should be correct" do
- @r509_ext.path_length.should == @pathlen
- end
+ it "the path length should be correct (critical:#{critical})" do
+ @r509_ext.path_length.should == @pathlen
+ end
- it "allows_sub_ca? should correctly report whether its path length allows it to issue CA certs" do
- @r509_ext.allows_sub_ca?.should == @allows_sub_ca
- end
+ it "allows_sub_ca? should correctly report whether its path length allows it to issue CA certs (critical:#{critical})" do
+ @r509_ext.allows_sub_ca?.should == @allows_sub_ca
+ end
+
+ it "reports #critical? properly" do
+ @r509_ext.critical?.should == critical
+ end
end
-shared_examples_for "a correct R509 KeyUsage object" do
- before :all do
- extension_name = "keyUsage"
- klass = KeyUsage
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
- @r509_ext = klass.new( openssl_ext )
- end
+shared_examples_for "a correct R509 KeyUsage object" do |critical|
+ before :each do
+ extension_name = "keyUsage"
+ klass = KeyUsage
+ ef = OpenSSL::X509::ExtensionFactory.new
+ openssl_ext = ef.create_extension( extension_name, @extension_value, critical )
+ @r509_ext = klass.new( openssl_ext )
+ end
- it "allowed_uses should be non-nil" do
- @r509_ext.allowed_uses.should_not == nil
- end
+ it "allowed_uses should be non-nil critical:#{critical}" do
+ @r509_ext.allowed_uses.should_not == nil
+ end
- it "allowed_uses should be correct" do
- @r509_ext.allowed_uses.should == @allowed_uses
- end
+ it "allowed_uses should be correct critical:#{critical}" do
+ @r509_ext.allowed_uses.should == @allowed_uses
+ end
- it "the individual allowed-use functions should be correct" do
- @r509_ext.digital_signature?.should == @allowed_uses.include?( KeyUsage::AU_DIGITAL_SIGNATURE )
- @r509_ext.non_repudiation?.should == @allowed_uses.include?( KeyUsage::AU_NON_REPUDIATION )
- @r509_ext.key_encipherment?.should == @allowed_uses.include?( KeyUsage::AU_KEY_ENCIPHERMENT )
- @r509_ext.data_encipherment?.should == @allowed_uses.include?( KeyUsage::AU_DATA_ENCIPHERMENT )
- @r509_ext.key_agreement?.should == @allowed_uses.include?( KeyUsage::AU_KEY_AGREEMENT )
- @r509_ext.certificate_sign?.should == @allowed_uses.include?( KeyUsage::AU_CERTIFICATE_SIGN )
- @r509_ext.crl_sign?.should == @allowed_uses.include?( KeyUsage::AU_CRL_SIGN )
- @r509_ext.encipher_only?.should == @allowed_uses.include?( KeyUsage::AU_ENCIPHER_ONLY )
- @r509_ext.decipher_only?.should == @allowed_uses.include?( KeyUsage::AU_DECIPHER_ONLY )
+ it "the individual allowed-use functions should be correct critical:#{critical}" do
+ @r509_ext.digital_signature?.should == @allowed_uses.include?( KeyUsage::AU_DIGITAL_SIGNATURE )
+ @r509_ext.non_repudiation?.should == @allowed_uses.include?( KeyUsage::AU_NON_REPUDIATION )
+ @r509_ext.key_encipherment?.should == @allowed_uses.include?( KeyUsage::AU_KEY_ENCIPHERMENT )
+ @r509_ext.data_encipherment?.should == @allowed_uses.include?( KeyUsage::AU_DATA_ENCIPHERMENT )
+ @r509_ext.key_agreement?.should == @allowed_uses.include?( KeyUsage::AU_KEY_AGREEMENT )
+ @r509_ext.key_cert_sign?.should == @allowed_uses.include?( KeyUsage::AU_KEY_CERT_SIGN )
+ @r509_ext.crl_sign?.should == @allowed_uses.include?( KeyUsage::AU_CRL_SIGN )
+ @r509_ext.encipher_only?.should == @allowed_uses.include?( KeyUsage::AU_ENCIPHER_ONLY )
+ @r509_ext.decipher_only?.should == @allowed_uses.include?( KeyUsage::AU_DECIPHER_ONLY )
+ end
+
+ it "the #allows? method should work critical:#{critical}" do
+ @allowed_uses.each do |au|
+ @r509_ext.allows?(au).should == true
end
+ end
+
+ it "reports #critical? properly" do
+ @r509_ext.critical?.should == critical
+ end
end
-shared_examples_for "a correct R509 ExtendedKeyUsage object" do
- before :all do
- extension_name = "extendedKeyUsage"
- klass = ExtendedKeyUsage
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
- @r509_ext = klass.new( openssl_ext )
- end
+shared_examples_for "a correct R509 ExtendedKeyUsage object" do |critical|
+ before :all do
+ extension_name = "extendedKeyUsage"
+ klass = ExtendedKeyUsage
+ ef = OpenSSL::X509::ExtensionFactory.new
+ openssl_ext = ef.create_extension( extension_name, @extension_value , critical )
+ @r509_ext = klass.new( openssl_ext )
+ end
- it "allowed_uses should be non-nil" do
- @r509_ext.allowed_uses.should_not == nil
- end
+ it "allowed_uses should be non-nil critical:#{critical}" do
+ @r509_ext.allowed_uses.should_not == nil
+ end
- it "allowed_uses should be correct" do
- @r509_ext.allowed_uses.should == @allowed_uses
- end
+ it "allowed_uses should be correct critical:#{critical}" do
+ @r509_ext.allowed_uses.should == @allowed_uses
+ end
- it "the individual allowed-use functions should be correct" do
- @r509_ext.web_server_authentication?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_WEB_SERVER_AUTH )
- @r509_ext.web_client_authentication?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_WEB_CLIENT_AUTH )
- @r509_ext.code_signing?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_CODE_SIGNING )
- @r509_ext.email_protection?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_EMAIL_PROTECTION )
+ it "the individual allowed-use functions should be correct critical:#{critical}" do
+ @r509_ext.web_server_authentication?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_WEB_SERVER_AUTH )
+ @r509_ext.web_client_authentication?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_WEB_CLIENT_AUTH )
+ @r509_ext.code_signing?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_CODE_SIGNING )
+ @r509_ext.email_protection?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_EMAIL_PROTECTION )
+ @r509_ext.ocsp_signing?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_OCSP_SIGNING )
+ @r509_ext.time_stamping?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_TIME_STAMPING )
+ @r509_ext.any_extended_key_usage?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_ANY_EXTENDED_KEY_USAGE )
+ end
+
+ it "the #allows? method should work critical:#{critical}" do
+ @allowed_uses.each do |au|
+ @r509_ext.allows?(au).should == true
end
+ end
+
+ it "reports #critical? properly" do
+ @r509_ext.critical?.should == critical
+ end
end
shared_examples_for "a correct R509 SubjectKeyIdentifier object" do
- before :all do
- extension_name = "subjectKeyIdentifier"
- klass = SubjectKeyIdentifier
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
- @r509_ext = klass.new( openssl_ext )
- end
+ before :all do
+ extension_name = "subjectKeyIdentifier"
+ klass = SubjectKeyIdentifier
+ openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
+ @r509_ext = klass.new( openssl_ext )
+ end
- it "key should be correct" do
- @r509_ext.key.should == @key
- end
+ it "key should be correct" do
+ @r509_ext.key.should == @key
+ end
end
shared_examples_for "a correct R509 AuthorityKeyIdentifier object" do
- before :all do
- extension_name = "authorityKeyIdentifier"
- klass = AuthorityKeyIdentifier
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
- @r509_ext = klass.new( openssl_ext )
- end
+ before :all do
+ extension_name = "authorityKeyIdentifier"
+ klass = AuthorityKeyIdentifier
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ef.issuer_certificate = OpenSSL::X509::Certificate.new TestFixtures::TEST_CA_CERT
+ openssl_ext = ef.create_extension( "authorityKeyIdentifier", @extension_value )
+ @r509_ext = klass.new( openssl_ext )
+ end
- #TODO
+ it "has the expected type" do
+ @r509_ext.oid.should == "authorityKeyIdentifier"
+ end
+
+ it "contains the key identifier" do
+ @r509_ext.key_identifier.should == "79:75:BB:84:3A:CB:2C:DE:7A:09:BE:31:1B:43:BC:1C:2A:4D:53:58"
+ end
+ it "parses the authority cert issuer and serial number" do
+ @r509_ext.authority_cert_issuer.value.to_s.should == "/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA"
+ @r509_ext.authority_cert_serial_number.should == 'FF:D9:C7:0B:87:37:D1:94'
+ end
end
-shared_examples_for "a correct R509 SubjectAlternativeName object" do
- before :all do
- extension_name = "subjectAltName"
- klass = SubjectAlternativeName
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
- @r509_ext = klass.new( openssl_ext )
- end
+shared_examples_for "a correct R509 SubjectAlternativeName object" do |critical|
+ before :all do
+ extension_name = "subjectAltName"
+ klass = SubjectAlternativeName
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ef.config = OpenSSL::Config.parse(@conf)
+ openssl_ext = ef.create_extension( extension_name, @extension_value , critical )
+ @r509_ext = klass.new( openssl_ext )
+ end
- it "dns_names should be correct" do
- @r509_ext.dns_names.should == @dns_names
- end
+ it "dns_names should be correct critical:#{critical}" do
+ @r509_ext.dns_names.should == @dns_names
+ end
- it "ip_addresses should be correct" do
- @r509_ext.ip_addresses.should == @ip_addresses
- end
+ it "ip_addresses should be correct critical:#{critical}" do
+ @r509_ext.ip_addresses.should == @ip_addresses
+ end
- it "uris should be correct" do
- @r509_ext.uris.should == @uris
- end
+ it "rfc_822names should be correct critical:#{critical}" do
+ @r509_ext.rfc_822_names.should == @rfc_822_names
+ end
+
+ it "uris should be correct critical:#{critical}" do
+ @r509_ext.uris.should == @uris
+ end
+
+ it "dirNames should be correct critical:#{critical}" do
+ @r509_ext.directory_names.size.should == @directory_names.size
+ end
+
+ it "ordered should be correct critical:#{critical}" do
+ @r509_ext.names.size.should == @dns_names.size + @ip_addresses.size + @rfc_822_names.size + @uris.size + @directory_names.size
+ end
+
+ it "reports #critical? properly" do
+ @r509_ext.critical?.should == critical
+ end
end
-shared_examples_for "a correct R509 AuthorityInfoAccess object" do
- before :all do
- extension_name = "authorityInfoAccess"
- klass = AuthorityInfoAccess
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
- @r509_ext = klass.new( openssl_ext )
- end
+shared_examples_for "a correct R509 AuthorityInfoAccess object" do |critical|
+ before :all do
+ extension_name = "authorityInfoAccess"
+ klass = AuthorityInfoAccess
+ ef = OpenSSL::X509::ExtensionFactory.new
+ openssl_ext = ef.create_extension( extension_name, @extension_value, critical )
+ @r509_ext = klass.new( openssl_ext )
+ end
- it "ca_issuers_uri should be correct" do
- @r509_ext.ca_issuers_uris.should == @ca_issuers_uris
- end
+ it "ca_issuers_uri should be correct critical:#{critical}" do
+ @r509_ext.ca_issuers.uris.should == @ca_issuers_uris
+ end
- it "ocsp_uri should be correct" do
- @r509_ext.ocsp_uris.should == @ocsp_uris
- end
+ it "ocsp_uri should be correct critical:#{critical}" do
+ @r509_ext.ocsp.uris.should == @ocsp_uris
+ end
+
+ it "reports #critical? properly" do
+ @r509_ext.critical?.should == critical
+ end
end
-shared_examples_for "a correct R509 CrlDistributionPoints object" do
- before :all do
- extension_name = "crlDistributionPoints"
- klass = CrlDistributionPoints
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
- @r509_ext = klass.new( openssl_ext )
- end
+shared_examples_for "a correct R509 CRLDistributionPoints object" do |critical|
+ before :all do
+ extension_name = "crlDistributionPoints"
+ klass = CRLDistributionPoints
+ ef = OpenSSL::X509::ExtensionFactory.new
+ openssl_ext = ef.create_extension( extension_name, @extension_value , critical )
+ @r509_ext = klass.new( openssl_ext )
+ end
- it "crl_uri should be correct" do
- @r509_ext.crl_uris.should == @crl_uris
- end
+ it "crl_uri should be correct critical:#{critical}" do
+ @r509_ext.crl.uris.should == @crl_uris
+ end
+
+ it "reports #critical? properly" do
+ @r509_ext.critical?.should == critical
+ end
end
+shared_examples_for "a correct R509 OCSPNoCheck object" do |critical|
+ before :all do
+ extension_name = "noCheck"
+ klass = OCSPNoCheck
+ ef = OpenSSL::X509::ExtensionFactory.new
+ openssl_ext = ef.create_extension( extension_name, "irrelevant", critical)
+ @r509_ext = klass.new( openssl_ext )
+ end
-describe R509::Cert::Extensions do
- include R509::Cert::Extensions
-
- context "Class functions" do
- context "#wrap_openssl_extensions and #get_unknown_extensions" do
- context "with no extensions" do
- before :each do
- @wrappable_extensions = []
- @unknown_extensions = []
-
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
- end
-
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
- it_should_behave_like "a correctly implemented get_unknown_extensions"
- end
-
- context "with one implemented extension" do
- before :each do
- @wrappable_extensions = []
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
-
- @unknown_extensions = []
-
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
- end
-
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
- it_should_behave_like "a correctly implemented get_unknown_extensions"
- end
-
- context "with all implemented extensions" do
- before :each do
- @wrappable_extensions = []
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
- @wrappable_extensions << OpenSSL::X509::Extension.new( "keyUsage", KeyUsage::AU_DIGITAL_SIGNATURE )
- @wrappable_extensions << OpenSSL::X509::Extension.new( "extendedKeyUsage", ExtendedKeyUsage::AU_WEB_SERVER_AUTH )
- @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" )
- @wrappable_extensions << OpenSSL::X509::Extension.new( "authorityKeyIdentifier", "keyid:always" )
- @wrappable_extensions << OpenSSL::X509::Extension.new( "subjectAltName", "DNS:www.test.local" )
- @wrappable_extensions << OpenSSL::X509::Extension.new( "authorityInfoAccess", "CA Issuers - URI:http://www.test.local" )
- @wrappable_extensions << OpenSSL::X509::Extension.new( "crlDistributionPoints", "URI:http://www.test.local" )
-
- @unknown_extensions = []
-
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
- end
-
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
- it_should_behave_like "a correctly implemented get_unknown_extensions"
- end
-
- context "with an unimplemented extension" do
- before :each do
- @wrappable_extensions = []
-
- @unknown_extensions = []
- @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
-
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
- end
-
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
- it_should_behave_like "a correctly implemented get_unknown_extensions"
- end
-
- context "with implemented and unimplemented extensions" do
- before :each do
- @wrappable_extensions = []
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
-
- @unknown_extensions = []
- @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
-
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
- end
-
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
- it_should_behave_like "a correctly implemented get_unknown_extensions"
- end
-
- context "with multiple extensions of an implemented type" do
- before :each do
- @wrappable_extensions = []
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:1" )
-
- @unknown_extensions = []
- @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
-
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
- end
-
- it "should raise an ArgumentError for #wrap_openssl_extensions" do
- expect {
- R509::Cert::Extensions.wrap_openssl_extensions( @openssl_extensions )
- }.to raise_error(ArgumentError)
- end
- it_should_behave_like "a correctly implemented get_unknown_extensions"
- end
-
- context "with multiple extensions of an unimplemented type" do
- before :each do
- @wrappable_extensions = []
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
-
- @unknown_extensions = []
- @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
- @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www2.test.local" )
-
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
- end
-
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
- it_should_behave_like "a correctly implemented get_unknown_extensions"
- end
- end
+ it "has the expected type" do
+ @r509_ext.oid.should == "noCheck"
+ end
+
+ it "reports #critical? properly" do
+ @r509_ext.critical?.should == critical
+ end
+end
+
+shared_examples_for "a correct R509 CertificatePolicies object" do
+ before :all do
+ klass = CertificatePolicies
+ openssl_ext = OpenSSL::X509::Extension.new @policy_data
+ @r509_ext = klass.new( openssl_ext )
+ end
+
+ it "should correctly parse the data" do
+ @r509_ext.policies.count.should == 1
+ @r509_ext.policies[0].policy_identifier.should == "2.16.840.1.12345.1.2.3.4.1"
+ @r509_ext.policies[0].policy_qualifiers.cps_uris.should == ["http://example.com/cps", "http://other.com/cps"]
+ end
+end
+
+shared_examples_for "a correct R509 InhibitAnyPolicy object" do |critical|
+ before :all do
+ extension_name = "inhibitAnyPolicy"
+ klass = InhibitAnyPolicy
+ ef = OpenSSL::X509::ExtensionFactory.new
+ openssl_ext = ef.create_extension( extension_name, @skip_certs.to_s,critical)
+ @r509_ext = klass.new( openssl_ext )
+ end
+
+ it "should parse the integer value out of the extension" do
+ @r509_ext.skip_certs.should == @skip_certs
+ end
+
+ it "reports #critical? properly" do
+ @r509_ext.critical?.should == critical
+ end
+end
+
+shared_examples_for "a correct R509 PolicyConstraints object" do |critical|
+ before :all do
+ extension_name = "policyConstraints"
+ klass = PolicyConstraints
+ ef = OpenSSL::X509::ExtensionFactory.new
+ openssl_ext = ef.create_extension( extension_name, @extension_value, critical)
+ @r509_ext = klass.new( openssl_ext )
+ end
+
+ it "should have the expected require policy" do
+ @r509_ext.require_explicit_policy.should == @require_explicit_policy
+ end
+ it "should have the expected inhibit mapping" do
+ @r509_ext.inhibit_policy_mapping.should == @inhibit_policy_mapping
+ end
+end
+
+shared_examples_for "a correct R509 NameConstraints object" do |critical|
+ before :all do
+ extension_name = "nameConstraints"
+ klass = NameConstraints
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ef.config = OpenSSL::Config.parse(@conf)
+ openssl_ext = ef.create_extension( extension_name, @extension_value, critical)
+ @r509_ext = klass.new( openssl_ext )
+ end
+
+ it "should have the permitted names" do
+ @permitted_names.each_with_index do |name,index|
+ @r509_ext.permitted_names[index].tag.should == name[:tag]
+ @r509_ext.permitted_names[index].value.should == name[:value]
end
+ end
+ it "should have the excluded names" do
+ @excluded_names.each_with_index do |name,index|
+ @r509_ext.excluded_names[index].tag.should == name[:tag]
+ @r509_ext.excluded_names[index].value.should == name[:value]
+ end
+ end
+end
- context "BasicConstraints" do
- context "with constraints for a CA certificate" do
- before :all do
- @extension_value = "CA:TRUE;pathlen:1"
- @is_ca = true
- @pathlen = 1
- @allows_sub_ca = true
- end
+describe R509::Cert::Extensions do
+ include R509::Cert::Extensions
- it_should_behave_like "a correct R509 BasicConstraints object"
+ context "Class functions" do
+ context "#wrap_openssl_extensions and #get_unknown_extensions" do
+ context "with no extensions" do
+ before :each do
+ @wrappable_extensions = []
+ @unknown_extensions = []
+
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
end
- context "with constraints for a sub-CA certificate" do
- before :all do
- @extension_value = "CA:TRUE;pathlen:0"
- @is_ca = true
- @pathlen = 0
- @allows_sub_ca = false
- end
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
+ end
- it_should_behave_like "a correct R509 BasicConstraints object"
+ context "with one implemented extension" do
+ before :each do
+ @wrappable_extensions = []
+ ef = OpenSSL::X509::ExtensionFactory.new
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:0" )
+
+ @unknown_extensions = []
+
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
end
- context "with constraints for a non-CA certificate" do
- before :all do
- @extension_value = "CA:FALSE"
- @is_ca = false
- @pathlen = nil
- @allows_sub_ca = false
- end
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
+ end
- it_should_behave_like "a correct R509 BasicConstraints object"
+ context "with all implemented extensions" do
+ before :each do
+ @wrappable_extensions = []
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ef.issuer_certificate = OpenSSL::X509::Certificate.new TestFixtures::TEST_CA_CERT
+ ef.subject_certificate = OpenSSL::X509::Certificate.new TestFixtures::TEST_CA_CERT
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:0", true )
+ @wrappable_extensions << ef.create_extension( "keyUsage", KeyUsage::AU_DIGITAL_SIGNATURE )
+ @wrappable_extensions << ef.create_extension( "extendedKeyUsage", ExtendedKeyUsage::AU_WEB_SERVER_AUTH )
+ @wrappable_extensions << ef.create_extension( "subjectKeyIdentifier", "hash" )
+ @wrappable_extensions << ef.create_extension( "authorityKeyIdentifier", "keyid:always" )
+ @wrappable_extensions << ef.create_extension( "subjectAltName", "DNS:www.test.local" )
+ @wrappable_extensions << ef.create_extension( "authorityInfoAccess", "caIssuers;URI:http://www.test.local" )
+ @wrappable_extensions << ef.create_extension( "crlDistributionPoints", "URI:http://www.test.local" )
+
+ @unknown_extensions = []
+
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
end
- end
- context "KeyUsage" do
- context "with one allowed use" do
- before :all do
- @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE ]
- @extension_value = @allowed_uses.join( ", " )
- end
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
+ end
- it_should_behave_like "a correct R509 KeyUsage object"
+ context "with an unimplemented extension" do
+ before :each do
+ @wrappable_extensions = []
+
+ @unknown_extensions = []
+ @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
+
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
end
- context "with some allowed uses" do
- before :all do
- # this spec and the one below alternate the uses
- @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE, KeyUsage::AU_KEY_ENCIPHERMENT, KeyUsage::AU_KEY_AGREEMENT, KeyUsage::AU_CRL_SIGN, KeyUsage::AU_DECIPHER_ONLY ]
- @extension_value = @allowed_uses.join( ", " )
- end
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
+ end
- it_should_behave_like "a correct R509 KeyUsage object"
+ context "with implemented and unimplemented extensions" do
+ before :each do
+ @wrappable_extensions = []
+ ef = OpenSSL::X509::ExtensionFactory.new
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:0" )
+
+ @unknown_extensions = []
+ @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
+
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
end
- context "with some different allowed uses" do
- before :all do
- @allowed_uses = [ KeyUsage::AU_NON_REPUDIATION, KeyUsage::AU_DATA_ENCIPHERMENT, KeyUsage::AU_CERTIFICATE_SIGN, KeyUsage::AU_ENCIPHER_ONLY ]
- @extension_value = @allowed_uses.join( ", " )
- end
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
+ end
- it_should_behave_like "a correct R509 KeyUsage object"
+ context "with multiple extensions of an implemented type" do
+ before :each do
+ @wrappable_extensions = []
+ ef = OpenSSL::X509::ExtensionFactory.new
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:0" )
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:1" )
+
+ @unknown_extensions = []
+ @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
+
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
end
- context "with all allowed uses" do
- before :all do
- @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE, KeyUsage::AU_KEY_ENCIPHERMENT,
- KeyUsage::AU_KEY_AGREEMENT, KeyUsage::AU_CRL_SIGN, KeyUsage::AU_DECIPHER_ONLY,
- KeyUsage::AU_NON_REPUDIATION, KeyUsage::AU_DATA_ENCIPHERMENT,
- KeyUsage::AU_CERTIFICATE_SIGN, KeyUsage::AU_ENCIPHER_ONLY ]
- @extension_value = @allowed_uses.join( ", " )
- end
+ it "should raise an ArgumentError for #wrap_openssl_extensions" do
+ expect {
+ R509::Cert::Extensions.wrap_openssl_extensions( @openssl_extensions )
+ }.to raise_error(ArgumentError)
+ end
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
+ end
- it_should_behave_like "a correct R509 KeyUsage object"
+ context "with multiple extensions of an unimplemented type" do
+ before :each do
+ @wrappable_extensions = []
+ ef = OpenSSL::X509::ExtensionFactory.new
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:0" )
+
+ @unknown_extensions = []
+ @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
+ @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www2.test.local" )
+
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
end
+
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
+ end
end
+ end
- context "ExtendedKeyUsage" do
- context "with one allowed use" do
- before :all do
- @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH ]
- @extension_value = @allowed_uses.join( ", " )
- end
+ context "BasicConstraints" do
+ context "with constraints for a CA certificate" do
+ before :all do
+ @extension_value = "CA:TRUE,pathlen:3"
+ @is_ca = true
+ @pathlen = 3
+ @allows_sub_ca = true
+ end
- it_should_behave_like "a correct R509 ExtendedKeyUsage object"
- end
+ it_should_behave_like "a correct R509 BasicConstraints object", false
+ it_should_behave_like "a correct R509 BasicConstraints object", true
+ end
- context "with some allowed uses" do
- before :all do
- # this spec and the one below alternate the uses
- @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH, ExtendedKeyUsage::AU_CODE_SIGNING ]
- @extension_value = @allowed_uses.join( ", " )
- end
+ context "with constraints for a sub-CA certificate" do
+ before :all do
+ @extension_value = "CA:TRUE,pathlen:0"
+ @is_ca = true
+ @pathlen = 0
+ @allows_sub_ca = false
+ end
- it_should_behave_like "a correct R509 ExtendedKeyUsage object"
- end
+ it_should_behave_like "a correct R509 BasicConstraints object", false
+ it_should_behave_like "a correct R509 BasicConstraints object", true
+ end
- context "with some different allowed uses" do
- before :all do
- @allowed_uses = [ ExtendedKeyUsage::AU_WEB_CLIENT_AUTH, ExtendedKeyUsage::AU_EMAIL_PROTECTION ]
- @extension_value = @allowed_uses.join( ", " )
- end
+ context "with constraints for a non-CA certificate" do
+ before :all do
+ @extension_value = "CA:FALSE"
+ @is_ca = false
+ @pathlen = nil
+ @allows_sub_ca = false
+ end
- it_should_behave_like "a correct R509 ExtendedKeyUsage object"
- end
+ it_should_behave_like "a correct R509 BasicConstraints object", false
+ it_should_behave_like "a correct R509 BasicConstraints object", true
+ end
+ end
- context "with all allowed uses" do
- before :all do
- @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH, ExtendedKeyUsage::AU_CODE_SIGNING,
- ExtendedKeyUsage::AU_WEB_CLIENT_AUTH, ExtendedKeyUsage::AU_EMAIL_PROTECTION ]
- @extension_value = @allowed_uses.join( ", " )
- end
+ context "KeyUsage" do
+ context "with one allowed use" do
+ before :all do
+ @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE ]
+ @extension_value = @allowed_uses.join( ", " )
+ end
- it_should_behave_like "a correct R509 ExtendedKeyUsage object"
- end
+ it_should_behave_like "a correct R509 KeyUsage object", false
+ it_should_behave_like "a correct R509 KeyUsage object", true
end
- context "SubjectKeyIdentifier" do
- before :all do
- @extension_value = "00:11:22:33:44:55:66:77:88:99:00:AA:BB:CC:DD:EE:FF:00:11:22"
- @key = @extension_value
- end
+ context "with some allowed uses" do
+ before :all do
+ # this spec and the one below alternate the uses
+ @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE, KeyUsage::AU_KEY_ENCIPHERMENT, KeyUsage::AU_KEY_AGREEMENT, KeyUsage::AU_CRL_SIGN, KeyUsage::AU_DECIPHER_ONLY ]
+ @extension_value = @allowed_uses.join( ", " )
+ end
- it_should_behave_like "a correct R509 SubjectKeyIdentifier object"
+ it_should_behave_like "a correct R509 KeyUsage object", false
+ it_should_behave_like "a correct R509 KeyUsage object", true
end
- context "AuthorityKeyIdentifier" do
- before :all do
- @extension_value = "keyid:always"
- end
+ context "with some different allowed uses" do
+ before :all do
+ @allowed_uses = [ KeyUsage::AU_NON_REPUDIATION, KeyUsage::AU_DATA_ENCIPHERMENT, KeyUsage::AU_KEY_CERT_SIGN, KeyUsage::AU_ENCIPHER_ONLY ]
+ @extension_value = @allowed_uses.join( ", " )
+ end
- it_should_behave_like "a correct R509 AuthorityKeyIdentifier object"
+ it_should_behave_like "a correct R509 KeyUsage object", false
+ it_should_behave_like "a correct R509 KeyUsage object", true
end
- context "SubjectAlternativeName" do
- context "with a DNS alternative name only" do
- before :all do
- @dns_names = ["www.test.local"]
- @ip_addresses = []
- @uris = []
- @extension_value = "DNS:#{@dns_names.join(",DNS:")}"
- end
+ context "with all allowed uses" do
+ before :all do
+ @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE, KeyUsage::AU_NON_REPUDIATION,
+ KeyUsage::AU_KEY_ENCIPHERMENT, KeyUsage::AU_DATA_ENCIPHERMENT,
+ KeyUsage::AU_KEY_AGREEMENT, KeyUsage::AU_KEY_CERT_SIGN,
+ KeyUsage::AU_CRL_SIGN, KeyUsage::AU_ENCIPHER_ONLY,
+ KeyUsage::AU_DECIPHER_ONLY ]
+ @extension_value = @allowed_uses.join( ", " )
+ end
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
- end
+ it_should_behave_like "a correct R509 KeyUsage object", false
+ it_should_behave_like "a correct R509 KeyUsage object", true
+ end
+ end
- context "with multiple DNS alternative names only" do
- before :all do
- @dns_names = ["www.test.local", "www2.test.local"]
- @ip_addresses = []
- @uris = []
- @extension_value = "DNS:#{@dns_names.join(",DNS:")}"
- end
+ context "ExtendedKeyUsage" do
+ context "with one allowed use" do
+ before :all do
+ @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH ]
+ @extension_value = @allowed_uses.join( ", " )
+ end
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
- end
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", false
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", true
+ end
- context "with an IP address alternative name only" do
- before :all do
- @dns_names = []
- @ip_addresses = ["10.1.2.3"]
- @uris = []
- @extension_value = "IP:#{@ip_addresses.join(",IP:")}"
- end
+ context "with some allowed uses" do
+ before :all do
+ # this spec and the one below alternate the uses
+ @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH, ExtendedKeyUsage::AU_CODE_SIGNING ]
+ @extension_value = @allowed_uses.join( ", " )
+ end
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
- end
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", false
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", true
+ end
- context "with multiple IP address alternative names only" do
- before :all do
- @dns_names = []
- @ip_addresses = ["10.1.2.3", "10.1.2.4"]
- @uris = []
- @extension_value = "IP:#{@ip_addresses.join(",IP:")}"
- end
+ context "with some different allowed uses" do
+ before :all do
+ @allowed_uses = [ ExtendedKeyUsage::AU_WEB_CLIENT_AUTH, ExtendedKeyUsage::AU_EMAIL_PROTECTION ]
+ @extension_value = @allowed_uses.join( ", " )
+ end
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
- end
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", false
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", true
+ end
- context "with a URI alternative name only" do
- before :all do
- @dns_names = []
- @ip_addresses = []
- @uris = ["http://www.test.local"]
- @extension_value = "URI:#{@uris.join(",URI:")}"
- end
+ context "with all allowed uses" do
+ before :all do
+ @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH, ExtendedKeyUsage::AU_CODE_SIGNING,
+ ExtendedKeyUsage::AU_WEB_CLIENT_AUTH, ExtendedKeyUsage::AU_EMAIL_PROTECTION,
+ ExtendedKeyUsage::AU_TIME_STAMPING, ExtendedKeyUsage::AU_OCSP_SIGNING,
+ ExtendedKeyUsage::AU_ANY_EXTENDED_KEY_USAGE]
+ @extension_value = @allowed_uses.join( ", " )
+ end
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
- end
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", false
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", true
+ end
+ end
- context "with multiple URI alternative names only" do
- before :all do
- @dns_names = []
- @ip_addresses = []
- @uris = ["http://www.test.local","http://www2.test.local"]
- @extension_value = "URI:#{@uris.join(",URI:")}"
- end
+ context "SubjectKeyIdentifier" do
+ before :all do
+ @extension_value = "00:11:22:33:44:55:66:77:88:99:00:AA:BB:CC:DD:EE:FF:00:11:22"
+ @key = @extension_value
+ end
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
- end
+ it_should_behave_like "a correct R509 SubjectKeyIdentifier object"
+ end
- context "with multiple different alternative names" do
- before :all do
- @dns_names = ["www.test.local"]
- @ip_addresses = ["10.1.2.3"]
- @uris = ["http://www.test.local"]
- @extension_value = "DNS:#{@dns_names.join(",DNS:")},IP:#{@ip_addresses.join(",IP:")},URI:#{@uris.join(",URI:")}"
- end
+ context "AuthorityKeyIdentifier" do
+ before :all do
+ @extension_value = "keyid:always,issuer:always"
+ end
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
- end
+ it_should_behave_like "a correct R509 AuthorityKeyIdentifier object"
+ end
- context "with multiple different alternative names with trailing newlines" do
- before :all do
- @dns_names = ["www.test.local"]
- @ip_addresses = ["10.1.2.3"]
- @uris = ["http://www.test.local"]
- @extension_value = "DNS:#{@dns_names.join("\n,DNS:")}\n,IP:#{@ip_addresses.join("\n,IP:")}\n,URI:#{@uris.join("\n,URI:")}\n"
- end
+ context "SubjectAlternativeName" do
+ context "with an unimplemented GeneralName type" do
+ it "errors as expected" do
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ext = ef.create_extension("subjectAltName","otherName:1.2.3.4;IA5STRING:Hello World")
+ expect { R509::Cert::Extensions::SubjectAlternativeName.new ext }.to raise_error(R509::R509Error, 'Unimplemented GeneralName tag: 0. At this time R509 does not support GeneralName types other than rfc822Name, dNSName, uniformResourceIdentifier, iPAddress, and directoryName')
+ end
+ end
+ context "with a DNS alternative name only" do
+ before :all do
+ @dns_names = ["www.test.local"]
+ @ip_addresses = []
+ @uris = []
+ @rfc_822_names = []
+ @directory_names = []
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
+ gns = R509::ASN1.general_name_parser(total)
+ serialized = gns.serialize_names
+ @conf = serialized[:conf]
+ @extension_value = serialized[:extension_string]
+ end
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
- end
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
end
- context "AuthorityInfoAccess" do
- context "with a CA Issuers URI only" do
- before :all do
- @ca_issuers_uris = ["http://www.test.local/ca.cert"]
- @ocsp_uris = []
- @extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join(",URI:")}"
- end
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
- end
+ context "with multiple DNS alternative names only" do
+ before :all do
+ @dns_names = ["www.test.local", "www2.test.local"]
+ @ip_addresses = []
+ @uris = []
+ @rfc_822_names = []
+ @directory_names = []
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
+ gns = R509::ASN1.general_name_parser(total)
+ serialized = gns.serialize_names
+ @conf = serialized[:conf]
+ @extension_value = serialized[:extension_string]
+ end
- context "with multiple CA Issuers URIs only" do
- before :all do
- @ca_issuers_uris = ["http://www.test.local/ca.cert", "http://www.test.local/subca.cert"]
- @ocsp_uris = []
- @extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join(",CA Issuers - URI:")}"
- end
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
+ end
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
- end
+ context "with an IP address alternative name only" do
+ before :all do
+ @dns_names = []
+ @ip_addresses = ["203.1.2.3"]
+ @rfc_822_names = []
+ @uris = []
+ @directory_names = []
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
+ gns = R509::ASN1.general_name_parser(total)
+ serialized = gns.serialize_names
+ @conf = serialized[:conf]
+ @extension_value = serialized[:extension_string]
+ end
- context "with an OCSP URI only" do
- before :all do
- @ca_issuers_uris = []
- @ocsp_uris = ["http://www.test.local"]
- @extension_value = "OCSP - URI:#{@ocsp_uris.join(",URI:")}"
- end
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
+ end
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
- end
+ context "with multiple IP address alternative names only" do
+ before :all do
+ @dns_names = []
+ @ip_addresses = ["10.1.2.3", "10.1.2.4"]
+ @uris = []
+ @rfc_822_names = []
+ @directory_names = []
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
+ gns = R509::ASN1.general_name_parser(total)
+ serialized = gns.serialize_names
+ @conf = serialized[:conf]
+ @extension_value = serialized[:extension_string]
+ end
- context "with multiple OCSP URIs only" do
- before :all do
- @ca_issuers_uris = []
- @ocsp_uris = ["http://www.test.local", "http://www2.test.local"]
- @extension_value = "OCSP - URI:#{@ocsp_uris.join(",OCSP - URI:")}"
- end
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
+ end
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
- end
+ context "with an rfc822Name alternative name only" do
+ before :all do
+ @dns_names = []
+ @ip_addresses = []
+ @rfc_822_names = ["some@guy.com"]
+ @uris = []
+ @directory_names = []
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
+ gns = R509::ASN1.general_name_parser(total)
+ serialized = gns.serialize_names
+ @conf = serialized[:conf]
+ @extension_value = serialized[:extension_string]
+ end
- context "with both a CA Issuers URI and an OCSP URI" do
- before :all do
- @ca_issuers_uris = ["http://www.test.local/ca.cert"]
- @ocsp_uris = ["http://www.test.local"]
- @extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join(",CA Issuers - URI:")},OCSP - URI:#{@ocsp_uris.join(",URI:")}"
- end
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
+ end
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
- end
+ context "with multiple rfc822Name alternative names only" do
+ before :all do
+ @dns_names = []
+ @ip_addresses = []
+ @rfc_822_names = ["some@guy.com","other@guy.com"]
+ @uris = []
+ @directory_names = []
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
+ gns = R509::ASN1.general_name_parser(total)
+ serialized = gns.serialize_names
+ @conf = serialized[:conf]
+ @extension_value = serialized[:extension_string]
+ end
- context "with both a CA Issuers URI and an OCSP URI with trailing newlines" do
- before :all do
- @ca_issuers_uris = ["http://www.test.local/ca.cert"]
- @ocsp_uris = ["http://www.test.local"]
- @extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join("\n,CA Issuers - URI:")}\n,OCSP - URI:#{@ocsp_uris.join("\n,URI:")}\n"
- end
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
+ end
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
- end
+ context "with a URI alternative name only" do
+ before :all do
+ @dns_names = []
+ @ip_addresses = []
+ @rfc_822_names = []
+ @uris = ["http://www.test.local"]
+ @directory_names = []
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
+ gns = R509::ASN1.general_name_parser(total)
+ serialized = gns.serialize_names
+ @conf = serialized[:conf]
+ @extension_value = serialized[:extension_string]
+ end
+
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
end
- context "CrlDistributionPoints" do
- context "wtih a single CRL URI" do
- before :all do
- @crl_uris = ["http://www.test.local/ca.crl"]
- @extension_value = "URI:#{@crl_uris.join(",URI:")}"
- end
+ context "with multiple URI alternative names only" do
+ before :all do
+ @dns_names = []
+ @ip_addresses = []
+ @rfc_822_names = []
+ @uris = ["http://www.test.local","http://www2.test.local"]
+ @directory_names = []
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
+ gns = R509::ASN1.general_name_parser(total)
+ serialized = gns.serialize_names
+ @conf = serialized[:conf]
+ @extension_value = serialized[:extension_string]
+ end
- it_should_behave_like "a correct R509 CrlDistributionPoints object"
- end
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
+ end
- context "wtih multiple CRL URIs" do
- before :all do
- @crl_uris = ["http://www.test.local/ca.crl", "http://www.test.local/subca.crl"]
- @extension_value = "URI:#{@crl_uris.join(",URI:")}"
- end
+ context "with a directoryName alternative name only" do
+ before :all do
+ @dns_names = []
+ @ip_addresses = []
+ @rfc_822_names = []
+ @uris = []
+ @directory_names = [
+ [['CN','langui.sh'],['O','org'],['L','locality']]
+ ]
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
+ gns = R509::ASN1.general_name_parser(total)
+ serialized = gns.serialize_names
+ @conf = serialized[:conf]
+ @extension_value = serialized[:extension_string]
+ end
- it_should_behave_like "a correct R509 CrlDistributionPoints object"
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
+ end
+
+ context "with multiple directoryName alternative names only" do
+ before :all do
+ @dns_names = []
+ @ip_addresses = []
+ @rfc_822_names = []
+ @uris = []
+ @directory_names = [
+ [['CN','langui.sh'],['O','org'],['L','locality']],
+ [['CN','otherdomain.com'],['O','org-like']]
+ ]
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
+ gns = R509::ASN1.general_name_parser(total)
+ serialized = gns.serialize_names
+ @conf = serialized[:conf]
+ @extension_value = serialized[:extension_string]
+ end
+
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
+ end
+
+ context "with multiple different alternative names" do
+ before :all do
+ @dns_names = ["www.test.local"]
+ @ip_addresses = ["10.1.2.3"]
+ @rfc_822_names = ["myemail@email.com"]
+ @uris = ["http://www.test.local"]
+ @directory_names = [
+ [['CN','langui.sh'],['O','org'],['L','locality']]
+ ]
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
+ gns = R509::ASN1.general_name_parser(total)
+ serialized = gns.serialize_names
+ @conf = serialized[:conf]
+ @extension_value = serialized[:extension_string]
+ end
+
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
+ end
+ end
+ context "AuthorityInfoAccess" do
+ context "with a CA Issuers URI only" do
+ before :all do
+ @ca_issuers_uris = ["http://www.test.local/ca.cert"]
+ @ocsp_uris = []
+ @extension_value = "caIssuers;URI:#{@ca_issuers_uris.join(",caIssuers;URI:")}"
+ end
+
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", false
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", true
+ end
+
+ context "with multiple CA Issuers URIs only" do
+ before :all do
+ @ca_issuers_uris = ["http://www.test.local/ca.cert", "http://www.test.local/subca.cert"]
+ @ocsp_uris = []
+ @extension_value = "caIssuers;URI:#{@ca_issuers_uris.join(",caIssuers;URI:")}"
+ end
+
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", false
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", true
+ end
+
+ context "with an OCSP URI only" do
+ before :all do
+ @ca_issuers_uris = []
+ @ocsp_uris = ["http://www.test.local"]
+ @extension_value = "OCSP;URI:#{@ocsp_uris.join(",OCSP;URI:")}"
+ end
+
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", false
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", true
+ end
+
+ context "with multiple OCSP URIs only" do
+ before :all do
+ @ca_issuers_uris = []
+ @ocsp_uris = ["http://www.test.local", "http://www2.test.local"]
+ @extension_value = "OCSP;URI:#{@ocsp_uris.join(",OCSP;URI:")}"
+ end
+
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", false
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", true
+ end
+
+ context "with both a CA Issuers URI and an OCSP URI" do
+ before :all do
+ @ca_issuers_uris = ["http://www.test.local/ca.cert"]
+ @ocsp_uris = ["http://www.test.local"]
+ @extension_value = "caIssuers;URI:#{@ca_issuers_uris.join(",caIssuers;URI:")},OCSP;URI:#{@ocsp_uris.join(",OCSP;URI:")}"
+ end
+
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", false
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", true
+ end
+ end
+
+ context "CRLDistributionPoints" do
+ context "with a single CRL URI" do
+ before :all do
+ @crl_uris = ["http://www.test.local/ca.crl"]
+ @extension_value = "URI:#{@crl_uris.join(",URI:")}"
+ end
+
+ it_should_behave_like "a correct R509 CRLDistributionPoints object", false
+ it_should_behave_like "a correct R509 CRLDistributionPoints object", true
+ end
+
+ context "with multiple CRL URIs" do
+ before :all do
+ @crl_uris = ["http://www.test.local/ca.crl", "http://www.test.local/subca.crl"]
+ @extension_value = "URI:#{@crl_uris.join(",URI:")}"
+ end
+
+ it_should_behave_like "a correct R509 CRLDistributionPoints object", false
+ it_should_behave_like "a correct R509 CRLDistributionPoints object", true
+ end
+ end
+
+ context "OCSPNoCheck" do
+ it_should_behave_like "a correct R509 OCSPNoCheck object", false
+ it_should_behave_like "a correct R509 OCSPNoCheck object", true
+ end
+
+ context "CertificatePolicies" do
+ before :all do
+ @policy_data = "0\x81\x90\x06\x03U\x1D \x04\x81\x880\x81\x850\x81\x82\x06\v`\x86H\x01\xE09\x01\x02\x03\x04\x010s0\"\x06\b+\x06\x01\x05\x05\a\x02\x01\x16\x16http://example.com/cps0 \x06\b+\x06\x01\x05\x05\a\x02\x01\x16\x14http://other.com/cps0+\x06\b+\x06\x01\x05\x05\a\x02\x020\x1F0\x16\x16\x06my org0\f\x02\x01\x01\x02\x01\x02\x02\x01\x03\x02\x01\x04\x1A\x05thing"
+ end
+
+ it_should_behave_like "a correct R509 CertificatePolicies object"
+ end
+
+ context "InhibitAnyPolicy" do
+ before :all do
+ @skip_certs = 3
+ end
+
+ it_should_behave_like "a correct R509 InhibitAnyPolicy object", false
+ it_should_behave_like "a correct R509 InhibitAnyPolicy object", true
+ end
+
+ context "PolicyConstraints" do
+ context "with just require" do
+ before :all do
+ @require_explicit_policy = 2
+ @inhibit_policy_mapping = nil
+ @extension_value = "requireExplicitPolicy:#{@require_explicit_policy}"
+ end
+ it_should_behave_like "a correct R509 PolicyConstraints object", false
+ it_should_behave_like "a correct R509 PolicyConstraints object", true
+ end
+ context "with just inhibit" do
+ before :all do
+ @require_explicit_policy = nil
+ @inhibit_policy_mapping = 3
+ @extension_value = "inhibitPolicyMapping:#{@inhibit_policy_mapping}"
+ end
+ it_should_behave_like "a correct R509 PolicyConstraints object", false
+ it_should_behave_like "a correct R509 PolicyConstraints object", true
+ end
+ context "with both require and inhibit" do
+ before :all do
+ @require_explicit_policy = 2
+ @inhibit_policy_mapping = 3
+ @extension_value = "requireExplicitPolicy:#{@require_explicit_policy},inhibitPolicyMapping:#{@inhibit_policy_mapping}"
+ end
+ it_should_behave_like "a correct R509 PolicyConstraints object", false
+ it_should_behave_like "a correct R509 PolicyConstraints object", true
+ end
+
+ end
+
+ context "NameConstraints" do
+ context "with one permitted name" do
+ before :all do
+ @excluded_names = []
+ @permitted_names = [{:tag => 2, :value => ".whatever.com"}]
+ gns = R509::ASN1::GeneralNames.new
+ @permitted_names.each do |name|
+ gns.add_item(name)
end
+ @conf = []
+ permitted = gns.names.map { |name|
+ serialized = name.serialize_name
+ @conf << serialized[:conf]
+ "permitted;" + serialized[:extension_string]
+ }.join(",")
+ @extension_value = permitted
+ @conf = @conf.join("\n")
+ end
- context "wtih multiple CRL URIs and trailing newlines" do
- before :all do
- @crl_uris = ["http://www.test.local/ca.crl", "http://www.test.local/subca.crl"]
- @extension_value = "URI:#{@crl_uris.join("\n,URI:")}\n"
- end
+ it_should_behave_like "a correct R509 NameConstraints object", false
+ it_should_behave_like "a correct R509 NameConstraints object", true
+ end
+ context "with multiple permitted names" do
+ before :all do
+ @excluded_names = []
+ @permitted_names = [{:tag => 2, :value => ".whatever.com"}, {:tag => 1, :value => "user@emaildomain.com" } ]
+ gns = R509::ASN1::GeneralNames.new
+ @permitted_names.each do |name|
+ gns.add_item(name)
+ end
+ @conf = []
+ permitted = gns.names.map { |name|
+ serialized = name.serialize_name
+ @conf << serialized[:conf]
+ "permitted;" + serialized[:extension_string]
+ }.join(",")
+ @extension_value = permitted
+ @conf = @conf.join("\n")
+ end
- it_should_behave_like "a correct R509 CrlDistributionPoints object"
+ it_should_behave_like "a correct R509 NameConstraints object", false
+ it_should_behave_like "a correct R509 NameConstraints object", true
+ end
+ context "with one excluded name" do
+ before :all do
+ @permitted_names = []
+ @excluded_names = [{:tag => 7, :value => "127.0.0.1/255.255.255.255"}]
+ egns = R509::ASN1::GeneralNames.new
+ @excluded_names.each do |name|
+ egns.add_item(name)
end
+ @conf = []
+ excluded = egns.names.map { |name|
+ serialized = name.serialize_name
+ @conf << serialized[:conf]
+ "excluded;" + serialized[:extension_string]
+ }.join(",")
+ @extension_value = excluded
+ @conf = @conf.join("\n")
+ end
+
+ it_should_behave_like "a correct R509 NameConstraints object", false
+ it_should_behave_like "a correct R509 NameConstraints object", true
end
+ context "with multiple excluded names" do
+ before :all do
+ @permitted_names = []
+ @excluded_names = [{:tag => 7, :value => "127.0.0.1/255.255.255.255"}, {:tag => 1, :value => "emaildomain.com" } ]
+ @permitted_names = []
+ egns = R509::ASN1::GeneralNames.new
+ @excluded_names.each do |name|
+ egns.add_item(name)
+ end
+ @conf = []
+ excluded = egns.names.map { |name|
+ serialized = name.serialize_name
+ @conf << serialized[:conf]
+ "excluded;" + serialized[:extension_string]
+ }.join(",")
+ @extension_value = excluded
+ @conf = @conf.join("\n")
+ end
+ it_should_behave_like "a correct R509 NameConstraints object", false
+ it_should_behave_like "a correct R509 NameConstraints object", true
+ end
+ context "with both permitted and excluded names" do
+ before :all do
+ @excluded_names = [{:tag => 7, :value => "127.0.0.1/255.255.255.255"}, {:tag => 1, :value => "emaildomain.com" } ]
+ @permitted_names = [{:tag => 2, :value => ".whatever.com"}, {:tag => 1, :value => "user@emaildomain.com"} ]
+ gns = R509::ASN1::GeneralNames.new
+ @permitted_names.each do |name|
+ gns.add_item(name)
+ end
+ @conf = []
+ permitted = gns.names.map { |name|
+ serialized = name.serialize_name
+ @conf << serialized[:conf]
+ "permitted;" + serialized[:extension_string]
+ }.join(",")
+ egns = R509::ASN1::GeneralNames.new
+ @excluded_names.each do |name|
+ egns.add_item(name)
+ end
+ excluded = egns.names.map { |name|
+ serialized = name.serialize_name
+ @conf << serialized[:conf]
+ "excluded;" + serialized[:extension_string]
+ }.join(",")
+ @extension_value = permitted + "," + excluded
+ @conf = @conf.join("\n")
+ end
+
+ it_should_behave_like "a correct R509 NameConstraints object", false
+ it_should_behave_like "a correct R509 NameConstraints object", true
+ end
+ end
end