botan 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +219 -0
- data/lib/botan.rb +25 -0
- data/lib/botan/bcrypt.rb +49 -0
- data/lib/botan/cipher.rb +214 -0
- data/lib/botan/defaults.rb +21 -0
- data/lib/botan/digest.rb +145 -0
- data/lib/botan/error.rb +8 -0
- data/lib/botan/ffi/libbotan.rb +573 -0
- data/lib/botan/kdf.rb +87 -0
- data/lib/botan/mac.rb +90 -0
- data/lib/botan/pk/mceies.rb +62 -0
- data/lib/botan/pk/op/decrypt.rb +59 -0
- data/lib/botan/pk/op/encrypt.rb +62 -0
- data/lib/botan/pk/op/keyagreement.rb +59 -0
- data/lib/botan/pk/op/sign.rb +68 -0
- data/lib/botan/pk/op/verify.rb +71 -0
- data/lib/botan/pk/privatekey.rb +288 -0
- data/lib/botan/pk/publickey.rb +161 -0
- data/lib/botan/rng.rb +62 -0
- data/lib/botan/utils.rb +104 -0
- data/lib/botan/version.rb +8 -0
- data/lib/botan/x509/certificate.rb +139 -0
- data/lib/botan/x509/constraints.rb +20 -0
- metadata +197 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# (c) 2017 Ribose Inc.
|
4
|
+
|
5
|
+
require 'ffi'
|
6
|
+
|
7
|
+
require 'botan/defaults'
|
8
|
+
require 'botan/error'
|
9
|
+
require 'botan/ffi/libbotan'
|
10
|
+
require 'botan/pk/publickey'
|
11
|
+
require 'botan/utils'
|
12
|
+
|
13
|
+
module Botan
|
14
|
+
module PK
|
15
|
+
# Public Key Verify Operation
|
16
|
+
#
|
17
|
+
# See {Botan::PK::PublicKey#verify} for a simpler interface.
|
18
|
+
class Verify
|
19
|
+
# @param key [Botan::PK::PublicKey] the public key
|
20
|
+
# @param padding [String] the padding method name
|
21
|
+
def initialize(key:, padding: nil)
|
22
|
+
padding ||= Botan::DEFAULT_EMSA[key.algo]
|
23
|
+
unless key.instance_of?(PublicKey)
|
24
|
+
raise Botan::Error, 'Verify requires an instance of PublicKey'
|
25
|
+
end
|
26
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
27
|
+
flags = 0
|
28
|
+
Botan.call_ffi(:botan_pk_op_verify_create,
|
29
|
+
ptr, key.ptr, padding, flags)
|
30
|
+
ptr = ptr.read_pointer
|
31
|
+
if ptr.null?
|
32
|
+
raise Botan::Error, 'botan_pk_op_verify_create returned NULL'
|
33
|
+
end
|
34
|
+
@ptr = FFI::AutoPointer.new(ptr, self.class.method(:destroy))
|
35
|
+
end
|
36
|
+
|
37
|
+
# @api private
|
38
|
+
def self.destroy(ptr)
|
39
|
+
LibBotan.botan_pk_op_verify_destroy(ptr)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Adds more data to the message currently being verified.
|
43
|
+
#
|
44
|
+
# @param msg [String] the data to add
|
45
|
+
# @return [self]
|
46
|
+
def update(msg)
|
47
|
+
msg_buf = FFI::MemoryPointer.from_data(msg)
|
48
|
+
Botan.call_ffi(:botan_pk_op_verify_update, @ptr, msg_buf, msg_buf.size)
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
# Checks the signature against the previously-provided data.
|
53
|
+
#
|
54
|
+
# @param signature [String] the signature to check
|
55
|
+
# @return [Boolean] true if the signature is valid
|
56
|
+
def check_signature(signature)
|
57
|
+
sig_buf = FFI::MemoryPointer.from_data(signature)
|
58
|
+
rc = Botan.call_ffi_rc(:botan_pk_op_verify_finish,
|
59
|
+
@ptr, sig_buf, sig_buf.size)
|
60
|
+
rc.zero?
|
61
|
+
end
|
62
|
+
|
63
|
+
def inspect
|
64
|
+
Botan.inspect_ptr(self)
|
65
|
+
end
|
66
|
+
|
67
|
+
alias << update
|
68
|
+
end # class
|
69
|
+
end # module
|
70
|
+
end # module
|
71
|
+
|
@@ -0,0 +1,288 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# (c) 2017 Ribose Inc.
|
4
|
+
|
5
|
+
require 'ffi'
|
6
|
+
require 'forwardable'
|
7
|
+
|
8
|
+
require 'botan/error'
|
9
|
+
require 'botan/ffi/libbotan'
|
10
|
+
require 'botan/pk/op/decrypt'
|
11
|
+
require 'botan/pk/op/sign'
|
12
|
+
require 'botan/pk/publickey'
|
13
|
+
require 'botan/rng'
|
14
|
+
require 'botan/utils'
|
15
|
+
|
16
|
+
module Botan
|
17
|
+
module PK
|
18
|
+
# Private Key
|
19
|
+
class PrivateKey
|
20
|
+
extend ::Forwardable
|
21
|
+
delegate %i[algo encrypt estimated_strength verify] => :public_key
|
22
|
+
# @!method algo
|
23
|
+
# @see Botan::PK::PublicKey#algo
|
24
|
+
# @!method encrypt
|
25
|
+
# @see Botan::PK::PublicKey#encrypt
|
26
|
+
# @!method estimated_strength
|
27
|
+
# @see Botan::PK::PublicKey#estimated_strength
|
28
|
+
# @!method verify
|
29
|
+
# @see Botan::PK::PublicKey#verify
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
attr_reader :ptr
|
33
|
+
# @api private
|
34
|
+
#
|
35
|
+
# See {generate} and {from_data} instead.
|
36
|
+
def initialize(ptr)
|
37
|
+
raise Botan::Error, 'PrivateKey received a NULL pointer' if ptr.null?
|
38
|
+
@ptr = FFI::AutoPointer.new(ptr, self.class.method(:destroy))
|
39
|
+
end
|
40
|
+
|
41
|
+
# @api private
|
42
|
+
def self.destroy(ptr)
|
43
|
+
LibBotan.botan_privkey_destroy(ptr)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Generates a new key pair.
|
47
|
+
#
|
48
|
+
# @param algo [String] the public-key algorithm name
|
49
|
+
# @param params [String] algorithm-specific parameters
|
50
|
+
# @param rng [Botan::RNG] the RNG to use
|
51
|
+
# @return [Botan::PK::PrivateKey]
|
52
|
+
def self.generate(algo, params: nil, rng: Botan::RNG.new)
|
53
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
54
|
+
Botan.call_ffi(:botan_privkey_create, ptr, algo, params, rng.ptr)
|
55
|
+
ptr = ptr.read_pointer
|
56
|
+
raise Botan::Error, 'botan_privkey_create failed' if ptr.null?
|
57
|
+
PrivateKey.new(ptr)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Creates a {PrivateKey} from BER/PEM data.
|
61
|
+
#
|
62
|
+
# @param data [String] the private key data in a supported format
|
63
|
+
# @return [Botan::PK::PrivateKey]
|
64
|
+
def self.from_data(data, password: nil, rng: Botan::RNG.new)
|
65
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
66
|
+
buf = FFI::MemoryPointer.from_data(data)
|
67
|
+
Botan.call_ffi(:botan_privkey_load, ptr, rng.ptr,
|
68
|
+
buf, buf.size, password)
|
69
|
+
PrivateKey.new(ptr.read_pointer)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the {PublicKey} portion of the key pair.
|
73
|
+
#
|
74
|
+
# @return [Botan::PK::PublicKey]
|
75
|
+
def public_key
|
76
|
+
pubkey_ptr = FFI::MemoryPointer.new(:pointer)
|
77
|
+
Botan.call_ffi(:botan_privkey_export_pubkey, pubkey_ptr, @ptr)
|
78
|
+
PublicKey.new(pubkey_ptr.read_pointer)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Exports the *unencrypted* key with PEM encoding.
|
82
|
+
#
|
83
|
+
# @return [String]
|
84
|
+
def export_pem!
|
85
|
+
export(pem: true)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Exports the *unencrypted* key with DER encoding.
|
89
|
+
#
|
90
|
+
# @return [String]
|
91
|
+
def export_der!
|
92
|
+
export(pem: false)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Exports the encrypted key with PEM encoding.
|
96
|
+
#
|
97
|
+
# @param password [String] the password for encrypting/decrypting
|
98
|
+
# @param cipher [String] the name of the cipher to use
|
99
|
+
# @param pbkdf [String] the name of the PBKDF algorithm to use
|
100
|
+
# @param iterations [Integer] the number of iterations for PBKDF
|
101
|
+
# @param rng [Botan::RNG] the RNG to use
|
102
|
+
# @return [String]
|
103
|
+
def export_pem(password:,
|
104
|
+
cipher: nil,
|
105
|
+
pbkdf: nil,
|
106
|
+
iterations: Botan::DEFAULT_KDF_ITERATIONS,
|
107
|
+
rng: Botan::RNG.new)
|
108
|
+
export_encrypted(password: password,
|
109
|
+
pem: true,
|
110
|
+
cipher: cipher,
|
111
|
+
pbkdf: pbkdf,
|
112
|
+
iterations: iterations,
|
113
|
+
rng: rng)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Exports the encrypted key with DER encoding.
|
117
|
+
#
|
118
|
+
# @param password [String] the password for encrypting/decrypting
|
119
|
+
# @param cipher [String] the name of the cipher to use
|
120
|
+
# @param pbkdf [String] the name of the PBKDF algorithm to use
|
121
|
+
# @param iterations [Integer] the number of iterations for PBKDF
|
122
|
+
# @param rng [Botan::RNG] the RNG to use
|
123
|
+
# @return [String]
|
124
|
+
def export_der(password:,
|
125
|
+
cipher: nil,
|
126
|
+
pbkdf: nil,
|
127
|
+
iterations: Botan::DEFAULT_KDF_ITERATIONS,
|
128
|
+
rng: Botan::RNG.new)
|
129
|
+
export_encrypted(password: password,
|
130
|
+
pem: true,
|
131
|
+
cipher: cipher,
|
132
|
+
pbkdf: pbkdf,
|
133
|
+
iterations: iterations,
|
134
|
+
rng: rng)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Exports the encrypted key with PEM encoding, using a timed PBKDF.
|
138
|
+
#
|
139
|
+
# @param password [String] the password for encrypting/decrypting
|
140
|
+
# @param milliseconds [Integer] the minimum number of milliseconds to
|
141
|
+
# run the PBKDF.
|
142
|
+
# @param cipher [String] the name of the cipher to use
|
143
|
+
# @param pbkdf [String] the name of the PBKDF algorithm to use
|
144
|
+
# @param rng [Botan::RNG] the RNG to use
|
145
|
+
# @return [Hash<Symbol>]
|
146
|
+
# * :iterations [Integer] the iteration count used
|
147
|
+
# * :data [String] the PEM-encoded key
|
148
|
+
def export_pem_timed(password:,
|
149
|
+
milliseconds:,
|
150
|
+
cipher: nil,
|
151
|
+
pbkdf: nil,
|
152
|
+
rng: Botan::RNG.new)
|
153
|
+
export_encrypted_timed(password: password,
|
154
|
+
pem: true,
|
155
|
+
milliseconds: milliseconds,
|
156
|
+
cipher: cipher,
|
157
|
+
pbkdf: pbkdf,
|
158
|
+
rng: rng)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Exports the encrypted key with DER encoding, using a timed PBKDF.
|
162
|
+
#
|
163
|
+
# @param password [String] the password for encrypting/decrypting
|
164
|
+
# @param milliseconds [Integer] the minimum number of milliseconds to
|
165
|
+
# run the PBKDF.
|
166
|
+
# @param cipher [String] the name of the cipher to use
|
167
|
+
# @param pbkdf [String] the name of the PBKDF algorithm to use
|
168
|
+
# @param rng [Botan::RNG] the RNG to use
|
169
|
+
# @return [Hash<Symbol>]
|
170
|
+
# * :iterations [Integer] the iteration count used
|
171
|
+
# * :data [String] the DER-encoded key
|
172
|
+
def export_der_timed(password:,
|
173
|
+
milliseconds:,
|
174
|
+
cipher: nil,
|
175
|
+
pbkdf: nil,
|
176
|
+
rng: Botan::RNG.new)
|
177
|
+
export_encrypted_timed(password: password,
|
178
|
+
pem: false,
|
179
|
+
milliseconds: milliseconds,
|
180
|
+
cipher: cipher,
|
181
|
+
pbkdf: pbkdf,
|
182
|
+
rng: rng)
|
183
|
+
end
|
184
|
+
|
185
|
+
# Checks whether the key appears to be valid.
|
186
|
+
#
|
187
|
+
# @param rng [Botan::RNG] the RNG to use
|
188
|
+
# @param thorough [Boolean] whether to perform more thorough checks
|
189
|
+
# that may be slower
|
190
|
+
# @return [Boolean] true if the key appears to be valid
|
191
|
+
def valid?(rng = nil, thorough = false)
|
192
|
+
rng ||= Botan::RNG.new
|
193
|
+
flags = thorough ? 1 : 0
|
194
|
+
rc = LibBotan.botan_privkey_check_key(@ptr, rng.ptr, flags)
|
195
|
+
rc.zero?
|
196
|
+
end
|
197
|
+
|
198
|
+
# Retrieves a field of key material.
|
199
|
+
#
|
200
|
+
# For example, the 'e' field of an RSA key might return
|
201
|
+
# the value 0x1001.
|
202
|
+
#
|
203
|
+
# @param field [String] the name of the field to retrieve
|
204
|
+
# @return [Integer]
|
205
|
+
def get_field(field)
|
206
|
+
mp = nil
|
207
|
+
mp_ptr = FFI::MemoryPointer.new(:pointer)
|
208
|
+
Botan.call_ffi(:botan_mp_init, mp_ptr)
|
209
|
+
mp = mp_ptr.read_pointer
|
210
|
+
Botan.call_ffi(:botan_privkey_get_field, mp, @ptr, field)
|
211
|
+
hex_str = Botan.call_ffi_with_buffer(lambda { |b, bl|
|
212
|
+
LibBotan.botan_mp_to_str(mp, 16, b, bl)
|
213
|
+
}, string: true)
|
214
|
+
hex_str.hex
|
215
|
+
ensure
|
216
|
+
LibBotan.botan_mp_destroy(mp) if mp && !mp.null?
|
217
|
+
end
|
218
|
+
|
219
|
+
# Decrypts data using the key.
|
220
|
+
#
|
221
|
+
# @param data [String] the data to decrypt
|
222
|
+
# @param padding [String] the padding method to use
|
223
|
+
# @return [String] the decrypted data
|
224
|
+
def decrypt(data, padding: nil)
|
225
|
+
dec = Botan::PK::Decrypt.new(key: self, padding: padding)
|
226
|
+
dec.decrypt(data)
|
227
|
+
end
|
228
|
+
|
229
|
+
# Creates a signature using the key.
|
230
|
+
#
|
231
|
+
# @param data [String] the data to sign
|
232
|
+
# @param padding [String] the padding method
|
233
|
+
# @param rng [Botan::RNG] the RNG to use
|
234
|
+
# @return [String] the generated signature
|
235
|
+
def sign(data, padding: nil, rng: Botan::RNG.new)
|
236
|
+
sign = Botan::PK::Sign.new(key: self, padding: padding)
|
237
|
+
sign << data
|
238
|
+
sign.finish(rng)
|
239
|
+
end
|
240
|
+
|
241
|
+
def inspect
|
242
|
+
Botan.inspect_ptr(self)
|
243
|
+
end
|
244
|
+
|
245
|
+
private
|
246
|
+
|
247
|
+
def export(pem:)
|
248
|
+
flags = pem ? 1 : 0
|
249
|
+
Botan.call_ffi_with_buffer(lambda { |b, bl|
|
250
|
+
LibBotan.botan_privkey_export(@ptr, b, bl, flags)
|
251
|
+
}, string: pem)
|
252
|
+
end
|
253
|
+
|
254
|
+
def export_encrypted(password:,
|
255
|
+
pem: true,
|
256
|
+
cipher: nil,
|
257
|
+
pbkdf: nil,
|
258
|
+
iterations: Botan::DEFAULT_KDF_ITERATIONS,
|
259
|
+
rng: Botan::RNG.new)
|
260
|
+
flags = pem ? 1 : 0
|
261
|
+
Botan.call_ffi_with_buffer(lambda { |b, bl|
|
262
|
+
LibBotan.botan_privkey_export_encrypted_pbkdf_iter(
|
263
|
+
@ptr, b, bl, rng.ptr, password, iterations,
|
264
|
+
cipher, pbkdf, flags
|
265
|
+
)
|
266
|
+
}, string: pem)
|
267
|
+
end
|
268
|
+
|
269
|
+
def export_encrypted_timed(password:,
|
270
|
+
milliseconds:,
|
271
|
+
pem: true,
|
272
|
+
cipher: nil,
|
273
|
+
pbkdf: nil,
|
274
|
+
rng: Botan::RNG.new)
|
275
|
+
flags = pem ? 1 : 0
|
276
|
+
iterations_ptr = FFI::MemoryPointer.new(:size_t)
|
277
|
+
data = Botan.call_ffi_with_buffer(lambda { |b, bl|
|
278
|
+
LibBotan.botan_privkey_export_encrypted_pbkdf_msec(
|
279
|
+
@ptr, b, bl, rng.ptr, password, milliseconds,
|
280
|
+
iterations_ptr, cipher, pbkdf, flags
|
281
|
+
)
|
282
|
+
}, string: pem)
|
283
|
+
{ data: data, iterations: iterations_ptr.read(:size_t) }
|
284
|
+
end
|
285
|
+
end # class
|
286
|
+
end # module
|
287
|
+
end # module
|
288
|
+
|
@@ -0,0 +1,161 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# (c) 2017 Ribose Inc.
|
4
|
+
|
5
|
+
require 'ffi'
|
6
|
+
|
7
|
+
require 'botan/error'
|
8
|
+
require 'botan/ffi/libbotan'
|
9
|
+
require 'botan/pk/op/encrypt'
|
10
|
+
require 'botan/pk/op/verify'
|
11
|
+
require 'botan/rng'
|
12
|
+
require 'botan/utils'
|
13
|
+
|
14
|
+
module Botan
|
15
|
+
module PK
|
16
|
+
# Public Key
|
17
|
+
class PublicKey
|
18
|
+
# @api private
|
19
|
+
attr_reader :ptr
|
20
|
+
def initialize(ptr)
|
21
|
+
raise Botan::Error, 'PublicKey received a NULL pointer' if ptr.null?
|
22
|
+
@ptr = FFI::AutoPointer.new(ptr, self.class.method(:destroy))
|
23
|
+
end
|
24
|
+
|
25
|
+
# @api private
|
26
|
+
def self.destroy(ptr)
|
27
|
+
LibBotan.botan_pubkey_destroy(ptr)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Creates a {PublicKey} from BER/PEM data.
|
31
|
+
#
|
32
|
+
# @param data [String] the public key data in a supported format
|
33
|
+
# @return [Botan::PK::PublicKey]
|
34
|
+
def self.from_data(data)
|
35
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
36
|
+
buf = FFI::MemoryPointer.from_data(data)
|
37
|
+
Botan.call_ffi(:botan_pubkey_load, ptr, buf, buf.size)
|
38
|
+
PublicKey.new(ptr.read_pointer)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the estimated strength of the key.
|
42
|
+
#
|
43
|
+
# @return [Integer]
|
44
|
+
def estimated_strength
|
45
|
+
strength_ptr = FFI::MemoryPointer.new(:size_t)
|
46
|
+
Botan.call_ffi(:botan_pubkey_estimated_strength, @ptr, strength_ptr)
|
47
|
+
strength_ptr.read(:size_t)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the public-key algorithm name.
|
51
|
+
#
|
52
|
+
# @return [String]
|
53
|
+
def algo
|
54
|
+
Botan.call_ffi_with_buffer(lambda { |b, bl|
|
55
|
+
LibBotan.botan_pubkey_algo_name(@ptr, b, bl)
|
56
|
+
}, guess: 32, string: true)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns the PEM-encoded public key.
|
60
|
+
#
|
61
|
+
# @return [String]
|
62
|
+
def export_pem
|
63
|
+
export(pem: true)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns the DER-encoded public key.
|
67
|
+
#
|
68
|
+
# @return [String]
|
69
|
+
def export_der
|
70
|
+
export(pem: false)
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_s
|
74
|
+
export_pem
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the fingerprint of the key.
|
78
|
+
#
|
79
|
+
# @param hash [String] the hash algorithm to use for the calculation
|
80
|
+
# @return [String]
|
81
|
+
def fingerprint(hash = 'SHA-256')
|
82
|
+
n = Botan::Digest.new(hash).length
|
83
|
+
buf = FFI::MemoryPointer.new(:uint8, n)
|
84
|
+
buf_len_ptr = FFI::MemoryPointer.new(:size_t)
|
85
|
+
buf_len_ptr.write(:size_t, n)
|
86
|
+
Botan.call_ffi(:botan_pubkey_fingerprint, @ptr, hash, buf, buf_len_ptr)
|
87
|
+
buf.read_bytes(buf_len_ptr.read(:size_t))
|
88
|
+
end
|
89
|
+
|
90
|
+
# Checks whether the key appears to be valid.
|
91
|
+
#
|
92
|
+
# @param rng [Botan::RNG] the RNG to use
|
93
|
+
# @param thorough [Boolean] whether to perform more thorough checks
|
94
|
+
# that may be slower
|
95
|
+
# @return [Boolean] true if the key appears to be valid
|
96
|
+
def valid?(rng = nil, thorough = false)
|
97
|
+
rng ||= Botan::RNG.new
|
98
|
+
flags = thorough ? 1 : 0
|
99
|
+
rc = LibBotan.botan_pubkey_check_key(@ptr, rng.ptr, flags)
|
100
|
+
rc.zero?
|
101
|
+
end
|
102
|
+
|
103
|
+
# Retrieves a field of key material.
|
104
|
+
#
|
105
|
+
# For example, the 'e' field of an RSA key might return
|
106
|
+
# the value 0x1001.
|
107
|
+
#
|
108
|
+
# @param field [String] the name of the field to retrieve
|
109
|
+
# @return [Integer]
|
110
|
+
def get_field(field)
|
111
|
+
mp = nil
|
112
|
+
mp_ptr = FFI::MemoryPointer.new(:pointer)
|
113
|
+
Botan.call_ffi(:botan_mp_init, mp_ptr)
|
114
|
+
mp = mp_ptr.read_pointer
|
115
|
+
Botan.call_ffi(:botan_pubkey_get_field, mp, @ptr, field)
|
116
|
+
hex_str = Botan.call_ffi_with_buffer(lambda { |b, bl|
|
117
|
+
LibBotan.botan_mp_to_str(mp, 16, b, bl)
|
118
|
+
}, string: true)
|
119
|
+
hex_str.hex
|
120
|
+
ensure
|
121
|
+
LibBotan.botan_mp_destroy(mp) if mp && !mp.null?
|
122
|
+
end
|
123
|
+
|
124
|
+
# Encrypts data using the key.
|
125
|
+
#
|
126
|
+
# @param data [String] the data to encrypt
|
127
|
+
# @param padding [String] the padding method to use
|
128
|
+
# @param rng [Botan::RNG] the RNG to use
|
129
|
+
# @return [String] the encrypted data
|
130
|
+
def encrypt(data, padding: nil, rng: Botan::RNG.new)
|
131
|
+
enc = Botan::PK::Encrypt.new(key: self, padding: padding)
|
132
|
+
enc.encrypt(data, rng: rng)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Verifies a signature using the key.
|
136
|
+
#
|
137
|
+
# @param data [String] the signature data to verify
|
138
|
+
# @param padding [String] the padding method
|
139
|
+
# @return [Boolean] true if the signature is valid
|
140
|
+
def verify(data:, signature:, padding: nil)
|
141
|
+
verify = Botan::PK::Verify.new(key: self, padding: padding)
|
142
|
+
verify << data
|
143
|
+
verify.check_signature(signature)
|
144
|
+
end
|
145
|
+
|
146
|
+
def inspect
|
147
|
+
Botan.inspect_ptr(self)
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
151
|
+
|
152
|
+
def export(pem:)
|
153
|
+
flags = pem ? 1 : 0
|
154
|
+
Botan.call_ffi_with_buffer(lambda { |b, bl|
|
155
|
+
LibBotan.botan_pubkey_export(@ptr, b, bl, flags)
|
156
|
+
}, string: pem)
|
157
|
+
end
|
158
|
+
end # class
|
159
|
+
end # module
|
160
|
+
end # module
|
161
|
+
|