aboutsummaryrefslogtreecommitdiff
path: root/vendor/certificate_authority/lib/certificate_authority/signing_request.rb
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/certificate_authority/lib/certificate_authority/signing_request.rb')
-rw-r--r--vendor/certificate_authority/lib/certificate_authority/signing_request.rb37
1 files changed, 36 insertions, 1 deletions
diff --git a/vendor/certificate_authority/lib/certificate_authority/signing_request.rb b/vendor/certificate_authority/lib/certificate_authority/signing_request.rb
index 590d5be..72d9e2b 100644
--- a/vendor/certificate_authority/lib/certificate_authority/signing_request.rb
+++ b/vendor/certificate_authority/lib/certificate_authority/signing_request.rb
@@ -5,6 +5,29 @@ module CertificateAuthority
attr_accessor :raw_body
attr_accessor :openssl_csr
attr_accessor :digest
+ attr_accessor :attributes
+
+ def initialize()
+ @attributes = []
+ end
+
+ # Fake attribute for convenience because adding
+ # alternative names on a CSR is remarkably non-trivial.
+ def subject_alternative_names=(alt_names)
+ raise "alt_names must be an Array" unless alt_names.is_a?(Array)
+
+ factory = OpenSSL::X509::ExtensionFactory.new
+ name_list = alt_names.map{|m| "DNS:#{m}"}.join(",")
+ ext = factory.create_ext("subjectAltName",name_list,false)
+ ext_set = OpenSSL::ASN1::Set([OpenSSL::ASN1::Sequence([ext])])
+ attr = OpenSSL::X509::Attribute.new("extReq", ext_set)
+ @attributes << attr
+ end
+
+ def read_attributes_by_oid(*oids)
+ attributes.detect { |a| oids.include?(a.oid) }
+ end
+ protected :read_attributes_by_oid
def to_cert
cert = Certificate.new
@@ -12,6 +35,15 @@ module CertificateAuthority
cert.distinguished_name = @distinguished_name
end
cert.key_material = @key_material
+ if attribute = read_attributes_by_oid('extReq', 'msExtReq')
+ set = OpenSSL::ASN1.decode(attribute.value)
+ seq = set.value.first
+ seq.value.collect { |asn1ext| OpenSSL::X509::Extension.new(asn1ext).to_a }.each do |o, v, c|
+ Certificate::EXTENSIONS.each do |klass|
+ cert.extensions[klass::OPENSSL_IDENTIFIER] = klass.parse(v, c) if v && klass::OPENSSL_IDENTIFIER == o
+ end
+ end
+ end
cert
end
@@ -24,10 +56,12 @@ module CertificateAuthority
raise "Invalid DN in request" unless @distinguished_name.valid?
raise "CSR must have key material" if @key_material.nil?
raise "CSR must include a public key on key material" if @key_material.public_key.nil?
+ raise "Need a private key on key material for CSR generation" if @key_material.private_key.nil?
opensslcsr = OpenSSL::X509::Request.new
opensslcsr.subject = @distinguished_name.to_x509_name
opensslcsr.public_key = @key_material.public_key
+ opensslcsr.attributes = @attributes unless @attributes.nil?
opensslcsr.sign @key_material.private_key, OpenSSL::Digest::Digest.new(@digest || "SHA512")
opensslcsr
end
@@ -38,6 +72,7 @@ module CertificateAuthority
csr.distinguished_name = DistinguishedName.from_openssl openssl_csr.subject
csr.raw_body = raw_csr
csr.openssl_csr = openssl_csr
+ csr.attributes = openssl_csr.attributes
key_material = SigningRequestKeyMaterial.new
key_material.public_key = openssl_csr.public_key
csr.key_material = key_material
@@ -53,4 +88,4 @@ module CertificateAuthority
csr
end
end
-end \ No newline at end of file
+end