Class: Chef::Certificate
- Inherits:
-
Object
- Object
- Chef::Certificate
- Defined in:
- lib/chef/certificate.rb
Class Method Summary collapse
-
.gen_keypair(common_name, subject_alternative_name = nil) ⇒ Object
Creates a new key pair, and signs them with the signing certificate and key generated from generate_signing_ca above.
- .gen_validation_key(name = , key_file = , admin = false) ⇒ Object
-
.generate_signing_ca ⇒ Object
Generates a new CA Certificate and Key, and writes them out to Chef::Config and Chef::Config.
Class Method Details
.gen_keypair(common_name, subject_alternative_name = nil) ⇒ Object
Creates a new key pair, and signs them with the signing certificate and key generated from generate_signing_ca above.
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 |
# File 'lib/chef/certificate.rb', line 88 def gen_keypair(common_name, subject_alternative_name = nil) Chef::Log.info("Creating new key pair for #{common_name}") # generate client keypair client_keypair = OpenSSL::PKey::RSA.generate(2048) client_cert = OpenSSL::X509::Certificate.new ca_cert = OpenSSL::X509::Certificate.new(File.read(Chef::Config[:signing_ca_cert])) info = [ ["C", Chef::Config[:signing_ca_country]], ["ST", Chef::Config[:signing_ca_state]], ["L", Chef::Config[:signing_ca_location]], ["O", Chef::Config[:signing_ca_org]], ["OU", "Certificate Service"], ["CN", common_name ] ] client_cert.subject = OpenSSL::X509::Name.new(info) client_cert.issuer = ca_cert.subject client_cert.not_before = Time.now client_cert.not_after = Time.now + 10 * 365 * 24 * 60 * 60 # 10 years client_cert.public_key = client_keypair.public_key client_cert.serial = 1 client_cert.version = 3 ef = OpenSSL::X509::ExtensionFactory.new ef.subject_certificate = client_cert ef.issuer_certificate = ca_cert client_cert.extensions = [ ef.create_extension("basicConstraints", "CA:FALSE", true), ef.create_extension("subjectKeyIdentifier", "hash") ] client_cert.add_extension ef.create_extension("subjectAltName", subject_alternative_name) if subject_alternative_name client_cert.sign(OpenSSL::PKey::RSA.new(File.read(Chef::Config[:signing_ca_key])), OpenSSL::Digest::SHA1.new) return client_cert.public_key, client_keypair end |
.gen_validation_key(name = , key_file = , admin = false) ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/chef/certificate.rb', line 131 def gen_validation_key(name=Chef::Config[:validation_client_name], key_file=Chef::Config[:validation_key], admin=false) # Create the validation key api_client = Chef::ApiClient.new api_client.name(name) api_client.admin(admin) begin # If both the couch record and file exist, don't do anything. Otherwise, # re-generate the validation key. Chef::ApiClient.cdb_load(name) # The couch document was loaded successfully if we got to here; if we # can't also load the file on the filesystem, we'll regenerate it all. File.open(key_file, "r") do |file| end rescue Chef::Exceptions::CouchDBNotFound create_validation_key(api_client, key_file) rescue if $!.class.name =~ /Errno::/ Chef::Log.error("Error opening validation key: #{$!} -- destroying and regenerating") begin api_client.cdb_destroy rescue Bunny::ServerDownError => e # create_validation_key is gonna fail anyway, so let's just bail out. Chef::Log.fatal("Could not de-index (to rabbitmq) previous validation key - rabbitmq is down! Start rabbitmq then restart chef-server to re-generate it") raise end create_validation_key(api_client, key_file) else raise end end end |
.generate_signing_ca ⇒ Object
Generates a new CA Certificate and Key, and writes them out to Chef::Config and Chef::Config.
32 33 34 35 36 37 38 39 40 41 42 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 79 80 |
# File 'lib/chef/certificate.rb', line 32 def generate_signing_ca ca_cert_file = Chef::Config[:signing_ca_cert] ca_keypair_file = Chef::Config[:signing_ca_key] unless File.exists?(ca_cert_file) && File.exists?(ca_keypair_file) Chef::Log.info("Creating new signing certificate") [ ca_cert_file, ca_keypair_file ].each do |f| ca_basedir = File.dirname(f) FileUtils.mkdir_p ca_basedir end keypair = OpenSSL::PKey::RSA.generate(1024) ca_cert = OpenSSL::X509::Certificate.new ca_cert.version = 3 ca_cert.serial = 1 info = [ ["C", Chef::Config[:signing_ca_country]], ["ST", Chef::Config[:signing_ca_state]], ["L", Chef::Config[:signing_ca_location]], ["O", Chef::Config[:signing_ca_org]], ["OU", "Certificate Service"], ["CN", "#{Chef::Config[:signing_ca_domain]}/emailAddress=#{Chef::Config[:signing_ca_email]}"] ] ca_cert.subject = ca_cert.issuer = OpenSSL::X509::Name.new(info) ca_cert.not_before = Time.now ca_cert.not_after = Time.now + 10 * 365 * 24 * 60 * 60 # 10 years ca_cert.public_key = keypair.public_key ef = OpenSSL::X509::ExtensionFactory.new ef.subject_certificate = ca_cert ef.issuer_certificate = ca_cert ca_cert.extensions = [ ef.create_extension("basicConstraints", "CA:TRUE", true), ef.create_extension("subjectKeyIdentifier", "hash"), ef.create_extension("keyUsage", "cRLSign,keyCertSign", true), ] ca_cert.add_extension ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always") ca_cert.sign keypair, OpenSSL::Digest::SHA1.new File.open(ca_cert_file, "w") { |f| f.write ca_cert.to_pem } File.open(ca_keypair_file, File::WRONLY|File::EXCL|File::CREAT, 0600) { |f| f.write keypair.to_pem } if (Chef::Config[:signing_ca_user] && Chef::Config[:signing_ca_group]) FileUtils.chown(Chef::Config[:signing_ca_user], Chef::Config[:signing_ca_group], ca_keypair_file) end end self end |