Class: Chef::Knife::WindowsCertGenerate
- Inherits:
-
Chef::Knife
- Object
- Chef::Knife
- Chef::Knife::WindowsCertGenerate
- Defined in:
- lib/chef/knife/windows_cert_generate.rb
Instance Attribute Summary collapse
-
#hostname ⇒ Object
Returns the value of attribute hostname.
-
#thumbprint ⇒ Object
Returns the value of attribute thumbprint.
Instance Method Summary collapse
- #certificates_already_exist?(file_path) ⇒ Boolean
- #generate_certificate(rsa_key) ⇒ Object
- #generate_keypair ⇒ Object
- #prompt_for_passphrase ⇒ Object
- #run ⇒ Object
- #write_certificate_to_file(cert, file_path, rsa_key) ⇒ Object
Instance Attribute Details
#hostname ⇒ Object
Returns the value of attribute hostname.
25 26 27 |
# File 'lib/chef/knife/windows_cert_generate.rb', line 25 def hostname @hostname end |
#thumbprint ⇒ Object
Returns the value of attribute thumbprint.
25 26 27 |
# File 'lib/chef/knife/windows_cert_generate.rb', line 25 def thumbprint @thumbprint end |
Instance Method Details
#certificates_already_exist?(file_path) ⇒ Boolean
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/chef/knife/windows_cert_generate.rb', line 114 def certificates_already_exist?(file_path) certs_exists = false %w{pem pfx b64}.each do |extn| unless Dir.glob("#{file_path}.*#{extn}").empty? certs_exists = true break end end if certs_exists begin confirm("Do you really want to overwrite existing certificates") rescue SystemExit # Need to handle this as confirming with N/n raises SystemExit exception exit! end end end |
#generate_certificate(rsa_key) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/chef/knife/windows_cert_generate.rb', line 82 def generate_certificate(rsa_key) @hostname = config[:hostname] if config[:hostname] # Create a self-signed X509 certificate from the rsa_key (unencrypted) cert = OpenSSL::X509::Certificate.new cert.version = 2 cert.serial = Random.rand(65534) + 1 # 2 digit byte range random number for better security aspect cert.subject = OpenSSL::X509::Name.parse "/CN=#{@hostname}" cert.issuer = cert.subject cert.public_key = rsa_key.public_key cert.not_before = Time.now cert.not_after = cert.not_before + 2 * 365 * config[:cert_validity].to_i * 60 * 60 # 2 years validity ef = OpenSSL::X509::ExtensionFactory.new ef.subject_certificate = cert ef.issuer_certificate = cert cert.add_extension(ef.create_extension("subjectKeyIdentifier", "hash", false)) cert.add_extension(ef.create_extension("authorityKeyIdentifier", "keyid:always", false)) cert.add_extension(ef.create_extension("extendedKeyUsage", "1.3.6.1.5.5.7.3.1", false)) cert.sign(rsa_key, OpenSSL::Digest.new("SHA1")) @thumbprint = OpenSSL::Digest::SHA1.new(cert.to_der) cert end |
#generate_keypair ⇒ Object
64 65 66 |
# File 'lib/chef/knife/windows_cert_generate.rb', line 64 def generate_keypair OpenSSL::PKey::RSA.new(config[:key_length].to_i) end |
#prompt_for_passphrase ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/chef/knife/windows_cert_generate.rb', line 68 def prompt_for_passphrase passphrase = "" begin print "Passphrases do not match. Try again.\n" unless passphrase.empty? print "Enter certificate passphrase (empty for no passphrase):" passphrase = STDIN.gets return passphrase.strip if passphrase == "\n" print "Enter same passphrase again:" confirm_passphrase = STDIN.gets end until passphrase == confirm_passphrase passphrase.strip end |
#run ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/chef/knife/windows_cert_generate.rb', line 132 def run STDOUT.sync = STDERR.sync = true # takes user specified first cli value as a destination file path for generated cert. file_path = @name_args.empty? ? config[:output_file].sub(/\.(\w+)$/, "") : @name_args.first # check if certs already exists at given file path certificates_already_exist? file_path begin filename = File.basename(file_path) rsa_key = generate_keypair cert = generate_certificate rsa_key write_certificate_to_file cert, file_path, rsa_key ui.info "Generated Certificates:" ui.info "- #{filename}.pfx - PKCS12 format key pair. Contains public and private keys, can be used with an SSL server." ui.info "- #{filename}.b64 - Base64 encoded PKCS12 key pair. Contains public and private keys, used by some cloud provider API's to configure SSL servers." ui.info "- #{filename}.pem - Base64 encoded public certificate only. Required by the client to connect to the server." ui.info "Certificate Thumbprint: #{@thumbprint.to_s.upcase}" rescue => e puts "ERROR: + #{e}" end end |
#write_certificate_to_file(cert, file_path, rsa_key) ⇒ Object
106 107 108 109 110 111 112 |
# File 'lib/chef/knife/windows_cert_generate.rb', line 106 def write_certificate_to_file(cert, file_path, rsa_key) File.open(file_path + ".pem", "wb") { |f| f.print cert.to_pem } config[:cert_passphrase] = prompt_for_passphrase unless config[:cert_passphrase] pfx = OpenSSL::PKCS12.create("#{config[:cert_passphrase]}", "winrmcert", rsa_key, cert) File.open(file_path + ".pfx", "wb") { |f| f.print pfx.to_der } File.open(file_path + ".b64", "wb") { |f| f.print Base64.strict_encode64(pfx.to_der) } end |