Skip to content
This repository was archived by the owner on Oct 18, 2023. It is now read-only.

Commit ee3e8a5

Browse files
authored
Client initialization parameters (#2)
* Adds crypto module * Adds new authentication module & params * Add parameters implementation * Add parameters usage to readme * Fix and improve readme. Remove test.
1 parent 566cd95 commit ee3e8a5

8 files changed

Lines changed: 127 additions & 5 deletions

File tree

Gemfile.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ PATH
22
remote: .
33
specs:
44
nemid (0.1.0)
5+
openssl (~> 2.2, >= 2.2.0)
56

67
GEM
78
remote: https://rubygems.org/
89
specs:
910
diff-lcs (1.4.4)
11+
openssl (2.2.0)
1012
rake (12.3.3)
1113
rspec (3.9.0)
1214
rspec-core (~> 3.9.0)

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,23 @@ Or install it yourself as:
2020

2121
## Usage
2222

23-
TODO: Write usage instructions here
23+
This gem implements one main module:
24+
25+
- `Authentication`: the purpose of this module is to generate client initialization
26+
parameters and response handling.
27+
28+
### Authentication::Parameters
29+
30+
Generate client initialization parameters
31+
32+
```ruby
33+
nemid = NemID::Authentication::Parameters.new(
34+
'path/to/your/voces/certificate',
35+
'your_voces_certificate_password',
36+
)
37+
38+
nemid.client_initialization_parameters # ruby hash with signed parameters
39+
```
2440

2541
## Development
2642

lib/nemid.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
require "nemid/version"
2+
require "nemid/authentication"
3+
require "nemid/crypto"
24

35
module NemID
46
class Error < StandardError; end

lib/nemid/authentication.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
require_relative "authentication/params"
2+
3+
module NemID
4+
module Authentication
5+
end
6+
end

lib/nemid/authentication/params.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
require 'date'
2+
3+
module NemID
4+
module Authentication
5+
class Params
6+
def initialize(certificate, pass)
7+
@nemid_crypto = NemID::Crypto.new(certificate, pass)
8+
end
9+
10+
def client_initialization_parameters
11+
params = unsigned_params
12+
normalized_unsigned_params = normalize(unsigned_params)
13+
14+
params.merge({
15+
"DIGEST_SIGNATURE": digest_signature(normalized_unsigned_params),
16+
"PARAMS_DIGEST": params_digest(normalized_unsigned_params),
17+
})
18+
end
19+
20+
private
21+
def digest_signature(normalized_unsigned_params)
22+
@nemid_crypto.base64_encoded_rsa_signature(normalized_unsigned_params)
23+
end
24+
25+
def normalize(params)
26+
params = params.transform_keys(&:upcase)
27+
28+
str = String.new
29+
30+
params.keys.sort.each { |k| str += "#{k.to_s}#{params[k]}" }
31+
32+
return str
33+
end
34+
35+
def params_digest(normalized_unsigned_params)
36+
@nemid_crypto.base64_encoded_digest_representation(normalized_unsigned_params)
37+
end
38+
39+
def sp_cert
40+
@nemid_crypto.base64_encoded_der_representation
41+
end
42+
43+
def unsigned_params
44+
{
45+
"CLIENTFLOW": "OCESLOGIN2",
46+
"SP_CERT": sp_cert,
47+
"TIMESTAMP": DateTime.now.new_offset(0).strftime('%F %T%z'),
48+
}
49+
end
50+
end
51+
end
52+
end

lib/nemid/crypto.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
require 'base64'
2+
require 'openssl'
3+
4+
module NemID
5+
class Crypto
6+
7+
def initialize(certificate, pass)
8+
certificate = read_file(certificate)
9+
@pkcs12 = read_pkcs12(certificate, pass)
10+
@rsa_instance = rsa_keypair(@pkcs12, pass)
11+
end
12+
13+
def base64_encoded_der_representation
14+
Base64.strict_encode64(@pkcs12.certificate.to_der)
15+
end
16+
17+
def base64_encoded_digest_representation(data)
18+
Base64.strict_encode64(digest(data))
19+
end
20+
21+
def base64_encoded_rsa_signature(data)
22+
Base64.strict_encode64(sign(data))
23+
end
24+
25+
private
26+
def digest(data)
27+
OpenSSL::Digest::SHA256.new.digest(data)
28+
end
29+
30+
def read_file(certificate)
31+
File.read(certificate)
32+
end
33+
34+
def read_pkcs12(certificate, pass)
35+
OpenSSL::PKCS12::new(certificate, pass)
36+
end
37+
38+
def rsa_keypair(pkcs12, passphrase)
39+
OpenSSL::PKey::RSA.new(pkcs12.key, passphrase)
40+
end
41+
42+
def sign(data)
43+
@rsa_instance.sign(OpenSSL::Digest::SHA256.new, data)
44+
end
45+
end
46+
end

nemid.gemspec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Gem::Specification.new do |spec|
1212
spec.license = "MIT"
1313
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
1414

15+
spec.add_dependency 'openssl', '~> 2.2', '>= 2.2.0'
16+
1517
spec.metadata["allowed_push_host"] = "http://rubygems.org"
1618

1719
spec.metadata["homepage_uri"] = spec.homepage

spec/nemid_spec.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,4 @@
22
it "has a version number" do
33
expect(NemID::VERSION).not_to be nil
44
end
5-
6-
it "does something useful" do
7-
expect(false).to eq(true)
8-
end
95
end

0 commit comments

Comments
 (0)