botan 0.1.0
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/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
|
+
|