Module: Watobo::CA
- Defined in:
- lib/watobo/core/ca.rb
Class Method Summary collapse
- .ca_ready? ⇒ Boolean
- .create_cert(cert_config) ⇒ Object
-
.create_csr(cert_config, keypair_file = nil) ⇒ Object
Creates a new Certificate Signing Request for the keypair in
keypair_file
, generating and saving new keypair if nil. -
.create_key(cert_config) ⇒ Object
Creates a new RSA key from
cert_config
. - .dh_key ⇒ Object
-
.sign_cert(cert_config, cert_file, csr_file) ⇒ Object
Signs the certificate described in
cert_config
andcsr_file
, saving it tocert_file
.
Class Method Details
.ca_ready? ⇒ Boolean
29 30 31 32 33 34 35 36 |
# File 'lib/watobo/core/ca.rb', line 29 def self.ca_ready? return false unless File.exists? @ca_config[:CA_dir] return false unless File.exists? @ca_config[:private_dir] return false unless File.exists? @ca_config[:fake_certs_dir] return false unless File.exists? @ca_config[:crl_dir] return false unless File.exists? @ca_config[:csr_dir] return true end |
.create_cert(cert_config) ⇒ Object
140 141 142 143 144 145 146 147 148 |
# File 'lib/watobo/core/ca.rb', line 140 def self.create_cert(cert_config) # puts " ... keypair ..." cert_keypair = create_key(cert_config) # puts "... csr ..." cert_csr = create_csr(cert_config, cert_keypair) # puts "... signing ..." signed_cert = sign_cert(cert_config, cert_keypair, cert_csr) return signed_cert, cert_keypair end |
.create_csr(cert_config, keypair_file = nil) ⇒ Object
Creates a new Certificate Signing Request for the keypair in keypair_file
, generating and saving new keypair if nil.
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
# File 'lib/watobo/core/ca.rb', line 350 def self.create_csr(cert_config, keypair_file = nil) keypair = nil target = cert_config[:hostname] || cert_config[:user] dest = @ca_config[:csr_dir] csr_file = File.join dest, "csr_#{target}.pem" csr_file.gsub!(/\*/,"_") return csr_file if File.exist? csr_file name = @ca_config[:name].dup case cert_config[:type] when 'server' then name << ['OU', 'CA'] name << ['CN', cert_config[:hostname]] when 'client' then name << ['CN', cert_config[:user]] name << ['emailAddress', cert_config[:email]] end #puts "Create Certificate Signing Request ..." # puts "Keypair File: " + keypair_file # puts name name = OpenSSL::X509::Name.new(name) # puts "- - -" if File.exists? keypair_file then # puts "Get Keypair from file #{keypair_file}" keypair = OpenSSL::PKey::RSA.new(File.read(keypair_file), cert_config[:password]) else # puts "Create Certificate KeyPair ..." keypair = create_key(cert_config) end # puts "Generating CSR for #{name}" if $DEBUG req = OpenSSL::X509::Request.new req.version = 0 req.subject = name req.public_key = keypair.public_key req.sign keypair, OpenSSL::Digest::MD5.new # puts "Writing CSR to #{csr_file}" if $DEBUG File.open csr_file, "w" do |f| f << req.to_pem end return csr_file end |
.create_key(cert_config) ⇒ Object
Creates a new RSA key from cert_config
.
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/watobo/core/ca.rb', line 153 def self.create_key(cert_config) #passwd_cb = nil target = cert_config[:hostname] || cert_config[:user] # puts target dest = @ca_config[:fake_certs_dir] # puts dest keypair_file = File.join(dest, (target + "_keypair.pem")) keypair_file.gsub!(/\*/,"_") return keypair_file if File.exist? keypair_file #puts "create_key: #{keypair_file}" begin Dir.mkdir dest #, 0700 rescue Errno::EEXIST # puts "directory exists" end if not File.exists?(keypair_file) then #puts "Generating RSA keypair" if $DEBUG keypair = OpenSSL::PKey::RSA.new 1024 # puts keypair.to_pem.class if cert_config[:password].nil? then # puts "no password for cert" # puts "Writing keypair to #{keypair_file}" if $DEBUG begin dummy = keypair.to_pem.split("\n") dummy.each do |line| line.strip! end fh = File.open( keypair_file, "wb" ) fh.write dummy.join("\n") fh.close rescue => bang puts "! Could not write keypair" puts bang puts bang.backtrace end else # passwd_cb = proc do cert_config[:password] end keypair_export = keypair.export OpenSSL::Cipher::DES.new(:EDE3, :CBC), cert_config[:password] # puts "Writing keypair to #{keypair_file}" if $DEBUG #File.open keypair_file, "w" do |f| # f << keypair_export #end begin fh = File.open( keypair_file, "w" ) fh.puts keypair_export fh.close rescue => bang puts "! Could not write keypair" puts bang puts bang.backtrace end end end return keypair_file end |
.dh_key ⇒ Object
398 399 400 401 402 403 404 405 406 407 408 409 |
# File 'lib/watobo/core/ca.rb', line 398 def self.dh_key dh_filename = File.join(@ca_config[:CA_dir], "watobo_dh.key") unless File.exist? dh_filename #puts "* no dh key file found" File.open(dh_filename,"w") do |fh| puts "* creating SSL key (DH 1024) ... " fh.write OpenSSL::PKey::DH.new(1024).to_pem print " DONE\r\n" end end OpenSSL::PKey::DH.new(File.read(dh_filename)) end |
.sign_cert(cert_config, cert_file, csr_file) ⇒ Object
Signs the certificate described in cert_config
and csr_file
, saving it to cert_file
.
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/watobo/core/ca.rb', line 220 def self.sign_cert(cert_config, cert_file, csr_file) target = cert_config[:hostname] || cert_config[:user] dest = @ca_config[:fake_certs_dir] cert_file = File.join dest, "#{target}_cert.pem" cert_file.gsub!(/\*/,"_") return cert_file if File.exist? cert_file csr = OpenSSL::X509::Request.new File.read(csr_file) raise "CSR sign verification failed." unless csr.verify csr.public_key if csr.public_key.n.num_bits < @ca_config[:cert_key_length_min] then raise "Key length too short" end if csr.public_key.n.num_bits > @ca_config[:cert_key_length_max] then raise "Key length too long" end if csr.subject.to_a[0, @ca_config[:name].size] != @ca_config[:name] then raise "DN does not match" end # Only checks signature here. You must verify CSR according to your # CP/CPS. # CA setup puts "Reading CA cert from #{@ca_config[:cert_file]}" if $DEBUG ca = OpenSSL::X509::Certificate.new File.read(@ca_config[:cert_file]) puts "Reading CA keypair from #{@ca_config[:keypair_file]}" if $DEBUG ca_keypair = OpenSSL::PKey::RSA.new File.read(@ca_config[:keypair_file]), @ca_config[:password] serial = File.read(@ca_config[:serial_file]).chomp.hex File.open @ca_config[:serial_file], "w" do |f| f << "%04X" % (serial + 1) end puts "Generating cert" if $DEBUG cert = OpenSSL::X509::Certificate.new from = Time.now cert.subject = csr.subject cert.issuer = ca.subject cert.not_before = from cert.not_after = from + @ca_config[:cert_days] * 24 * 60 * 60 cert.public_key = csr.public_key cert.serial = serial cert.version = 2 # X509v3 basic_constraint = nil key_usage = [] ext_key_usage = [] case cert_config[:type] when "ca" then basic_constraint = "CA:TRUE" key_usage << "cRLSign" << "keyCertSign" when "terminalsubca" then basic_constraint = "CA:TRUE,pathlen:0" key_usage << "cRLSign" << "keyCertSign" when "server" then basic_constraint = "CA:FALSE" key_usage << "digitalSignature" << "keyEncipherment" ext_key_usage << "serverAuth" when "ocsp" then basic_constraint = "CA:FALSE" key_usage << "nonRepudiation" << "digitalSignature" ext_key_usage << "serverAuth" << "OCSPSigning" when "client" then basic_constraint = "CA:FALSE" key_usage << "nonRepudiation" << "digitalSignature" << "keyEncipherment" ext_key_usage << "clientAuth" << "emailProtection" else raise "unknonw cert type \"#{cert_config[:type]}\"" end ef = OpenSSL::X509::ExtensionFactory.new ef.subject_certificate = cert ef.issuer_certificate = ca ex = [] ex << ef.create_extension("basicConstraints", basic_constraint, true) ex << ef.create_extension("nsComment", "Ruby/OpenSSL Generated Certificate") ex << ef.create_extension("subjectKeyIdentifier", "hash") #ex << ef.create_extension("nsCertType", "client,email") unless key_usage.empty? then ex << ef.create_extension("keyUsage", key_usage.join(",")) end #ex << ef.create_extension("authorityKeyIdentifier", # "keyid:always,issuer:always") #ex << ef.create_extension("authorityKeyIdentifier", "keyid:always") unless ext_key_usage.empty? then ex << ef.create_extension("extendedKeyUsage", ext_key_usage.join(",")) end if @ca_config[:cdp_location] then ex << ef.create_extension("crlDistributionPoints", @ca_config[:cdp_location]) end if @ca_config[:ocsp_location] then ex << ef.create_extension("authorityInfoAccess", "OCSP;" << @ca_config[:ocsp_location]) end cert.extensions = ex cert.sign ca_keypair, OpenSSL::Digest::SHA1.new # backup_cert_file = @ca_config[:backup_certs_dir] + "/cert_#{cert.serial}.pem" # puts "Writing backup cert to #{backup_cert_file}" if $DEBUG # File.open backup_cert_file, "w", 0644 do |f| # f << cert.to_pem # end # Write cert puts "Writing cert to #{cert_file}" File.open cert_file, "w", 0644 do |f| f << cert.to_pem end return cert_file end |