class OrangeData::Credentials
wrapper for keys/certs used for connection auth
Constants
- DEFAULT_KEY_LENGTH
Attributes
certificate[RW]
certificate_key[RW]
signature_key[RW]
signature_key_name[RW]
title[RW]
Public Class Methods
default_test()
click to toggle source
ключи для тествого окружения
# File lib/orange_data/credentials.rb, line 288 def self.default_test from_hash(YAML.load_file(File.expand_path('credentials_test.yml', __dir__))) end
from_hash(creds, key_pass:nil)
click to toggle source
# File lib/orange_data/credentials.rb, line 145 def self.from_hash(creds, key_pass:nil) key_pass ||= '' # to prevent password prompt, works in fresh openssl gem/ruby new( title: creds[:title], signature_key_name: creds[:signature_key_name], signature_key: OpenSSL::PKey::RSA.load_from(creds[:signature_key], creds[:signature_key_pass] || key_pass), certificate: creds[:certificate] && OpenSSL::X509::Certificate.new(creds[:certificate]), certificate_key: OpenSSL::PKey::RSA.load_from(creds[:certificate_key], creds[:certificate_key_pass] || key_pass) ) end
from_json(json)
click to toggle source
# File lib/orange_data/credentials.rb, line 181 def self.from_json(json) require 'json' from_hash(JSON.parse(json, symbolize_names: true)) end
generate_signature_key(key_length=DEFAULT_KEY_LENGTH)
click to toggle source
# File lib/orange_data/credentials.rb, line 220 def self.generate_signature_key(key_length=DEFAULT_KEY_LENGTH) raise ArgumentError, "key length should be >= 489, recomended #{DEFAULT_KEY_LENGTH}" unless key_length >= 489 OpenSSL::PKey::RSA.new(key_length) end
new(signature_key_name:nil, signature_key:nil, certificate:nil, certificate_key:nil, title:nil)
click to toggle source
# File lib/orange_data/credentials.rb, line 115 def initialize(signature_key_name:nil, signature_key:nil, certificate:nil, certificate_key:nil, title:nil) raise ArgumentError, "Signature key should be a private key" if signature_key && !signature_key.private? raise ArgumentError, "Certificate key should be a private key" if certificate_key && !certificate_key.private? @signature_key_name = signature_key_name @signature_key = signature_key @certificate = certificate @certificate_key = certificate_key @title = title end
read_certs_from_pack(path, signature_key_name:nil, cert_key_pass:nil, title:nil, signature_key:nil)
click to toggle source
# File lib/orange_data/credentials.rb, line 226 def self.read_certs_from_pack(path, signature_key_name:nil, cert_key_pass:nil, title:nil, signature_key:nil) path = File.expand_path(path) client_cert = Dir.glob(path + '/*.{crt}').select{|f| File.file?(f.sub(/.crt\z/, '.key')) } raise 'Expect to find exactly one <num>.crt with corresponding <num>.key file' unless client_cert.size == 1 client_cert = client_cert.first unless signature_key # private_key_test.xml || rsa_\d+_private_key.xml xmls = Dir.glob(path + '/*.{xml}').select{|f| f =~ /private/ } signature_key = if xmls.size == 1 File.read(xmls.first) else generate_signature_key(DEFAULT_KEY_LENGTH) # .tap{|k| logger.info("Generated public signature key: #{k.public_key.to_xml}") } end end from_hash( title: title || "Generated from #{File.basename(path)}", signature_key_name: signature_key_name || File.basename(client_cert).gsub(/\..*/, ''), certificate: File.read(client_cert), certificate_key: File.read(client_cert.sub(/.crt\z/, '.key')), certificate_key_pass: cert_key_pass, signature_key: signature_key ) end
read_certs_from_zip_pack(rubyzip_object, signature_key_name:nil, cert_key_pass:nil, title:nil, signature_key:nil)
click to toggle source
# File lib/orange_data/credentials.rb, line 254 def self.read_certs_from_zip_pack(rubyzip_object, signature_key_name:nil, cert_key_pass:nil, title:nil, signature_key:nil) client_cert = rubyzip_object.glob("*.crt").select{|f| rubyzip_object.glob(f.name.sub(/.crt\z/, '.key')).any? } raise 'Expect to find exactly one <num>.crt with corresponding <num>.key file' unless client_cert.size == 1 client_cert = client_cert.first client_key = rubyzip_object.glob(client_cert.name.sub(/.crt\z/, '.key')).first unless signature_key # private_key_test.xml || rsa_\d+_private_key.xml xmls = rubyzip_object.glob('/*.{xml}').select{|f| f =~ /private/ } signature_key = if xmls.size == 1 xmls.first.get_input_stream.read else generate_signature_key(DEFAULT_KEY_LENGTH) # .tap{|k| logger.info("Generated public signature key: #{k.public_key.to_xml}") } end end from_hash( title: title || "Generated from zip", signature_key_name: signature_key_name || File.basename(client_cert.name).gsub(/\..*/, ''), certificate: client_cert.get_input_stream.read, certificate_key: client_key.get_input_stream.read, certificate_key_pass: cert_key_pass, signature_key: signature_key ) end
Public Instance Methods
==(other)
click to toggle source
# File lib/orange_data/credentials.rb, line 134 def ==(other) return false unless %i[signature_key_name title].all?{|m| send(m) == other.send(m) } # certificates/keys cannot be compared directly, so dump %i[signature_key certificate certificate_key].all?{|m| c1 = send(m) c2 = other.send(m) c1 == c2 || (c1 && c2 && c1.to_der == c2.to_der) } end
certificate_subject()
click to toggle source
# File lib/orange_data/credentials.rb, line 207 def certificate_subject if subj = certificate.subject.to_a.select{|ent| ent.first == 'O' }.first subj[1].force_encoding('UTF-8') end end
generate_signature_key!(key_length=DEFAULT_KEY_LENGTH)
click to toggle source
deprecated
# File lib/orange_data/credentials.rb, line 216 def generate_signature_key!(key_length=DEFAULT_KEY_LENGTH) self.signature_key = self.class.generate_signature_key(key_length) end
inspect()
click to toggle source
# File lib/orange_data/credentials.rb, line 194 def inspect info_fields = { title: (title || 'untitled').inspect, key_name: signature_key_name.inspect, } if certificate && (subject_name = certificate_subject) info_fields[:certificate] = %("#{(subject_name || 'unknown').gsub('"', '\"')}") end "#<#{self.class.name}:#{object_id} #{info_fields.map{|(k, v)| "#{k}=#{v}" }.join(' ')}>" end
signature_public_xml()
click to toggle source
публичная часть ключа подписи в формате пригодном для отдачи в ЛК
# File lib/orange_data/credentials.rb, line 283 def signature_public_xml signature_key.public_key.to_xml end
to_hash(key_pass:nil, save_pass:false)
click to toggle source
# File lib/orange_data/credentials.rb, line 156 def to_hash(key_pass:nil, save_pass:false) if key_pass.nil? key_pass = SecureRandom.hex save_pass = true elsif key_pass == false key_pass = nil end { title: title, signature_key_name: signature_key_name, signature_key: signature_key && signature_key.to_pem(key_pass && OpenSSL::Cipher.new("aes-128-cbc"), key_pass), certificate: certificate && certificate.to_pem, certificate_key: certificate_key && certificate_key.to_pem(key_pass && OpenSSL::Cipher.new("aes-128-cbc"), key_pass), }.tap do |h| h.delete(:title) if !title || title == '' if save_pass h[:certificate_key_pass] = key_pass if certificate && key_pass h[:signature_key_pass] = key_pass if signature_key && key_pass end end end
to_json(key_pass:nil, save_pass:false)
click to toggle source
# File lib/orange_data/credentials.rb, line 186 def to_json(key_pass:nil, save_pass:false) to_hash(key_pass:key_pass, save_pass:save_pass).to_json end
to_yaml(key_pass:nil, save_pass:false)
click to toggle source
# File lib/orange_data/credentials.rb, line 190 def to_yaml(key_pass:nil, save_pass:false) to_hash(key_pass:key_pass, save_pass:save_pass).to_yaml end
valid?()
click to toggle source
# File lib/orange_data/credentials.rb, line 126 def valid? signature_key_name && signature_key && signature_key.private? && (signature_key.n.num_bits >= 489) && # minimum working key length for sha256 signature certificate && certificate_key && certificate_key.private? && certificate.check_private_key(certificate_key) end