Class: OrangeData::Credentials
- Inherits:
-
Object
- Object
- OrangeData::Credentials
- Defined in:
- lib/orange_data/credentials.rb
Overview
wrapper for keys/certs used for connection auth
Defined Under Namespace
Modules: KeyEncoding
Constant Summary collapse
- DEFAULT_KEY_LENGTH =
2048
Instance Attribute Summary collapse
-
#certificate ⇒ Object
Returns the value of attribute certificate.
-
#certificate_key ⇒ Object
Returns the value of attribute certificate_key.
-
#signature_key ⇒ Object
Returns the value of attribute signature_key.
-
#signature_key_name ⇒ Object
Returns the value of attribute signature_key_name.
-
#title ⇒ Object
Returns the value of attribute title.
Class Method Summary collapse
-
.default_test ⇒ Object
ключи для тествого окружения.
- .from_hash(creds, key_pass: nil) ⇒ Object
- .from_json(json) ⇒ Object
- .generate_signature_key(key_length = DEFAULT_KEY_LENGTH) ⇒ Object
- .read_certs_from_pack(path, signature_key_name: nil, cert_key_pass: nil, title: nil, signature_key: nil) ⇒ Object
- .read_certs_from_zip_pack(rubyzip_object, signature_key_name: nil, cert_key_pass: nil, title: nil, signature_key: nil) ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
- #certificate_subject ⇒ Object
-
#generate_signature_key!(key_length = DEFAULT_KEY_LENGTH) ⇒ Object
deprecated.
-
#initialize(signature_key_name: nil, signature_key: nil, certificate: nil, certificate_key: nil, title: nil) ⇒ Credentials
constructor
A new instance of Credentials.
- #inspect ⇒ Object
-
#signature_public_xml ⇒ Object
публичная часть ключа подписи в формате пригодном для отдачи в ЛК.
- #to_hash(key_pass: nil, save_pass: false) ⇒ Object
- #to_json(key_pass: nil, save_pass: false) ⇒ Object
- #to_yaml(key_pass: nil, save_pass: false) ⇒ Object
- #valid? ⇒ Boolean
Constructor Details
#initialize(signature_key_name: nil, signature_key: nil, certificate: nil, certificate_key: nil, title: nil) ⇒ Credentials
Returns a new instance of Credentials.
96 97 98 99 100 101 102 103 104 105 |
# File 'lib/orange_data/credentials.rb', line 96 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 |
Instance Attribute Details
#certificate ⇒ Object
Returns the value of attribute certificate.
94 95 96 |
# File 'lib/orange_data/credentials.rb', line 94 def certificate @certificate end |
#certificate_key ⇒ Object
Returns the value of attribute certificate_key.
94 95 96 |
# File 'lib/orange_data/credentials.rb', line 94 def certificate_key @certificate_key end |
#signature_key ⇒ Object
Returns the value of attribute signature_key.
94 95 96 |
# File 'lib/orange_data/credentials.rb', line 94 def signature_key @signature_key end |
#signature_key_name ⇒ Object
Returns the value of attribute signature_key_name.
94 95 96 |
# File 'lib/orange_data/credentials.rb', line 94 def signature_key_name @signature_key_name end |
#title ⇒ Object
Returns the value of attribute title.
94 95 96 |
# File 'lib/orange_data/credentials.rb', line 94 def title @title end |
Class Method Details
.default_test ⇒ Object
ключи для тествого окружения
269 270 271 |
# File 'lib/orange_data/credentials.rb', line 269 def self.default_test from_hash(YAML.load_file(File.('credentials_test.yml', __dir__))) end |
.from_hash(creds, key_pass: nil) ⇒ Object
126 127 128 129 130 131 132 133 134 135 |
# File 'lib/orange_data/credentials.rb', line 126 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) ⇒ Object
162 163 164 165 |
# File 'lib/orange_data/credentials.rb', line 162 def self.from_json(json) require 'json' from_hash(JSON.parse(json, symbolize_names: true)) end |
.generate_signature_key(key_length = DEFAULT_KEY_LENGTH) ⇒ Object
201 202 203 204 205 |
# File 'lib/orange_data/credentials.rb', line 201 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 |
.read_certs_from_pack(path, signature_key_name: nil, cert_key_pass: nil, title: nil, signature_key: nil) ⇒ Object
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/orange_data/credentials.rb', line 207 def self.read_certs_from_pack(path, signature_key_name:nil, cert_key_pass:nil, title:nil, signature_key:nil) path = File.(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}").grep(/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) ⇒ Object
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/orange_data/credentials.rb', line 235 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}').grep(/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 |
Instance Method Details
#==(other) ⇒ Object
115 116 117 118 119 120 121 122 123 124 |
# File 'lib/orange_data/credentials.rb', line 115 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 ⇒ Object
188 189 190 191 192 |
# File 'lib/orange_data/credentials.rb', line 188 def certificate_subject return unless (subj = certificate.subject.to_a.select{|ent| ent.first == 'O' }.first) subj[1].force_encoding('UTF-8') end |
#generate_signature_key!(key_length = DEFAULT_KEY_LENGTH) ⇒ Object
deprecated
197 198 199 |
# File 'lib/orange_data/credentials.rb', line 197 def generate_signature_key!(key_length=DEFAULT_KEY_LENGTH) self.signature_key = self.class.generate_signature_key(key_length) end |
#inspect ⇒ Object
175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/orange_data/credentials.rb', line 175 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 ⇒ Object
публичная часть ключа подписи в формате пригодном для отдачи в ЛК
264 265 266 |
# File 'lib/orange_data/credentials.rb', line 264 def signature_public_xml signature_key.public_key.to_xml end |
#to_hash(key_pass: nil, save_pass: false) ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/orange_data/credentials.rb', line 137 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) ⇒ Object
167 168 169 |
# File 'lib/orange_data/credentials.rb', line 167 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) ⇒ Object
171 172 173 |
# File 'lib/orange_data/credentials.rb', line 171 def to_yaml(key_pass:nil, save_pass:false) to_hash(key_pass:key_pass, save_pass:save_pass).to_yaml end |
#valid? ⇒ Boolean
107 108 109 110 111 112 113 |
# File 'lib/orange_data/credentials.rb', line 107 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 |