Class: PuppetECDSAGen
- Defined in:
- modules/puppetmaster/files/puppet_ecdsacert.rb
Overview
ECDSA certificates generator class Generates the cert, the CSR, and sends the signing request to the puppetmaster
Class Attribute Summary collapse
-
.confkeys ⇒ Object
Returns the value of attribute confkeys.
Instance Method Summary collapse
- #cleanup ⇒ Object
- #csr_alt_names(csr) ⇒ Object
- #csr_path ⇒ Object
-
#generate_csr(ec_domain_key) ⇒ Object
Generates and writes out the CSR.
-
#generate_ecdsa_key ⇒ Object
Generates and writes out the private key.
- #https ⇒ Object
-
#initialize(args) ⇒ PuppetECDSAGen
constructor
A new instance of PuppetECDSAGen.
- #parse_config(filename) ⇒ Object
- #sign ⇒ Object
- #subject ⇒ Object
Constructor Details
#initialize(args) ⇒ PuppetECDSAGen
Returns a new instance of PuppetECDSAGen.
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 |
# File 'modules/puppetmaster/files/puppet_ecdsacert.rb', line 47 def initialize(args) @config = {} self.class.confkeys.each do |key| @config[key] = args[key] end parse_config args[:configfile] if args[:configfile] @common_name = args[:common_name] @all_alt_names = args[:altnames].map do |name| begin _ = IPAddr.new name "IP:#{name}" rescue IPAddr::InvalidAddressError "DNS:#{name}" end end # We need the CN in the SAN if we want to validate against it @all_alt_names << "DNS:#{@common_name}" Log.info "Creating and signing ECDSA certificate for #{@common_name}" Log.debug "subjectAltNames: #{@all_alt_names}" Log.debug "Using NIST curve #{@config[:asn1_oid]}" end |
Class Attribute Details
.confkeys ⇒ Object
Returns the value of attribute confkeys.
43 44 45 |
# File 'modules/puppetmaster/files/puppet_ecdsacert.rb', line 43 def confkeys @confkeys end |
Instance Method Details
#cleanup ⇒ Object
163 164 165 166 |
# File 'modules/puppetmaster/files/puppet_ecdsacert.rb', line 163 def cleanup Log.debug "Removing file #{csr_path} if present" File.delete csr_path if File.exists? csr_path end |
#csr_alt_names(csr) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'modules/puppetmaster/files/puppet_ecdsacert.rb', line 122 def csr_alt_names(csr) extensions = [ OpenSSL::X509::ExtensionFactory.new.create_extension( 'subjectAltName', @all_alt_names.join(',') ) ] # add SAN extension to the CSR attribute_values = OpenSSL::ASN1::Set [OpenSSL::ASN1::Sequence(extensions)] [ OpenSSL::X509::Attribute.new('extReq', attribute_values), OpenSSL::X509::Attribute.new('msExtReq', attribute_values) ].each do |attribute| csr.add_attribute attribute end end |
#csr_path ⇒ Object
93 94 95 |
# File 'modules/puppetmaster/files/puppet_ecdsacert.rb', line 93 def csr_path File.join '/tmp', "#{@common_name}.csr.pem" end |
#generate_csr(ec_domain_key) ⇒ Object
Generates and writes out the CSR
98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'modules/puppetmaster/files/puppet_ecdsacert.rb', line 98 def generate_csr(ec_domain_key) ec_public = OpenSSL::PKey::EC.new(@config[:asn1_oid]) ec_public.public_key = ec_domain_key.public_key csr = OpenSSL::X509::Request.new csr.version = 0 csr.subject = subject csr.public_key = ec_public csr_alt_names csr csr.sign ec_domain_key, OpenSSL::Digest::SHA256.new Log.debug "Generated CSR at #{csr_path}" File.open(csr_path, "w", 0o0644) {|f| f.write(csr.to_pem)} end |
#generate_ecdsa_key ⇒ Object
Generates and writes out the private key
83 84 85 86 87 88 89 90 91 |
# File 'modules/puppetmaster/files/puppet_ecdsacert.rb', line 83 def generate_ecdsa_key ec_domain_key = OpenSSL::PKey::EC.new(@config[:asn1_oid]) ec_domain_key.generate_key private_key_file = File.join @config[:key_dir], "#{@common_name}.key" Log.info "Storing the private key in #{private_key_file}" File.open(private_key_file, 'w', 0o0640) { |f| f.write(ec_domain_key.to_pem) } ec_domain_key end |
#https ⇒ Object
138 139 140 141 142 143 144 145 146 |
# File 'modules/puppetmaster/files/puppet_ecdsacert.rb', line 138 def https http = Net::HTTP.new(@config[:puppetca], 8140) http.use_ssl = true # TODO: fix this http.verify_mode = OpenSSL::SSL::VERIFY_NONE http end |
#parse_config(filename) ⇒ Object
73 74 75 76 77 78 79 80 |
# File 'modules/puppetmaster/files/puppet_ecdsacert.rb', line 73 def parse_config(filename) data = File.read filename conffile = YAML.load(data) conffile.each do |key, val| k = key.to_sym @config[k] = val if self.class.confkeys.include? k end end |
#sign ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'modules/puppetmaster/files/puppet_ecdsacert.rb', line 148 def sign req = Net::HTTP::Put.new("/production/certificate_request/#{@common_name}", 'Content-Type' => 'text/plain') req.body = File.read csr_path Log.info "Submitting CSR for signing to #{@config[:puppetca]}" resp, _ = https.request(req) unless resp.code == '200' fail(PuppetECDSAGenError, format('Signing request to %s failed with code %s: %s', @config[:puppetca], resp.code, resp.body) ) end Log.info "CSR request succeeded" end |
#subject ⇒ Object
111 112 113 114 115 116 117 118 119 120 |
# File 'modules/puppetmaster/files/puppet_ecdsacert.rb', line 111 def subject subject = OpenSSL::X509::Name.new [ ['CN', @common_name], ['O', @config[:organization]], ['C', @config[:country]], ['ST', @config[:state]], ['L', @config[:locality]] ] subject end |