diff options
author | elijah <elijah@riseup.net> | 2014-10-21 17:32:28 -0700 |
---|---|---|
committer | elijah <elijah@riseup.net> | 2014-10-21 17:32:28 -0700 |
commit | a6b4ff1c21915475655a4a28c163904687d1035e (patch) | |
tree | 00502e075dc5ecafa10df9a3165033300658dd0b /vendor/certificate_authority/lib/certificate_authority/signing_request.rb | |
parent | 9e5572c7177ab10904aafbdcba99de0364e57db9 (diff) | |
download | leap_cli-a6b4ff1c21915475655a4a28c163904687d1035e.tar.gz leap_cli-a6b4ff1c21915475655a4a28c163904687d1035e.tar.bz2 |
fixed `leap cert csr` to add correct "Requested Extensions" attribute on the CSR.
Diffstat (limited to 'vendor/certificate_authority/lib/certificate_authority/signing_request.rb')
-rw-r--r-- | vendor/certificate_authority/lib/certificate_authority/signing_request.rb | 37 |
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 |