virgil-sdk 4.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +15 -0
  4. data/Gemfile +4 -0
  5. data/README.md +134 -0
  6. data/Rakefile +9 -0
  7. data/bin/console +16 -0
  8. data/bin/setup +8 -0
  9. data/dockefiles/Dockerfile-200 +25 -0
  10. data/dockefiles/Dockerfile-2110 +36 -0
  11. data/dockefiles/Dockerfile-220 +26 -0
  12. data/dockefiles/Dockerfile-226 +25 -0
  13. data/dockefiles/Dockerfile-233 +25 -0
  14. data/dockefiles/Dockerfile-240 +26 -0
  15. data/docker-compose.yml +107 -0
  16. data/lib/virgil/sdk.rb +10 -0
  17. data/lib/virgil/sdk/client.rb +47 -0
  18. data/lib/virgil/sdk/client/card.rb +142 -0
  19. data/lib/virgil/sdk/client/card_validator.rb +104 -0
  20. data/lib/virgil/sdk/client/http.rb +45 -0
  21. data/lib/virgil/sdk/client/http/base_connection.rb +112 -0
  22. data/lib/virgil/sdk/client/http/cards_service_connection.rb +113 -0
  23. data/lib/virgil/sdk/client/http/request.rb +63 -0
  24. data/lib/virgil/sdk/client/request_signer.rb +90 -0
  25. data/lib/virgil/sdk/client/requests.rb +50 -0
  26. data/lib/virgil/sdk/client/requests/confirm_identity_request.rb +67 -0
  27. data/lib/virgil/sdk/client/requests/create_card_request.rb +105 -0
  28. data/lib/virgil/sdk/client/requests/revoke_card_request.rb +85 -0
  29. data/lib/virgil/sdk/client/requests/signable_request.rb +142 -0
  30. data/lib/virgil/sdk/client/requests/verify_identity_request.rb +60 -0
  31. data/lib/virgil/sdk/client/search_criteria.rb +79 -0
  32. data/lib/virgil/sdk/client/signatures_base64.rb +25 -0
  33. data/lib/virgil/sdk/client/virgil_client.rb +425 -0
  34. data/lib/virgil/sdk/cryptography.rb +42 -0
  35. data/lib/virgil/sdk/cryptography/hashes.rb +44 -0
  36. data/lib/virgil/sdk/cryptography/hashes/fingerprint.rb +79 -0
  37. data/lib/virgil/sdk/cryptography/hashes/hash_algorithm.rb +91 -0
  38. data/lib/virgil/sdk/cryptography/keys.rb +48 -0
  39. data/lib/virgil/sdk/cryptography/keys/key_pair.rb +46 -0
  40. data/lib/virgil/sdk/cryptography/keys/key_pair_type.rb +108 -0
  41. data/lib/virgil/sdk/cryptography/keys/key_storage.rb +177 -0
  42. data/lib/virgil/sdk/cryptography/keys/private_key.rb +44 -0
  43. data/lib/virgil/sdk/cryptography/keys/public_key.rb +44 -0
  44. data/lib/virgil/sdk/cryptography/keys/storage_item.rb +63 -0
  45. data/lib/virgil/sdk/cryptography/virgil_crypto.rb +411 -0
  46. data/lib/virgil/sdk/high_level.rb +21 -0
  47. data/lib/virgil/sdk/high_level/virgil_api.rb +71 -0
  48. data/lib/virgil/sdk/high_level/virgil_app_credentials.rb +54 -0
  49. data/lib/virgil/sdk/high_level/virgil_buffer.rb +161 -0
  50. data/lib/virgil/sdk/high_level/virgil_card.rb +204 -0
  51. data/lib/virgil/sdk/high_level/virgil_card_manager.rb +294 -0
  52. data/lib/virgil/sdk/high_level/virgil_card_verifier_info.rb +49 -0
  53. data/lib/virgil/sdk/high_level/virgil_context.rb +69 -0
  54. data/lib/virgil/sdk/high_level/virgil_identity.rb +17 -0
  55. data/lib/virgil/sdk/high_level/virgil_identity/email_confirmation.rb +60 -0
  56. data/lib/virgil/sdk/high_level/virgil_identity/validation_token.rb +49 -0
  57. data/lib/virgil/sdk/high_level/virgil_identity/verification_attempt.rb +69 -0
  58. data/lib/virgil/sdk/high_level/virgil_identity/verification_options.rb +56 -0
  59. data/lib/virgil/sdk/high_level/virgil_key.rb +168 -0
  60. data/lib/virgil/sdk/high_level/virgil_key_manager.rb +97 -0
  61. data/lib/virgil/sdk/version.rb +5 -0
  62. data/virgil-sdk.gemspec +31 -0
  63. 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