Class: CsrPeek::Policy
- Inherits:
-
Object
- Object
- CsrPeek::Policy
- Defined in:
- lib/csr_peek/policy.rb
Overview
An issuance policy: the rules a key or certificate must satisfy to be acceptable, as opposed to whether a key is cryptographically weak.
These are deliberately separate ideas. An Ed25519 key is not weak, but a policy scoped to the CA/Browser Forum Baseline Requirements does not permit it for public TLS. #weak_key? answers the maths; a Policy answers "may I issue against this?". Pass your own Policy to raise the bar (3072-bit RSA, a curve allowlist, a compromised-key blocklist) without monkey-patching.
strict = CsrPeek::Policy.new(min_rsa_bits: 3072, allowed_curves: %w[secp384r1])
csr.acceptable_key?(strict) # => false
csr.key_policy_violations(strict) # => [:rsa_too_small]
Instance Attribute Summary collapse
-
#allowed_curves ⇒ Object
readonly
Returns the value of attribute allowed_curves.
-
#allowed_key_types ⇒ Object
readonly
Returns the value of attribute allowed_key_types.
-
#blocked_spki_fingerprints ⇒ Object
readonly
Returns the value of attribute blocked_spki_fingerprints.
-
#min_dsa_bits ⇒ Object
readonly
Returns the value of attribute min_dsa_bits.
-
#min_ec_bits ⇒ Object
readonly
Returns the value of attribute min_ec_bits.
-
#min_rsa_bits ⇒ Object
readonly
Returns the value of attribute min_rsa_bits.
-
#weak_signature_hashes ⇒ Object
readonly
Returns the value of attribute weak_signature_hashes.
Instance Method Summary collapse
- #blocked?(spki_fingerprint) ⇒ Boolean
- #curve_allowed?(curve) ⇒ Boolean
-
#initialize(min_rsa_bits: 2048, min_ec_bits: 256, min_dsa_bits: 2048, allowed_key_types: %w[RSA EC],, allowed_curves: nil, weak_signature_hashes: %w[md2 md4 md5 sha1],, blocked_spki_fingerprints: []) ⇒ Policy
constructor
allowed_key_types / allowed_curves default to nil meaning "no restriction on this axis".
- #key_type_allowed?(type) ⇒ Boolean
-
#key_violations(type:, bits:, curve:, spki_fingerprint: nil) ⇒ Object
The reasons this key fails the policy, as an array of symbols.
-
#weak_signature?(signature_algorithm) ⇒ Boolean
True when a certificate's signature algorithm uses a hash this policy rejects (MD5, SHA-1, ...), matched as a substring of the lower-cased name.
Constructor Details
#initialize(min_rsa_bits: 2048, min_ec_bits: 256, min_dsa_bits: 2048, allowed_key_types: %w[RSA EC],, allowed_curves: nil, weak_signature_hashes: %w[md2 md4 md5 sha1],, blocked_spki_fingerprints: []) ⇒ Policy
allowed_key_types / allowed_curves default to nil meaning "no restriction on this axis". blocked_spki_fingerprints is matched case-insensitively and ignoring colons, so "AA:BB" and "aabb" are the same entry.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/csr_peek/policy.rb', line 23 def initialize(min_rsa_bits: 2048, min_ec_bits: 256, min_dsa_bits: 2048, allowed_key_types: %w[RSA EC], allowed_curves: nil, weak_signature_hashes: %w[md2 md4 md5 sha1], blocked_spki_fingerprints: []) @min_rsa_bits = min_rsa_bits @min_ec_bits = min_ec_bits @min_dsa_bits = min_dsa_bits @allowed_key_types = allowed_key_types&.map(&:to_s)&.to_set&.freeze @allowed_curves = allowed_curves&.map(&:to_s)&.to_set&.freeze @weak_signature_hashes = weak_signature_hashes.map { |h| h.to_s.downcase }.freeze @blocked_spki_fingerprints = blocked_spki_fingerprints .map { |f| normalize_fingerprint(f) }.to_set.freeze freeze end |
Instance Attribute Details
#allowed_curves ⇒ Object (readonly)
Returns the value of attribute allowed_curves.
17 18 19 |
# File 'lib/csr_peek/policy.rb', line 17 def allowed_curves @allowed_curves end |
#allowed_key_types ⇒ Object (readonly)
Returns the value of attribute allowed_key_types.
17 18 19 |
# File 'lib/csr_peek/policy.rb', line 17 def allowed_key_types @allowed_key_types end |
#blocked_spki_fingerprints ⇒ Object (readonly)
Returns the value of attribute blocked_spki_fingerprints.
17 18 19 |
# File 'lib/csr_peek/policy.rb', line 17 def blocked_spki_fingerprints @blocked_spki_fingerprints end |
#min_dsa_bits ⇒ Object (readonly)
Returns the value of attribute min_dsa_bits.
17 18 19 |
# File 'lib/csr_peek/policy.rb', line 17 def min_dsa_bits @min_dsa_bits end |
#min_ec_bits ⇒ Object (readonly)
Returns the value of attribute min_ec_bits.
17 18 19 |
# File 'lib/csr_peek/policy.rb', line 17 def min_ec_bits @min_ec_bits end |
#min_rsa_bits ⇒ Object (readonly)
Returns the value of attribute min_rsa_bits.
17 18 19 |
# File 'lib/csr_peek/policy.rb', line 17 def min_rsa_bits @min_rsa_bits end |
#weak_signature_hashes ⇒ Object (readonly)
Returns the value of attribute weak_signature_hashes.
17 18 19 |
# File 'lib/csr_peek/policy.rb', line 17 def weak_signature_hashes @weak_signature_hashes end |
Instance Method Details
#blocked?(spki_fingerprint) ⇒ Boolean
58 59 60 61 62 |
# File 'lib/csr_peek/policy.rb', line 58 def blocked?(spki_fingerprint) return false if spki_fingerprint.nil? || blocked_spki_fingerprints.empty? blocked_spki_fingerprints.include?(normalize_fingerprint(spki_fingerprint)) end |
#curve_allowed?(curve) ⇒ Boolean
54 55 56 |
# File 'lib/csr_peek/policy.rb', line 54 def curve_allowed?(curve) allowed_curves.nil? || (curve && allowed_curves.include?(curve.to_s)) end |
#key_type_allowed?(type) ⇒ Boolean
50 51 52 |
# File 'lib/csr_peek/policy.rb', line 50 def key_type_allowed?(type) allowed_key_types.nil? || allowed_key_types.include?(type.to_s) end |
#key_violations(type:, bits:, curve:, spki_fingerprint: nil) ⇒ Object
The reasons this key fails the policy, as an array of symbols. Empty means acceptable. Inputs are the plain values an inspector already computes.
40 41 42 43 44 45 46 47 48 |
# File 'lib/csr_peek/policy.rb', line 40 def key_violations(type:, bits:, curve:, spki_fingerprint: nil) return [:key_unreadable] if type.nil? || type == "unknown" violations = [] violations << :unsupported_key_type unless key_type_allowed?(type) violations.concat(size_violations(type, bits, curve)) violations << :key_blocklisted if blocked?(spki_fingerprint) violations end |
#weak_signature?(signature_algorithm) ⇒ Boolean
True when a certificate's signature algorithm uses a hash this policy rejects (MD5, SHA-1, ...), matched as a substring of the lower-cased name. An unknown (blank) algorithm fails closed - "cannot verify" is not "safe", the same stance #weak_key? takes for an unloadable key.
68 69 70 71 72 73 |
# File 'lib/csr_peek/policy.rb', line 68 def weak_signature?(signature_algorithm) name = signature_algorithm.to_s.downcase return true if name.empty? weak_signature_hashes.any? { |h| name.include?(h) } end |