virgil-sdk 4.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|