Class: Ronin::Support::Crypto::Cert
- Inherits:
-
OpenSSL::X509::Certificate
- Object
- OpenSSL::X509::Certificate
- Ronin::Support::Crypto::Cert
- Defined in:
- lib/ronin/support/crypto/cert.rb
Overview
Represents a X509 or TLS certificate.
Defined Under Namespace
Classes: Name
Constant Summary collapse
- ONE_YEAR =
One year in seconds
60 * 60 * 24 * 365
Class Method Summary collapse
-
.generate(version: 2, serial: 0, not_before: Time.now, not_after: not_before + ONE_YEAR, subject: nil, extensions: nil, key:, ca_cert: nil, ca_key: nil, ca: false, subject_alt_names: nil, signing_hash: :sha256) ⇒ Cert
Generates and signs a new certificate.
-
.load(buffer) ⇒ Cert
Parses the PEM encoded certificate.
-
.load_file(path) ⇒ Cert
Loads the certificate from the file.
-
.Name(name) ⇒ Cert::Name
Coerces a value into a Name object.
-
.parse(string) ⇒ Cert
Parses the PEM encoded certificate string.
Instance Method Summary collapse
-
#common_name ⇒ String?
The subjects common name (
CN
) entry. -
#extension_names ⇒ Array<String>
The extension OID names.
-
#extension_value(oid) ⇒ String?
Gets the value for the extension with the matching OID.
-
#extensions_hash ⇒ Hash{String => OpenSSL::X509::Extension}
Converts the certificate's extensions into a Hash.
-
#issuer ⇒ Name?
The issuer of the certificate.
-
#save(path, encoding: :pem) ⇒ Object
Saves the certificate to the given path.
-
#subject ⇒ Name?
The subject of the certificate.
-
#subject_alt_name ⇒ String?
Retrieves the
subjectAltName
extension and parses it's contents. -
#subject_alt_names ⇒ Array<String>?
Retrieves the
subjectAltName
extension and parses it's value.
Class Method Details
.generate(version: 2, serial: 0, not_before: Time.now, not_after: not_before + ONE_YEAR, subject: nil, extensions: nil, key:, ca_cert: nil, ca_key: nil, ca: false, subject_alt_names: nil, signing_hash: :sha256) ⇒ Cert
Generates and signs a new certificate.
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 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 |
# File 'lib/ronin/support/crypto/cert.rb', line 352 def self.generate(version: 2, serial: 0, not_before: Time.now, not_after: not_before + ONE_YEAR, subject: nil, extensions: nil, # signing arguments key: , ca_cert: nil, ca_key: nil, ca: false, subject_alt_names: nil, signing_hash: :sha256) cert = new cert.version = version cert.serial = if ca_cert then ca_cert.serial + 1 else serial end cert.not_before = not_before cert.not_after = not_after cert.public_key = case key when OpenSSL::PKey::EC then key else key.public_key end cert.subject = Name(subject) if subject cert.issuer = if ca_cert then ca_cert.subject else cert.subject end if subject_alt_names subject_alt_name = subject_alt_names.map { |alt_name| if alt_name.match?(Network::IP::REGEX) "IP:#{alt_name}" else "DNS:#{alt_name}" end }.join(', ') extensions ||= {} extensions = extensions.merge('subjectAltName' => subject_alt_name) end if ca extensions ||= {} extensions = extensions.merge('basicConstraints' => ['CA:TRUE', true]) end if extensions extension_factory = OpenSSL::X509::ExtensionFactory.new extension_factory.subject_certificate = cert extension_factory.issuer_certificate = ca_cert || cert extensions.each do |name,(value,critical)| ext = extension_factory.create_extension(name,value,critical) cert.add_extension(ext) end end signing_key = ca_key || key signing_digest = OpenSSL::Digest.const_get(signing_hash.upcase).new cert.sign(signing_key,signing_digest) return cert end |
.load(buffer) ⇒ Cert
Parses the PEM encoded certificate.
226 227 228 |
# File 'lib/ronin/support/crypto/cert.rb', line 226 def self.load(buffer) new(buffer) end |
.load_file(path) ⇒ Cert
Loads the certificate from the file.
239 240 241 |
# File 'lib/ronin/support/crypto/cert.rb', line 239 def self.load_file(path) new(File.read(path)) end |
.Name(name) ⇒ Cert::Name
Coerces a value into a Name object.
190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/ronin/support/crypto/cert.rb', line 190 def self.Name(name) case name when String then Name.parse(name) when Hash then Name.build(**name) when Name then name when OpenSSL::X509::Name new_name = Name.allocate new_name.send(:initialize_copy,name) new_name else raise(ArgumentError,"value must be either a String, Hash, or a OpenSSL::X509::Name object: #{name.inspect}") end end |
.parse(string) ⇒ Cert
Parses the PEM encoded certificate string.
213 214 215 |
# File 'lib/ronin/support/crypto/cert.rb', line 213 def self.parse(string) new(string) end |
Instance Method Details
#common_name ⇒ String?
The subjects common name (CN
) entry.
447 448 449 450 451 |
# File 'lib/ronin/support/crypto/cert.rb', line 447 def common_name if (subject = self.subject) subject.common_name end end |
#extension_names ⇒ Array<String>
The extension OID names.
458 459 460 |
# File 'lib/ronin/support/crypto/cert.rb', line 458 def extension_names extensions.map(&:oid) end |
#extension_value(oid) ⇒ String?
Gets the value for the extension with the matching OID.
481 482 483 484 485 |
# File 'lib/ronin/support/crypto/cert.rb', line 481 def extension_value(oid) if (ext = find_extension(oid)) ext.value end end |
#extensions_hash ⇒ Hash{String => OpenSSL::X509::Extension}
Converts the certificate's extensions into a Hash.
468 469 470 |
# File 'lib/ronin/support/crypto/cert.rb', line 468 def extensions_hash extensions.to_h { |ext| [ext.oid, ext] } end |
#issuer ⇒ Name?
The issuer of the certificate.
425 426 427 428 429 |
# File 'lib/ronin/support/crypto/cert.rb', line 425 def issuer @issuer ||= if (issuer = super) Cert::Name(issuer) end end |
#save(path, encoding: :pem) ⇒ Object
Saves the certificate to the given path.
527 528 529 530 531 532 533 534 535 536 |
# File 'lib/ronin/support/crypto/cert.rb', line 527 def save(path, encoding: :pem) exported = case encoding when :pem then to_pem when :der then to_der else raise(ArgumentError,"encoding: keyword argument (#{encoding.inspect}) must be either :pem or :der") end File.write(path,exported) end |
#subject ⇒ Name?
The subject of the certificate.
436 437 438 439 440 |
# File 'lib/ronin/support/crypto/cert.rb', line 436 def subject @subject ||= if (subject = super) Cert::Name(subject) end end |
#subject_alt_name ⇒ String?
Retrieves the subjectAltName
extension and parses it's contents.
494 495 496 |
# File 'lib/ronin/support/crypto/cert.rb', line 494 def subject_alt_name extension_value('subjectAltName') end |