Alternate names, if present, are specified in the subjectAltName extension of
the certificate. The values are in the form:

"DNS:alternate_name1, DNS:alternate_name2"

This helper will retrieve the value of the subjectAltName extension and extract
the alternate names, returning and empty list if the extension is absent. This
will make it easier to access the entire list of possible names for a
certificate, rather than just the common name; this is helpful for generating
more detailed SSL error messages.

Paired-With: Jacob Helwig <ja...@puppetlabs.com>
Signed-off-by: Nick Lewis <n...@puppetlabs.com>
---
Local-branch: ticket/2.7.x/7224
 lib/puppet/ssl/certificate.rb     |    6 ++++++
 spec/unit/ssl/certificate_spec.rb |   25 +++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/lib/puppet/ssl/certificate.rb b/lib/puppet/ssl/certificate.rb
index a0e6002..d57ac1a 100644
--- a/lib/puppet/ssl/certificate.rb
+++ b/lib/puppet/ssl/certificate.rb
@@ -27,6 +27,12 @@ class Puppet::SSL::Certificate < Puppet::SSL::Base
     [:s]
   end
 
+  def alternate_names
+    alts = content.extensions.find{|ext| ext.oid == "subjectAltName"}
+    return [] unless alts
+    alts.value.split(/,\s+/).map{|al| al.sub(/^DNS:/,'')}
+  end
+
   def expiration
     return nil unless content
     content.not_after
diff --git a/spec/unit/ssl/certificate_spec.rb 
b/spec/unit/ssl/certificate_spec.rb
index 0b635f2..de5cedf 100755
--- a/spec/unit/ssl/certificate_spec.rb
+++ b/spec/unit/ssl/certificate_spec.rb
@@ -89,6 +89,31 @@ describe Puppet::SSL::Certificate do
       @certificate.should respond_to(:content)
     end
 
+    describe "#alternate_names" do
+      before do
+        Puppet[:certdnsnames] = 'foo:bar:baz'
+        @csr            = OpenSSL::X509::Request.new
+        @csr.subject    = OpenSSL::X509::Name.new([['CN', 'quux']])
+        @csr.public_key = 
OpenSSL::PKey::RSA.generate(Puppet[:keylength]).public_key
+      end
+
+      it "should list all alternate names when the extension is present" do
+        cert = Puppet::SSL::CertificateFactory.new('server', @csr, @csr, 
14).result
+
+        @certificate = @class.from_s(cert.to_pem)
+
+        @certificate.alternate_names.should =~ ['foo', 'bar', 'baz', 'quux']
+      end
+
+      it "should return an empty list of names if the extension is absent" do
+        cert = Puppet::SSL::CertificateFactory.new('client', @csr, @csr, 
14).result
+
+        @certificate = @class.from_s(cert.to_pem)
+
+        @certificate.alternate_names.should == []
+      end
+    end
+
     it "should return a nil expiration if there is no actual certificate" do
       @certificate.stubs(:content).returns nil
 
-- 
1.7.5.1

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to puppet-dev@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-dev+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to