Module: Watobo::CA
- Defined in:
- lib/watobo/core/ca.rb
Overview
:nodoc: all
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
23 24 25 26 27 28 29 30 |
# File 'lib/watobo/core/ca.rb', line 23 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
139 140 141 142 143 144 145 146 147 |
# File 'lib/watobo/core/ca.rb', line 139 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.
349 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 |
# File 'lib/watobo/core/ca.rb', line 349 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!(/\*/,"_") name = @ca_config[:name].dup case cert_config[:type] when 'server' then # name << ['OU', 'Watobo CA'] name << ['CN', cert_config[:hostname]] #name << ['CN', "WATOBO"] when 'client' then name << ['CN', cert_config[:user]] name << ['emailAddress', cert_config[:email]] end name = OpenSSL::X509::Name.new(name) if File.exists? keypair_file then keypair = OpenSSL::PKey::RSA.new(File.read(keypair_file), cert_config[:password]) else keypair = create_key(cert_config) end req = OpenSSL::X509::Request.new req.version = 0 req.subject = name req.public_key = keypair.public_key req.sign keypair, OpenSSL::Digest::MD5.new 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
.
152 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 |
# File 'lib/watobo/core/ca.rb', line 152 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
10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/watobo/core/ca.rb', line 10 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| print "* 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
.
219 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 |
# File 'lib/watobo/core/ca.rb', line 219 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 |