# frozen_string_literal: true require 'xml/kit/key_info/key_value' require 'xml/kit/key_info/retrieval_method' require 'xml/kit/key_info/rsa_key_value' module Xml module Kit # An implementation of the KeyInfo element. # https://www.w3.org/TR/xmldsig-core1/#sec-KeyInfo # # @since 0.3.0 class KeyInfo include Templatable attr_accessor :key_name attr_accessor :x509_data attr_accessor :encrypted_key def initialize(x509: nil, encrypted_key: nil) @encrypted_key = encrypted_key @x509_data = x509 yield self if block_given? end def asymmetric_cipher(algorithm: Crypto::RsaCipher::ALGORITHM) return encrypted_key.asymmetric_cipher if encrypted_key if x509_data return Crypto.cipher_for( derive_algorithm_from(x509_data.public_key), x509_data.public_key ) end super(algorithm: algorithm) end def symmetric_cipher return super if encrypted_key.nil? encrypted_key.symmetric_cipher end def key_value @key_value ||= KeyValue.new end def retrieval_method @retrieval_method ||= RetrievalMethod.new end def subject_key_identifier ski = x509_data.extensions.find { |x| x.oid == 'subjectKeyIdentifier' } return if ski.nil? Base64.strict_encode64(ski.value) end private def derive_algorithm_from(key) case key when OpenSSL::PKey::RSA "#{::Xml::Kit::Namespaces::XMLENC}rsa-1_5" else raise ::Xml::Kit::Error, "#{key.try(:class)} is not supported" end end end end end