Module: Ruby::Rego::Builtins::Jwt::Jwk

Defined in:
lib/ruby/rego/builtins/jwt/jwk.rb

Overview

Parses a JWK or JWK Set (RFC 7517) into OpenSSL public keys for io.jwt.verify_*. OPA’s getKeyFromCertOrJWK accepts a single JWK object or a {"keys":[...]} set and errors if any key is unbuildable, so keys returns the built keys, or nil when the string is not a JWK shape or ANY of its keys cannot be built (-> undefined), or [] for an empty {"keys":[]} set (the caller verifies that as false). A private JWK (a d member) is rejected like OPA’s public-key path.

Constant Summary collapse

EC_CURVES =

JWK crv -> OpenSSL curve name for EC keys.

{ "P-256" => "prime256v1", "P-384" => "secp384r1", "P-521" => "secp521r1" }.freeze
RSA_MIN_MODULUS_BITS =

Go’s minimum signing key size (crypto/rsa rejects a modulus below this).

1024
RSA_MIN_EXPONENT =

Go’s checkPub requires an ODD public exponent in 2 <= e <= 2^31-1; OpenSSL signs with any e (incl. e=1, the identity), so OPA rejects keys outside this that the gem would otherwise sign. An even e is already rejected by the e*d≡1 consistency check (no inverse exists mod the even p-1/q-1), but the explicit odd? mirrors checkPub exactly.

OpenSSL::BN.new(2)
RSA_MAX_EXPONENT =
OpenSSL::BN.new(((2**31) - 1).to_s)

Class Method Summary collapse

Class Method Details

.keys(json_string) ⇒ Array[untyped]?

The OpenSSL public keys for a JWK or JWK Set, or nil when the string is not a JWK shape or any of its keys cannot be built — OPA errors (undefined) if a key carries private material, has a missing/garbled component or unknown kty, or if ANY key in a set is unbuildable. An empty {"keys":[]} set yields [] (no key to try, which the caller verifies as false). :reek:NilCheck – nil distinguishes “not a usable JWK” (undefined) from “[] empty set” (false).

Parameters:

  • json_string (String)

Returns:

  • (Array[untyped], nil)


28
29
30
31
32
33
34
35
# File 'lib/ruby/rego/builtins/jwt/jwk.rb', line 28

def self.keys(json_string)
  return nil unless json_string.encoding.ascii_compatible? && json_string.valid_encoding?

  entries = jwk_entries(JSON.parse(json_string))
  entries.nil? ? nil : build_keys(entries)
rescue JSON::ParserError
  nil
end

.oct_secret(jwk) ⇒ Object

The HMAC secret bytes of an oct JWK (the base64url k), or nil when the JWK is not a usable oct key — including an EMPTY k, which OPA rejects (an empty HMAC secret is undefined, not a signable key). For io.jwt.encode_sign’s HS* algorithms, which key on the raw secret. A k using the standard-base64 ‘+’/’/’ alphabet is undefined here (strict base64url) where OPA is lenient — a safe, gem-stricter divergence (the JWK spec mandates base64url). :reek:NilCheck



140
141
142
143
144
145
146
147
# File 'lib/ruby/rego/builtins/jwt/jwk.rb', line 140

def self.oct_secret(jwk)
  return nil unless jwk.is_a?(Hash) && jwk["kty"] == "oct"

  secret = segment(jwk["k"])
  secret unless secret.empty?
rescue OpenSSL::OpenSSLError, ::ArgumentError, ::TypeError
  nil
end

.private_key(jwk) ⇒ Object

An OpenSSL PRIVATE key from an RSA/EC/OKP JWK carrying private material, or nil when the JWK is not a buildable private key. For io.jwt.encode_sign’s asymmetric algorithms. :reek:NilCheck



152
153
154
155
156
157
158
159
160
161
162
# File 'lib/ruby/rego/builtins/jwt/jwk.rb', line 152

def self.private_key(jwk)
  return nil unless jwk.is_a?(Hash)

  case jwk["kty"]
  when "RSA" then rsa_private(jwk)
  when "EC" then ec_private(jwk)
  when "OKP" then okp_private(jwk)
  end
rescue OpenSSL::OpenSSLError, ::ArgumentError, ::TypeError, ::KeyError
  nil
end