Class: CsrPeek::Certificate
- Inherits:
-
Data
- Object
- Data
- CsrPeek::Certificate
- Includes:
- Inspectable
- Defined in:
- lib/csr_peek/certificate.rb
Overview
A friendly, read-only view over an OpenSSL::X509::Certificate.
An immutable value object: build one with CsrPeek.parse_certificate (which returns nil for junk input) or Certificate.from_openssl. Parsed facts are resolved once into frozen members. This class inspects; it does not build trust chains or perform revocation checks.
Constant Summary
Constants included from Inspectable
Inspectable::MIN_DSA_BITS, Inspectable::MIN_EC_BITS, Inspectable::MIN_RSA_BITS, Inspectable::STRONG_UNSIZED_TYPES
Instance Attribute Summary collapse
-
#basic_constraints ⇒ Object
readonly
Returns the value of attribute basic_constraints.
-
#ec_curve ⇒ Object
readonly
Returns the value of attribute ec_curve.
-
#extended_key_usage ⇒ Object
readonly
Returns the value of attribute extended_key_usage.
-
#issuer ⇒ Object
readonly
Returns the value of attribute issuer.
-
#key_bits ⇒ Object
readonly
Returns the value of attribute key_bits.
-
#key_type ⇒ Object
readonly
Returns the value of attribute key_type.
-
#key_usage ⇒ Object
readonly
Returns the value of attribute key_usage.
-
#openssl ⇒ Object
readonly
Returns the value of attribute openssl.
-
#public_key ⇒ Object
readonly
Returns the value of attribute public_key.
-
#subject ⇒ Object
readonly
Returns the value of attribute subject.
-
#subject_alt_names ⇒ Object
readonly
Returns the value of attribute subject_alt_names.
-
#subject_components ⇒ Object
readonly
Returns the value of attribute subject_components.
Class Method Summary collapse
Instance Method Summary collapse
-
#acceptable?(policy = Policy::BASELINE) ⇒ Boolean
True when both the key and the signature satisfy the issuance policy.
-
#ca? ⇒ Boolean
Whether this certificate may act as a CA (basicConstraints CA:TRUE).
-
#expired?(now = Time.now) ⇒ Boolean
True when now is after not_after.
- #not_after ⇒ Object
- #not_before ⇒ Object
- #not_yet_valid?(now = Time.now) ⇒ Boolean
-
#path_length ⇒ Object
The pathLenConstraint from basicConstraints, or nil when unset.
-
#policy_violations(policy = Policy::BASELINE) ⇒ Object
All policy reasons this certificate is unacceptable, as symbols; empty when it passes.
- #self_signed? ⇒ Boolean
-
#serial ⇒ Object
Serial as lower-case hex, zero-padded to an even number of digits.
-
#signature_algorithm ⇒ Object
The signature algorithm name, e.g.
- #to_h ⇒ Object
-
#valid_at?(now = Time.now) ⇒ Boolean
True when now falls within [not_before, not_after].
-
#version ⇒ Object
X.509 version as the human-facing number: 1, 2, or 3 (the DER field is zero-based, so v3 is stored as 2).
-
#weak_signature?(policy = Policy::BASELINE) ⇒ Boolean
True when signed with a hash the policy rejects (MD5/SHA-1 by default).
Methods included from Inspectable
#==, #acceptable_key?, #all_names, #common_name, #dns_names, #fingerprint, #hash, #inspect, #ip_addresses, #key_policy_violations, #spki_fingerprint, #weak_key?
Instance Attribute Details
#basic_constraints ⇒ Object (readonly)
Returns the value of attribute basic_constraints
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def basic_constraints @basic_constraints end |
#ec_curve ⇒ Object (readonly)
Returns the value of attribute ec_curve
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def ec_curve @ec_curve end |
#extended_key_usage ⇒ Object (readonly)
Returns the value of attribute extended_key_usage
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def extended_key_usage @extended_key_usage end |
#issuer ⇒ Object (readonly)
Returns the value of attribute issuer
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def issuer @issuer end |
#key_bits ⇒ Object (readonly)
Returns the value of attribute key_bits
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def key_bits @key_bits end |
#key_type ⇒ Object (readonly)
Returns the value of attribute key_type
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def key_type @key_type end |
#key_usage ⇒ Object (readonly)
Returns the value of attribute key_usage
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def key_usage @key_usage end |
#openssl ⇒ Object (readonly)
Returns the value of attribute openssl
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def openssl @openssl end |
#public_key ⇒ Object (readonly)
Returns the value of attribute public_key
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def public_key @public_key end |
#subject ⇒ Object (readonly)
Returns the value of attribute subject
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def subject @subject end |
#subject_alt_names ⇒ Object (readonly)
Returns the value of attribute subject_alt_names
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def subject_alt_names @subject_alt_names end |
#subject_components ⇒ Object (readonly)
Returns the value of attribute subject_components
17 18 19 |
# File 'lib/csr_peek/certificate.rb', line 17 def subject_components @subject_components end |
Class Method Details
.from_openssl(cert) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/csr_peek/certificate.rb', line 24 def self.from_openssl(cert) pkey = load_public_key(cert) facts = KeyFacts.of(pkey) new( openssl: cert, public_key: pkey, key_type: facts[:type], key_bits: facts[:bits], ec_curve: facts[:curve], subject: Names.subject_to_h(cert.subject).freeze, subject_components: Names.components(cert.subject).freeze, subject_alt_names: Extensions.subject_alt_names(find_ext(cert, "subjectAltName")), issuer: Names.subject_to_h(cert.issuer).freeze, key_usage: Extensions.key_usages(find_ext(cert, "keyUsage")).freeze, extended_key_usage: Extensions.extended_key_usages(find_ext(cert, "extendedKeyUsage")).freeze, basic_constraints: Extensions.basic_constraints(find_ext(cert, "basicConstraints")).freeze ) end |
Instance Method Details
#acceptable?(policy = Policy::BASELINE) ⇒ Boolean
True when both the key and the signature satisfy the issuance policy.
111 112 113 |
# File 'lib/csr_peek/certificate.rb', line 111 def acceptable?(policy = Policy::BASELINE) acceptable_key?(policy) && !weak_signature?(policy) end |
#ca? ⇒ Boolean
Whether this certificate may act as a CA (basicConstraints CA:TRUE).
124 125 126 |
# File 'lib/csr_peek/certificate.rb', line 124 def ca? basic_constraints[:ca] end |
#expired?(now = Time.now) ⇒ Boolean
True when now is after not_after. "expired" means the window has passed; a certificate whose window has not begun is #not_yet_valid?, not expired.
84 85 86 |
# File 'lib/csr_peek/certificate.rb', line 84 def expired?(now = Time.now) now > not_after end |
#not_after ⇒ Object
73 74 75 |
# File 'lib/csr_peek/certificate.rb', line 73 def not_after openssl.not_after end |
#not_before ⇒ Object
69 70 71 |
# File 'lib/csr_peek/certificate.rb', line 69 def not_before openssl.not_before end |
#not_yet_valid?(now = Time.now) ⇒ Boolean
88 89 90 |
# File 'lib/csr_peek/certificate.rb', line 88 def not_yet_valid?(now = Time.now) now < not_before end |
#path_length ⇒ Object
The pathLenConstraint from basicConstraints, or nil when unset.
129 130 131 |
# File 'lib/csr_peek/certificate.rb', line 129 def path_length basic_constraints[:path_length] end |
#policy_violations(policy = Policy::BASELINE) ⇒ Object
All policy reasons this certificate is unacceptable, as symbols; empty when it passes. Combines key violations with :weak_signature.
117 118 119 120 121 |
# File 'lib/csr_peek/certificate.rb', line 117 def policy_violations(policy = Policy::BASELINE) violations = key_policy_violations(policy) violations << :weak_signature if weak_signature?(policy) violations end |
#self_signed? ⇒ Boolean
92 93 94 95 96 |
# File 'lib/csr_peek/certificate.rb', line 92 def self_signed? openssl.subject == openssl.issuer && openssl.verify(public_key) rescue OpenSSL::X509::CertificateError, OpenSSL::PKey::PKeyError, TypeError false end |
#serial ⇒ Object
Serial as lower-case hex, zero-padded to an even number of digits.
58 59 60 61 |
# File 'lib/csr_peek/certificate.rb', line 58 def serial hex = openssl.serial.to_s(16).downcase hex.length.odd? ? "0#{hex}" : hex end |
#signature_algorithm ⇒ Object
The signature algorithm name, e.g. "sha256WithRSAEncryption".
99 100 101 102 103 |
# File 'lib/csr_peek/certificate.rb', line 99 def signature_algorithm openssl.signature_algorithm rescue OpenSSL::X509::CertificateError nil end |
#to_h ⇒ Object
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 |
# File 'lib/csr_peek/certificate.rb', line 133 def to_h { subject: subject, issuer: issuer, common_name: common_name, serial: serial, version: version, not_before: not_before, not_after: not_after, expired: expired?, not_yet_valid: not_yet_valid?, self_signed: self_signed?, ca: ca?, path_length: path_length, key_usage: key_usage, extended_key_usage: extended_key_usage, dns_names: dns_names, ip_addresses: ip_addresses, all_names: all_names, key_type: key_type, key_bits: key_bits, weak_key: weak_key?, acceptable: acceptable?, signature_algorithm: signature_algorithm, weak_signature: weak_signature?, spki_fingerprint_sha256: spki_fingerprint(:sha256), fingerprint_sha256: fingerprint(:sha256) } end |
#valid_at?(now = Time.now) ⇒ Boolean
True when now falls within [not_before, not_after].
78 79 80 |
# File 'lib/csr_peek/certificate.rb', line 78 def valid_at?(now = Time.now) now.between?(not_before, not_after) end |
#version ⇒ Object
X.509 version as the human-facing number: 1, 2, or 3 (the DER field is zero-based, so v3 is stored as 2).
65 66 67 |
# File 'lib/csr_peek/certificate.rb', line 65 def version openssl.version + 1 end |
#weak_signature?(policy = Policy::BASELINE) ⇒ Boolean
True when signed with a hash the policy rejects (MD5/SHA-1 by default).
106 107 108 |
# File 'lib/csr_peek/certificate.rb', line 106 def weak_signature?(policy = Policy::BASELINE) policy.weak_signature?(signature_algorithm) end |