virgil-sdk 4.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +15 -0
- data/Gemfile +4 -0
- data/README.md +134 -0
- data/Rakefile +9 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/dockefiles/Dockerfile-200 +25 -0
- data/dockefiles/Dockerfile-2110 +36 -0
- data/dockefiles/Dockerfile-220 +26 -0
- data/dockefiles/Dockerfile-226 +25 -0
- data/dockefiles/Dockerfile-233 +25 -0
- data/dockefiles/Dockerfile-240 +26 -0
- data/docker-compose.yml +107 -0
- data/lib/virgil/sdk.rb +10 -0
- data/lib/virgil/sdk/client.rb +47 -0
- data/lib/virgil/sdk/client/card.rb +142 -0
- data/lib/virgil/sdk/client/card_validator.rb +104 -0
- data/lib/virgil/sdk/client/http.rb +45 -0
- data/lib/virgil/sdk/client/http/base_connection.rb +112 -0
- data/lib/virgil/sdk/client/http/cards_service_connection.rb +113 -0
- data/lib/virgil/sdk/client/http/request.rb +63 -0
- data/lib/virgil/sdk/client/request_signer.rb +90 -0
- data/lib/virgil/sdk/client/requests.rb +50 -0
- data/lib/virgil/sdk/client/requests/confirm_identity_request.rb +67 -0
- data/lib/virgil/sdk/client/requests/create_card_request.rb +105 -0
- data/lib/virgil/sdk/client/requests/revoke_card_request.rb +85 -0
- data/lib/virgil/sdk/client/requests/signable_request.rb +142 -0
- data/lib/virgil/sdk/client/requests/verify_identity_request.rb +60 -0
- data/lib/virgil/sdk/client/search_criteria.rb +79 -0
- data/lib/virgil/sdk/client/signatures_base64.rb +25 -0
- data/lib/virgil/sdk/client/virgil_client.rb +425 -0
- data/lib/virgil/sdk/cryptography.rb +42 -0
- data/lib/virgil/sdk/cryptography/hashes.rb +44 -0
- data/lib/virgil/sdk/cryptography/hashes/fingerprint.rb +79 -0
- data/lib/virgil/sdk/cryptography/hashes/hash_algorithm.rb +91 -0
- data/lib/virgil/sdk/cryptography/keys.rb +48 -0
- data/lib/virgil/sdk/cryptography/keys/key_pair.rb +46 -0
- data/lib/virgil/sdk/cryptography/keys/key_pair_type.rb +108 -0
- data/lib/virgil/sdk/cryptography/keys/key_storage.rb +177 -0
- data/lib/virgil/sdk/cryptography/keys/private_key.rb +44 -0
- data/lib/virgil/sdk/cryptography/keys/public_key.rb +44 -0
- data/lib/virgil/sdk/cryptography/keys/storage_item.rb +63 -0
- data/lib/virgil/sdk/cryptography/virgil_crypto.rb +411 -0
- data/lib/virgil/sdk/high_level.rb +21 -0
- data/lib/virgil/sdk/high_level/virgil_api.rb +71 -0
- data/lib/virgil/sdk/high_level/virgil_app_credentials.rb +54 -0
- data/lib/virgil/sdk/high_level/virgil_buffer.rb +161 -0
- data/lib/virgil/sdk/high_level/virgil_card.rb +204 -0
- data/lib/virgil/sdk/high_level/virgil_card_manager.rb +294 -0
- data/lib/virgil/sdk/high_level/virgil_card_verifier_info.rb +49 -0
- data/lib/virgil/sdk/high_level/virgil_context.rb +69 -0
- data/lib/virgil/sdk/high_level/virgil_identity.rb +17 -0
- data/lib/virgil/sdk/high_level/virgil_identity/email_confirmation.rb +60 -0
- data/lib/virgil/sdk/high_level/virgil_identity/validation_token.rb +49 -0
- data/lib/virgil/sdk/high_level/virgil_identity/verification_attempt.rb +69 -0
- data/lib/virgil/sdk/high_level/virgil_identity/verification_options.rb +56 -0
- data/lib/virgil/sdk/high_level/virgil_key.rb +168 -0
- data/lib/virgil/sdk/high_level/virgil_key_manager.rb +97 -0
- data/lib/virgil/sdk/version.rb +5 -0
- data/virgil-sdk.gemspec +31 -0
- metadata +203 -0
@@ -0,0 +1,177 @@
|
|
1
|
+
# Copyright (C) 2016 Virgil Security Inc.
|
2
|
+
#
|
3
|
+
# Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are
|
9
|
+
# met:
|
10
|
+
#
|
11
|
+
# (1) Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
#
|
14
|
+
# (2) Redistributions in binary form must reproduce the above copyright
|
15
|
+
# notice, this list of conditions and the following disclaimer in
|
16
|
+
# the documentation and/or other materials provided with the
|
17
|
+
# distribution.
|
18
|
+
#
|
19
|
+
# (3) Neither the name of the copyright holder nor the names of its
|
20
|
+
# contributors may be used to endorse or promote products derived from
|
21
|
+
# this software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
|
24
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
25
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
26
|
+
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
27
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
28
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
30
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
31
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
32
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
|
35
|
+
module Virgil
|
36
|
+
module SDK
|
37
|
+
module Cryptography
|
38
|
+
module Keys
|
39
|
+
class KeyStorage
|
40
|
+
|
41
|
+
attr_reader :folder_path
|
42
|
+
|
43
|
+
class KeyStorageException < StandardError
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
class KeyEntryAlreadyExistsException < KeyStorageException
|
48
|
+
|
49
|
+
def to_s
|
50
|
+
"Storage key entry already exists"
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
class KeyEntryNotFoundException < KeyStorageException
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
"Storage key entry isn't found"
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize(folder_path=self.class.default_folder)
|
64
|
+
|
65
|
+
raise ArgumentError.new("folder_path is not valid") if (!folder_path.is_a?(String) || folder_path.empty?)
|
66
|
+
|
67
|
+
@folder_path = folder_path
|
68
|
+
validate_storage_folder
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def self.default_folder
|
74
|
+
path = "./key_storage"
|
75
|
+
FileUtils.mkdir(path) unless Dir.exist?(path)
|
76
|
+
path
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
# Stores the key to the given alias.
|
81
|
+
#
|
82
|
+
# Args:
|
83
|
+
# storage_item: The storage item to be kept
|
84
|
+
#
|
85
|
+
# Raises:
|
86
|
+
# KeyEntryAlreadyExistsException: if key storage already has item with such name
|
87
|
+
def store(storage_item)
|
88
|
+
|
89
|
+
validate_storage_folder
|
90
|
+
if exists?(storage_item.name)
|
91
|
+
raise KeyEntryAlreadyExistsException.new
|
92
|
+
end
|
93
|
+
|
94
|
+
open(item_file_path(storage_item.name), 'w') do |f|
|
95
|
+
f.write(storage_item.to_json)
|
96
|
+
File.chmod(0400, item_file_path(storage_item.name))
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
# Loads the key associated with the given alias.
|
103
|
+
#
|
104
|
+
# Args:
|
105
|
+
# item_name: The alias name.
|
106
|
+
#
|
107
|
+
# Returns:
|
108
|
+
# The requested key, or null if the given alias does not exist or does
|
109
|
+
# not identify a key-related entry.
|
110
|
+
#
|
111
|
+
# Raises:
|
112
|
+
# KeyEntryNotFoundException: if key storage doesn't have item with such name
|
113
|
+
def load(item_name)
|
114
|
+
|
115
|
+
validate_storage_folder
|
116
|
+
raise KeyEntryNotFoundException.new unless exists?(item_name)
|
117
|
+
|
118
|
+
json_body = File.read(item_file_path(item_name))
|
119
|
+
return nil if json_body.nil?
|
120
|
+
|
121
|
+
StorageItem.restore_from_json(item_name, json_body)
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
# Checks if the given alias exists in this keystore.
|
127
|
+
#
|
128
|
+
# Args:
|
129
|
+
# item_name: The alias name.
|
130
|
+
#
|
131
|
+
# Returns:
|
132
|
+
# true if the given alias exists in this keystore.
|
133
|
+
# false if the given alias doesn't exist in this keystore.
|
134
|
+
def exists?(item_name)
|
135
|
+
|
136
|
+
File.exist?(item_file_path(item_name))
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
# Delete the key associated with the given alias.
|
142
|
+
#
|
143
|
+
# Args:
|
144
|
+
# item_name: The alias name.
|
145
|
+
#
|
146
|
+
# Raises:
|
147
|
+
# KeyEntryNotFoundException: if key storage doesn't have item with such name
|
148
|
+
def delete(item_name)
|
149
|
+
|
150
|
+
validate_storage_folder
|
151
|
+
raise KeyEntryNotFoundException.new unless exists?(item_name)
|
152
|
+
|
153
|
+
File.delete(item_file_path(item_name))
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def validate_storage_folder
|
161
|
+
|
162
|
+
unless (Dir.exist?(folder_path) && File.writable?(folder_path) && File.readable?(folder_path))
|
163
|
+
raise KeyStorageException.new("Destination folder doesn't exist or you don't have permission to write there")
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
def item_file_path(item_name)
|
169
|
+
|
170
|
+
File.join(folder_path, item_name)
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright (C) 2016 Virgil Security Inc.
|
2
|
+
#
|
3
|
+
# Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are
|
9
|
+
# met:
|
10
|
+
#
|
11
|
+
# (1) Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
#
|
14
|
+
# (2) Redistributions in binary form must reproduce the above copyright
|
15
|
+
# notice, this list of conditions and the following disclaimer in
|
16
|
+
# the documentation and/or other materials provided with the
|
17
|
+
# distribution.
|
18
|
+
#
|
19
|
+
# (3) Neither the name of the copyright holder nor the names of its
|
20
|
+
# contributors may be used to endorse or promote products derived from
|
21
|
+
# this software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
|
24
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
25
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
26
|
+
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
27
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
28
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
30
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
31
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
32
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
|
35
|
+
module Virgil
|
36
|
+
module SDK
|
37
|
+
module Cryptography
|
38
|
+
module Keys
|
39
|
+
# Class containing private key information
|
40
|
+
PrivateKey = Struct.new(:receiver_id, :value)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright (C) 2016 Virgil Security Inc.
|
2
|
+
#
|
3
|
+
# Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are
|
9
|
+
# met:
|
10
|
+
#
|
11
|
+
# (1) Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
#
|
14
|
+
# (2) Redistributions in binary form must reproduce the above copyright
|
15
|
+
# notice, this list of conditions and the following disclaimer in
|
16
|
+
# the documentation and/or other materials provided with the
|
17
|
+
# distribution.
|
18
|
+
#
|
19
|
+
# (3) Neither the name of the copyright holder nor the names of its
|
20
|
+
# contributors may be used to endorse or promote products derived from
|
21
|
+
# this software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
|
24
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
25
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
26
|
+
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
27
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
28
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
30
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
31
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
32
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
|
35
|
+
module Virgil
|
36
|
+
module SDK
|
37
|
+
module Cryptography
|
38
|
+
module Keys
|
39
|
+
# Class containing public key information
|
40
|
+
PublicKey = Struct.new(:receiver_id, :value)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Copyright (C) 2016 Virgil Security Inc.
|
2
|
+
#
|
3
|
+
# Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are
|
9
|
+
# met:
|
10
|
+
#
|
11
|
+
# (1) Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
#
|
14
|
+
# (2) Redistributions in binary form must reproduce the above copyright
|
15
|
+
# notice, this list of conditions and the following disclaimer in
|
16
|
+
# the documentation and/or other materials provided with the
|
17
|
+
# distribution.
|
18
|
+
#
|
19
|
+
# (3) Neither the name of the copyright holder nor the names of its
|
20
|
+
# contributors may be used to endorse or promote products derived from
|
21
|
+
# this software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
|
24
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
25
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
26
|
+
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
27
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
28
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
30
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
31
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
32
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
|
35
|
+
require 'json'
|
36
|
+
|
37
|
+
module Virgil
|
38
|
+
module SDK
|
39
|
+
module Cryptography
|
40
|
+
module Keys
|
41
|
+
# StorageItem class represents a key pair storage entry.
|
42
|
+
# name: Gets or sets the name.
|
43
|
+
# data: key pair in bytes
|
44
|
+
# meta: the meta data associated with key pair.
|
45
|
+
StorageItem = Struct.new(:name, :data, :meta) do
|
46
|
+
|
47
|
+
def to_json
|
48
|
+
model = {
|
49
|
+
'data': HighLevel::VirgilBuffer.new(data).to_base64,
|
50
|
+
'meta': meta
|
51
|
+
}
|
52
|
+
model.to_json
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.restore_from_json(name, str_json)
|
56
|
+
model = JSON.parse(str_json)
|
57
|
+
new(name, HighLevel::VirgilBuffer.from_base64(model['data']).bytes, model['meta'])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,411 @@
|
|
1
|
+
# Copyright (C) 2016 Virgil Security Inc.
|
2
|
+
#
|
3
|
+
# Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are
|
9
|
+
# met:
|
10
|
+
#
|
11
|
+
# (1) Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
#
|
14
|
+
# (2) Redistributions in binary form must reproduce the above copyright
|
15
|
+
# notice, this list of conditions and the following disclaimer in
|
16
|
+
# the documentation and/or other materials provided with the
|
17
|
+
# distribution.
|
18
|
+
#
|
19
|
+
# (3) Neither the name of the copyright holder nor the names of its
|
20
|
+
# contributors may be used to endorse or promote products derived from
|
21
|
+
# this software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
|
24
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
25
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
26
|
+
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
27
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
28
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
# SERVICES; LOSS OF USE, bytes, OR PROFITS; OR BUSINESS INTERRUPTION)
|
30
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
31
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
32
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
|
35
|
+
module Virgil
|
36
|
+
module SDK
|
37
|
+
module Cryptography
|
38
|
+
# Wrapper for cryptographic operations.
|
39
|
+
#
|
40
|
+
# Class provides a cryptographic operations in applications, such as hashing,
|
41
|
+
# signature generation and verification, and encryption and decryption
|
42
|
+
class VirgilCrypto
|
43
|
+
include Virgil::Crypto
|
44
|
+
|
45
|
+
# Exception raised when Signature is not valid
|
46
|
+
class SignatureIsNotValid < StandardError
|
47
|
+
def to_s
|
48
|
+
"Signature is not valid"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
CUSTOM_PARAM_KEY_SIGNATURE = Crypto::Bytes.from_string(
|
53
|
+
'VIRGIL-DATA-SIGNATURE'
|
54
|
+
)
|
55
|
+
|
56
|
+
# Generates asymmetric key pair that is comprised of both public and private keys by specified type.
|
57
|
+
# Args:
|
58
|
+
# key_pair_type: type of the generated keys.
|
59
|
+
# The possible values can be found in KeyPairType enum.
|
60
|
+
# Returns:
|
61
|
+
# Generated key pair.
|
62
|
+
def generate_keys(key_pair_type=Keys::KeyPairType::Default)
|
63
|
+
native_type = Keys::KeyPairType.convert_to_native(key_pair_type)
|
64
|
+
native_key_pair = Crypto::Native::VirgilKeyPair.generate(native_type)
|
65
|
+
key_pair_id = self.compute_public_key_hash(native_key_pair.public_key)
|
66
|
+
private_key = Keys::PrivateKey.new(
|
67
|
+
key_pair_id,
|
68
|
+
wrap_bytes(
|
69
|
+
Crypto::Native::VirgilKeyPair.private_key_to_der(
|
70
|
+
native_key_pair.private_key
|
71
|
+
)
|
72
|
+
)
|
73
|
+
)
|
74
|
+
public_key = Keys::PublicKey.new(
|
75
|
+
key_pair_id,
|
76
|
+
wrap_bytes(
|
77
|
+
Crypto::Native::VirgilKeyPair.public_key_to_der(
|
78
|
+
native_key_pair.public_key
|
79
|
+
)
|
80
|
+
)
|
81
|
+
)
|
82
|
+
return Keys::KeyPair.new(private_key, public_key)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Imports the Private key from material representation.
|
86
|
+
#
|
87
|
+
# Args:
|
88
|
+
# key_bytes: key material representation bytes.
|
89
|
+
# password: private key password, nil by default.
|
90
|
+
#
|
91
|
+
# Returns:
|
92
|
+
# Imported private key.
|
93
|
+
def import_private_key(key_bytes, password=nil)
|
94
|
+
decrypted_private_key = if !password
|
95
|
+
Crypto::Native::VirgilKeyPair.private_key_to_der(key_bytes)
|
96
|
+
else
|
97
|
+
Crypto::Native::VirgilKeyPair.decrypt_private_key(
|
98
|
+
key_bytes,
|
99
|
+
Crypto::Bytes.from_string(password)
|
100
|
+
)
|
101
|
+
end
|
102
|
+
|
103
|
+
public_key_bytes = Crypto::Native::VirgilKeyPair.extract_public_key(
|
104
|
+
decrypted_private_key, []
|
105
|
+
)
|
106
|
+
key_pair_id = self.compute_public_key_hash(public_key_bytes)
|
107
|
+
private_key_bytes = Crypto::Native::VirgilKeyPair.private_key_to_der(
|
108
|
+
decrypted_private_key
|
109
|
+
)
|
110
|
+
return Keys::PrivateKey.new(key_pair_id, wrap_bytes(private_key_bytes))
|
111
|
+
end
|
112
|
+
|
113
|
+
# Imports the Public key from material representation.
|
114
|
+
#
|
115
|
+
# Args:
|
116
|
+
# key_bytes: key material representation bytes.
|
117
|
+
#
|
118
|
+
# Returns:
|
119
|
+
# Imported public key.
|
120
|
+
def import_public_key(key_bytes)
|
121
|
+
key_pair_id = self.compute_public_key_hash(key_bytes)
|
122
|
+
public_key_bytes =
|
123
|
+
Crypto::Native::VirgilKeyPair.public_key_to_der(key_bytes)
|
124
|
+
Keys::PublicKey.new(key_pair_id, wrap_bytes(public_key_bytes))
|
125
|
+
end
|
126
|
+
|
127
|
+
# Exports the Private key into material representation.
|
128
|
+
#
|
129
|
+
# Args:
|
130
|
+
# private_key: private key for export.
|
131
|
+
# password: private key password, nil by default.
|
132
|
+
#
|
133
|
+
# Returns:
|
134
|
+
# Key material representation bytes.
|
135
|
+
def export_private_key(private_key, password=nil)
|
136
|
+
unless password
|
137
|
+
return Crypto::Native::VirgilKeyPair.private_key_to_der(
|
138
|
+
private_key.value
|
139
|
+
)
|
140
|
+
end
|
141
|
+
|
142
|
+
password_bytes = Crypto::Bytes.from_string(password)
|
143
|
+
private_key_bytes = Crypto::Native::VirgilKeyPair.encrypt_private_key(
|
144
|
+
private_key.value,
|
145
|
+
password_bytes
|
146
|
+
)
|
147
|
+
wrap_bytes(
|
148
|
+
Crypto::Native::VirgilKeyPair.private_key_to_der(
|
149
|
+
private_key_bytes,
|
150
|
+
password_bytes
|
151
|
+
)
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Exports the Public key into material representation.
|
156
|
+
#
|
157
|
+
# Args:
|
158
|
+
# public_key: public key for export.
|
159
|
+
#
|
160
|
+
# Returns:
|
161
|
+
# Key material representation bytes.
|
162
|
+
def export_public_key(public_key)
|
163
|
+
wrap_bytes(
|
164
|
+
Crypto::Native::VirgilKeyPair.public_key_to_der(public_key.value)
|
165
|
+
)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Extracts the Public key from Private key.
|
169
|
+
#
|
170
|
+
# Args:
|
171
|
+
# private_key: source private key for extraction.
|
172
|
+
#
|
173
|
+
# Returns:
|
174
|
+
# Exported public key.
|
175
|
+
def extract_public_key(private_key)
|
176
|
+
public_key_bytes = Crypto::Native::VirgilKeyPair.extract_public_key(
|
177
|
+
private_key.value,
|
178
|
+
[]
|
179
|
+
)
|
180
|
+
Keys::PublicKey.new(
|
181
|
+
private_key.receiver_id,
|
182
|
+
wrap_bytes(
|
183
|
+
Crypto::Native::VirgilKeyPair.public_key_to_der(public_key_bytes)
|
184
|
+
)
|
185
|
+
)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Encrypts the specified bytes using recipients Public keys.
|
189
|
+
#
|
190
|
+
# Args:
|
191
|
+
# bytes: raw data bytes for encryption.
|
192
|
+
# recipients: list of recipients' public keys.
|
193
|
+
#
|
194
|
+
# Returns:
|
195
|
+
# Encrypted bytes bytes.
|
196
|
+
def encrypt(bytes, *recipients)
|
197
|
+
cipher = Crypto::Native::VirgilCipher.new
|
198
|
+
recipients.each do |public_key|
|
199
|
+
cipher.add_key_recipient(public_key.receiver_id, public_key.value)
|
200
|
+
end
|
201
|
+
wrap_bytes(cipher.encrypt(bytes))
|
202
|
+
end
|
203
|
+
|
204
|
+
# Decrypts the specified bytes using Private key.
|
205
|
+
#
|
206
|
+
# Args:
|
207
|
+
# bytes: encrypted bytes bytes for decryption.
|
208
|
+
# private_key: private key for decryption.
|
209
|
+
#
|
210
|
+
# Returns:
|
211
|
+
# Decrypted bytes bytes.
|
212
|
+
def decrypt(cipher_bytes, private_key)
|
213
|
+
cipher = Crypto::Native::VirgilCipher.new
|
214
|
+
decrypted_bytes = cipher.decrypt_with_key(
|
215
|
+
cipher_bytes,
|
216
|
+
private_key.receiver_id,
|
217
|
+
private_key.value
|
218
|
+
)
|
219
|
+
wrap_bytes(decrypted_bytes)
|
220
|
+
end
|
221
|
+
|
222
|
+
# Signs and encrypts the data.
|
223
|
+
#
|
224
|
+
# Args:
|
225
|
+
# bytes: data bytes for signing and encryption.
|
226
|
+
# private_key: private key to sign the data.
|
227
|
+
# recipients: list of recipients' public keys.
|
228
|
+
# Used for data encryption.
|
229
|
+
#
|
230
|
+
# Returns:
|
231
|
+
# Signed and encrypted data bytes.
|
232
|
+
def sign_then_encrypt(bytes, private_key, *recipients)
|
233
|
+
signer = Crypto::Native::VirgilSigner.new
|
234
|
+
signature = signer.sign(bytes, private_key.value)
|
235
|
+
cipher = Crypto::Native::VirgilCipher.new
|
236
|
+
custom_bytes = cipher.custom_params
|
237
|
+
custom_bytes.set_data(
|
238
|
+
CUSTOM_PARAM_KEY_SIGNATURE,
|
239
|
+
signature
|
240
|
+
)
|
241
|
+
recipients.each do |public_key|
|
242
|
+
cipher.add_key_recipient(public_key.receiver_id, public_key.value)
|
243
|
+
end
|
244
|
+
wrap_bytes(cipher.encrypt(bytes))
|
245
|
+
end
|
246
|
+
|
247
|
+
# Decrypts and verifies the data.
|
248
|
+
#
|
249
|
+
# Args:
|
250
|
+
# bytes: encrypted data bytes.
|
251
|
+
# private_key: private key for decryption.
|
252
|
+
# public_key: public key for verification.
|
253
|
+
#
|
254
|
+
# Returns:
|
255
|
+
# Decrypted data bytes.
|
256
|
+
#
|
257
|
+
# Raises:
|
258
|
+
# SignatureIsNotValid: if signature is not verified.
|
259
|
+
def decrypt_then_verify(bytes, private_key, public_key)
|
260
|
+
cipher = Crypto::Native::VirgilCipher.new
|
261
|
+
decrypted_bytes = cipher.decrypt_with_key(
|
262
|
+
bytes,
|
263
|
+
private_key.receiver_id,
|
264
|
+
private_key.value
|
265
|
+
)
|
266
|
+
signature = cipher.custom_params.get_data(CUSTOM_PARAM_KEY_SIGNATURE)
|
267
|
+
is_valid = self.verify(decrypted_bytes, signature, public_key)
|
268
|
+
unless is_valid
|
269
|
+
raise SignatureIsNotValid.new
|
270
|
+
end
|
271
|
+
wrap_bytes(decrypted_bytes)
|
272
|
+
end
|
273
|
+
|
274
|
+
# Signs the specified data using Private key.
|
275
|
+
#
|
276
|
+
# Args:
|
277
|
+
# bytes: raw data bytes for signing.
|
278
|
+
# private_key: private key for signing.
|
279
|
+
#
|
280
|
+
# Returns:
|
281
|
+
# Signature data.
|
282
|
+
def sign(bytes, private_key)
|
283
|
+
signer = Crypto::Native::VirgilSigner.new
|
284
|
+
wrap_bytes(signer.sign(bytes, private_key.value))
|
285
|
+
end
|
286
|
+
|
287
|
+
# Verifies the specified signature using original data and signer's public key.
|
288
|
+
#
|
289
|
+
# Args:
|
290
|
+
# bytes: original data bytes for verification.
|
291
|
+
# signature: signature bytes for verification.
|
292
|
+
# signer_public_key: signer public key for verification.
|
293
|
+
#
|
294
|
+
# Returns:
|
295
|
+
# True if signature is valid, False otherwise.
|
296
|
+
def verify(bytes, signature, signer_public_key)
|
297
|
+
signer = Crypto::Native::VirgilSigner.new
|
298
|
+
signer.verify(bytes, signature, signer_public_key.value)
|
299
|
+
end
|
300
|
+
|
301
|
+
# Encrypts the specified stream using recipients Public keys.
|
302
|
+
#
|
303
|
+
# Args:
|
304
|
+
# input_stream: readable stream containing input bytes.
|
305
|
+
# output_stream: writable stream for output.
|
306
|
+
# recipients: list of recipients' public keys.
|
307
|
+
def encrypt_stream(input_stream, output_stream, *recipients)
|
308
|
+
cipher = Crypto::Native::VirgilChunkCipher.new
|
309
|
+
recipients.each do |public_key|
|
310
|
+
cipher.add_key_recipient(public_key.receiver_id, public_key.value)
|
311
|
+
end
|
312
|
+
source = Crypto::VirgilStreamDataSource.new(input_stream)
|
313
|
+
sink = Crypto::VirgilStreamDataSink.new(output_stream)
|
314
|
+
wrap_bytes(cipher.encrypt(source, sink))
|
315
|
+
end
|
316
|
+
|
317
|
+
# Decrypts the specified stream using Private key.
|
318
|
+
#
|
319
|
+
# Args:
|
320
|
+
# input_stream: readable stream containing input data.
|
321
|
+
# output_stream: writable stream for output.
|
322
|
+
# private_key: private key for decryption.
|
323
|
+
def decrypt_stream(input_stream, output_stream, private_key)
|
324
|
+
cipher = Crypto::Native::VirgilChunkCipher.new
|
325
|
+
source = Crypto::VirgilStreamDataSource.new(input_stream)
|
326
|
+
sink = Crypto::VirgilStreamDataSink.new(output_stream)
|
327
|
+
cipher.decrypt_with_key(
|
328
|
+
source,
|
329
|
+
sink,
|
330
|
+
private_key.receiver_id,
|
331
|
+
private_key.value
|
332
|
+
)
|
333
|
+
end
|
334
|
+
|
335
|
+
# Signs the specified stream using Private key.
|
336
|
+
#
|
337
|
+
# Args:
|
338
|
+
# input_stream: readable stream containing input data.
|
339
|
+
# private_key: private key for signing.
|
340
|
+
#
|
341
|
+
# Returns:
|
342
|
+
# Signature bytes.
|
343
|
+
def sign_stream(input_stream, private_key)
|
344
|
+
signer = Crypto::Native::VirgilStreamSigner.new
|
345
|
+
source = Crypto::VirgilStreamDataSource.new(input_stream)
|
346
|
+
wrap_bytes(signer.sign(source, private_key.value))
|
347
|
+
end
|
348
|
+
|
349
|
+
# Verifies the specified signature using original stream and signer's Public key.
|
350
|
+
#
|
351
|
+
# Args:
|
352
|
+
# input_stream: readable stream containing input data.
|
353
|
+
# signature: signature bytes for verification.
|
354
|
+
# signer_public_key: signer public key for verification.
|
355
|
+
#
|
356
|
+
# Returns:
|
357
|
+
# True if signature is valid, False otherwise.
|
358
|
+
def verify_stream(input_stream, signature, signer_public_key)
|
359
|
+
signer = Crypto::Native::VirgilStreamSigner.new
|
360
|
+
source = Crypto::VirgilStreamDataSource.new(input_stream)
|
361
|
+
signer.verify(source, signature, signer_public_key.value)
|
362
|
+
end
|
363
|
+
|
364
|
+
# Calculates the fingerprint.
|
365
|
+
#
|
366
|
+
# Args:
|
367
|
+
# bytes: data bytes for fingerprint calculation.
|
368
|
+
#
|
369
|
+
# Returns:
|
370
|
+
# Fingerprint of the source data.
|
371
|
+
def calculate_fingerprint(bytes)
|
372
|
+
hash_bytes = self.compute_hash(bytes, Hashes::HashAlgorithm::SHA256)
|
373
|
+
Hashes::Fingerprint.new(hash_bytes)
|
374
|
+
end
|
375
|
+
|
376
|
+
# Computes the hash of specified data.
|
377
|
+
#
|
378
|
+
# Args:
|
379
|
+
# bytes: data bytes for fingerprint calculation.
|
380
|
+
# algorithm: hashing algorithm.
|
381
|
+
# The possible values can be found in HashAlgorithm enum.
|
382
|
+
#
|
383
|
+
# Returns:
|
384
|
+
# Hash bytes.
|
385
|
+
def compute_hash(bytes, algorithm)
|
386
|
+
native_algorithm = Hashes::HashAlgorithm.convert_to_native(algorithm)
|
387
|
+
native_hasher = Crypto::Native::VirgilHash.new(native_algorithm)
|
388
|
+
wrap_bytes(native_hasher.hash(bytes))
|
389
|
+
end
|
390
|
+
|
391
|
+
# Computes the hash of specified public key using SHA256 algorithm.
|
392
|
+
#
|
393
|
+
# Args:
|
394
|
+
# public_key: public key for hashing.
|
395
|
+
#
|
396
|
+
# Returns:
|
397
|
+
# Hash bytes.
|
398
|
+
def compute_public_key_hash(public_key)
|
399
|
+
public_key_der = Crypto::Native::VirgilKeyPair.public_key_to_der(public_key)
|
400
|
+
self.compute_hash(public_key_der, Hashes::HashAlgorithm::SHA256)
|
401
|
+
end
|
402
|
+
|
403
|
+
private
|
404
|
+
|
405
|
+
def wrap_bytes(raw_bytes)
|
406
|
+
Crypto::Bytes.new(raw_bytes)
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
end
|
411
|
+
end
|