# typed: strict # frozen_string_literal: true module Paseto class AsymmetricKey < Interface::Key extend T::Sig extend T::Helpers abstract! sig(:final) { override.returns(String) } attr_reader :id, :paserk sig(:final) { returns(String) } attr_reader :pid, :public_paserk sig { params(_key: T.untyped).void } def initialize(_key) @public_paserk = T.let("#{paserk_version}.public.#{Util.encode64(public_bytes)}".freeze, String) @pid = T.let(Operations::ID.pid(self).freeze, String) if private? @paserk = T.let("#{paserk_version}.secret.#{Util.encode64(to_bytes)}".freeze, String) @id = T.let(Operations::ID.sid(self).freeze, String) else @paserk = @public_paserk @id = T.let(@pid, String) end end sig { abstract.params(message: String, footer: String, implicit_assertion: String).returns(Token) } def sign(message:, footer: '', implicit_assertion: ''); end sig { abstract.params(token: Token, implicit_assertion: String).returns(String) } def verify(token:, implicit_assertion: ''); end sig { abstract.returns(String) } def public_to_pem; end sig { abstract.returns(String) } def private_to_pem; end sig { abstract.returns(T::Boolean) } def private?; end sig { abstract.returns(String) } def public_bytes; end sig { abstract.params(other: T.untyped).returns(String) } def ecdh(other); end sig(:final) do override.params( payload: T::Hash[String, T.untyped], footer: String, implicit_assertion: String, options: T.nilable(T.any(String, Integer, Symbol, T::Boolean)) ).returns(String) end def encode!(payload, footer: '', implicit_assertion: '', **options) MultiJson.dump(payload, options) .then { |json| sign(message: json, footer: footer, implicit_assertion: implicit_assertion) } .then(&:to_s) end sig(:final) do override.params( payload: String, implicit_assertion: String, options: T.nilable(T.any(Proc, String, Integer, Symbol, T::Boolean)) ).returns(Result) end def decode!(payload, implicit_assertion: '', **options) token = Token.parse(payload) verify(token: token, implicit_assertion: implicit_assertion) .then { |json| MultiJson.load(json, **options) } .then { |claims| Result.new(claims: claims, footer: token.footer) } end sig(:final) { override.returns(String) } def pbkw_header = protocol.pbkd_secret_header sig(:final) { override.returns(String) } def purpose = 'public' sig(:final) { returns(Interface::PKE) } def pke = protocol.pke(self) sig(:final) { returns(String) } def sid = @sid ||= T.let(Operations::ID.sid(self), T.nilable(String)) sig(:final) { params(other: SymmetricKey).returns(String) } def seal(other) = Paserk.seal(sealing_key: self, key: other) sig(:final) { params(paserk: String).returns(SymmetricKey) } def unseal(paserk) = Paserk.from_paserk(paserk: paserk, unsealing_key: self) end end