Class: Puppet::SSL::CertificateRequest
- Extended by:
- Indirector
- Defined in:
- lib/vendor/puppet/ssl/certificate_request.rb
Overview
Manage certificate requests.
Defined Under Namespace
Modules: AutoSigner Classes: Ca, DisabledCa, File, Rest
Constant Summary
Constants included from Indirector
Constants inherited from Base
Base::SEPARATOR, Base::VALID_CERTNAME
Instance Attribute Summary
Attributes inherited from Base
Class Method Summary collapse
-
.from_s(string) ⇒ Object
Convert a string into an instance.
-
.supported_formats ⇒ Object
Because of how the format handler class is included, this can’t be in the base class.
Instance Method Summary collapse
- #extension_factory ⇒ Object
-
#generate(key, options = {}) ⇒ Object
How to create a certificate request with our system defaults.
-
#request_extensions ⇒ Object
Return the set of extensions requested on this CSR, in a form designed to be useful to Ruby: a hash.
- #subject_alt_names ⇒ Object
Methods included from Indirector
Methods inherited from Base
#ca?, #fingerprint, from_multiple_s, #initialize, #read, to_multiple_s, #to_s, #to_text, validate_certname, wrapped_class, wraps
Constructor Details
This class inherits a constructor from Puppet::SSL::Base
Class Method Details
.from_s(string) ⇒ Object
Convert a string into an instance.
24 25 26 27 28 29 30 |
# File 'lib/vendor/puppet/ssl/certificate_request.rb', line 24 def self.from_s(string) instance = wrapped_class.new(string) name = instance.subject.to_s.sub(/\/CN=/i, '').downcase result = new(name) result.content = instance result end |
.supported_formats ⇒ Object
Because of how the format handler class is included, this can’t be in the base class.
34 35 36 |
# File 'lib/vendor/puppet/ssl/certificate_request.rb', line 34 def self.supported_formats [:s] end |
Instance Method Details
#extension_factory ⇒ Object
38 39 40 |
# File 'lib/vendor/puppet/ssl/certificate_request.rb', line 38 def extension_factory @ef ||= OpenSSL::X509::ExtensionFactory.new end |
#generate(key, options = {}) ⇒ Object
How to create a certificate request with our system defaults.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/vendor/puppet/ssl/certificate_request.rb', line 43 def generate(key, = {}) Puppet.info "Creating a new SSL certificate request for #{name}" # Support either an actual SSL key, or a Puppet key. key = key.content if key.is_a?(Puppet::SSL::Key) # If we're a CSR for the CA, then use the real ca_name, rather than the # fake 'ca' name. This is mostly for backward compatibility with 0.24.x, # but it's also just a good idea. common_name = name == Puppet::SSL::CA_NAME ? Puppet.settings[:ca_name] : name csr = OpenSSL::X509::Request.new csr.version = 0 csr.subject = OpenSSL::X509::Name.new([["CN", common_name]]) csr.public_key = key.public_key if [:dns_alt_names] then names = [:dns_alt_names].split(/\s*,\s*/).map(&:strip) + [name] names = names.sort.uniq.map {|name| "DNS:#{name}" }.join(", ") names = extension_factory.create_extension("subjectAltName", names, false) extReq = OpenSSL::ASN1::Set([OpenSSL::ASN1::Sequence([names])]) # We only support the standard request extensions. If you really need # msExtReq support, let us know and we can restore them. --daniel 2011-10-10 csr.add_attribute(OpenSSL::X509::Attribute.new("extReq", extReq)) end csr.sign(key, OpenSSL::Digest::MD5.new) raise Puppet::Error, "CSR sign verification failed; you need to clean the certificate request for #{name} on the server" unless csr.verify(key.public_key) @content = csr Puppet.info "Certificate Request fingerprint (md5): #{fingerprint}" @content end |
#request_extensions ⇒ Object
Return the set of extensions requested on this CSR, in a form designed to be useful to Ruby: a hash. Which, not coincidentally, you can pass successfully to the OpenSSL constructor later, if you want.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/vendor/puppet/ssl/certificate_request.rb', line 83 def request_extensions raise Puppet::Error, "CSR needs content to extract fields" unless @content # Prefer the standard extReq, but accept the Microsoft specific version as # a fallback, if the standard version isn't found. ext = @content.attributes.find {|x| x.oid == "extReq" } or @content.attributes.find {|x| x.oid == "msExtReq" } return [] unless ext # Assert the structure and extract the names into an array of arrays. unless ext.value.is_a? OpenSSL::ASN1::Set raise Puppet::Error, "In #{ext.oid}, expected Set but found #{ext.value.class}" end unless ext.value.value.is_a? Array raise Puppet::Error, "In #{ext.oid}, expected Set[Array] but found #{ext.value.value.class}" end unless ext.value.value.length == 1 raise Puppet::Error, "In #{ext.oid}, expected Set[Array[...]], but found #{ext.value.value.length} items in the array" end san = ext.value.value.first unless san.is_a? OpenSSL::ASN1::Sequence raise Puppet::Error, "In #{ext.oid}, expected Set[Array[Sequence[...]]], but found #{san.class}" end san = san.value # OK, now san should be the array of items, validate that... index = -1 san.map do |name| index += 1 unless name.is_a? OpenSSL::ASN1::Sequence raise Puppet::Error, "In #{ext.oid}, expected request extension record #{index} to be a Sequence, but found #{name.class}" end name = name.value # OK, turn that into an extension, to unpack the content. Lovely that # we have to swap the order of arguments to the underlying method, or # perhaps that the ASN.1 representation chose to pack them in a # strange order where the optional component comes *earlier* than the # fixed component in the sequence. case name.length when 2 ev = OpenSSL::X509::Extension.new(name[0].value, name[1].value) { "oid" => ev.oid, "value" => ev.value } when 3 ev = OpenSSL::X509::Extension.new(name[0].value, name[2].value, name[1].value) { "oid" => ev.oid, "value" => ev.value, "critical" => ev.critical? } else raise Puppet::Error, "In #{ext.oid}, expected extension record #{index} to have two or three items, but found #{name.length}" end end.flatten end |
#subject_alt_names ⇒ Object
141 142 143 144 145 146 147 148 |
# File 'lib/vendor/puppet/ssl/certificate_request.rb', line 141 def subject_alt_names @subject_alt_names ||= request_extensions. select {|x| x["oid"] = "subjectAltName" }. map {|x| x["value"].split(/\s*,\s*/) }. flatten. sort. uniq end |