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
data/lib/botan/kdf.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# (c) 2017 Ribose Inc.
|
4
|
+
|
5
|
+
require 'ffi'
|
6
|
+
|
7
|
+
require 'botan/defaults'
|
8
|
+
require 'botan/utils'
|
9
|
+
|
10
|
+
module Botan
|
11
|
+
# Key Derivation Functions
|
12
|
+
#
|
13
|
+
# == Examples
|
14
|
+
# === examples/kdf.rb
|
15
|
+
# {include:file:examples/kdf.rb}
|
16
|
+
module KDF
|
17
|
+
# Derives a key using the given KDF algorithm.
|
18
|
+
#
|
19
|
+
# @param secret [String] the secret input
|
20
|
+
# @param key_length [Integer] the desired length of the key to produce
|
21
|
+
# @param label [String] purpose for the derived keying material
|
22
|
+
# @param algo [String] the KDF algorithm name
|
23
|
+
# @param salt [String] the randomly chosen salt
|
24
|
+
# @return [String] the derived key
|
25
|
+
def self.kdf(secret:, key_length:,
|
26
|
+
label: '',
|
27
|
+
algo: DEFAULT_KDF_ALGO,
|
28
|
+
salt: RNG.get(DEFAULT_KDF_SALT_LENGTH))
|
29
|
+
out_buf = FFI::MemoryPointer.new(:uint8, key_length)
|
30
|
+
|
31
|
+
secret_buf = FFI::MemoryPointer.from_data(secret)
|
32
|
+
salt_buf = FFI::MemoryPointer.from_data(salt)
|
33
|
+
label_buf = FFI::MemoryPointer.from_data(label)
|
34
|
+
Botan.call_ffi(:botan_kdf,
|
35
|
+
algo, out_buf, out_buf.size,
|
36
|
+
secret_buf, secret_buf.size,
|
37
|
+
salt_buf, salt_buf.size,
|
38
|
+
label_buf, label_buf.size)
|
39
|
+
out_buf.read_bytes(key_length)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Derives a key using the given PBKDF algorithm.
|
43
|
+
#
|
44
|
+
# @param password [String] the password to derive the key from
|
45
|
+
# @param key_length [Integer] the desired length of the key to produce
|
46
|
+
# @param algo [String] the PBKDF algorithm name
|
47
|
+
# @param iterations [Integer] the number of iterations to use
|
48
|
+
# @param salt [String] the randomly chosen salt
|
49
|
+
# @return [String] the derived key
|
50
|
+
def self.pbkdf(password:, key_length:,
|
51
|
+
algo: DEFAULT_PBKDF_ALGO,
|
52
|
+
iterations: DEFAULT_KDF_ITERATIONS,
|
53
|
+
salt: RNG.get(DEFAULT_KDF_SALT_LENGTH))
|
54
|
+
out_buf = FFI::MemoryPointer.new(:uint8, key_length)
|
55
|
+
salt_buf = FFI::MemoryPointer.from_data(salt)
|
56
|
+
Botan.call_ffi(:botan_pbkdf,
|
57
|
+
algo, out_buf, key_length,
|
58
|
+
password, salt_buf, salt_buf.size, iterations)
|
59
|
+
out_buf.read_bytes(key_length)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Derives a key using the given PBKDF algorithm.
|
63
|
+
#
|
64
|
+
# @param password [String] the password to derive the key from
|
65
|
+
# @param key_length [Integer] teh desired length of the key to rpoduce
|
66
|
+
# @param milliseconds [Integer] the number of milliseconds to run
|
67
|
+
# @param algo [String] the PBKDF algorithm name
|
68
|
+
# @param salt [String] the randomly chosen salt
|
69
|
+
# @return [Hash<Symbol>]
|
70
|
+
# * :iterations [Integer] the iteration count used
|
71
|
+
# * :key [String] the derived key
|
72
|
+
def self.pbkdf_timed(password:, key_length:, milliseconds:,
|
73
|
+
algo: DEFAULT_PBKDF_ALGO,
|
74
|
+
salt: RNG.get(DEFAULT_KDF_SALT_LENGTH))
|
75
|
+
out_buf = FFI::MemoryPointer.new(:uint8, key_length)
|
76
|
+
salt_buf = FFI::MemoryPointer.from_data(salt)
|
77
|
+
iterations_ptr = FFI::MemoryPointer.new(:size_t)
|
78
|
+
Botan.call_ffi(:botan_pbkdf_timed,
|
79
|
+
algo, out_buf, key_length,
|
80
|
+
password, salt_buf, salt_buf.size,
|
81
|
+
milliseconds, iterations_ptr)
|
82
|
+
{ iterations: iterations_ptr.read(:size_t),
|
83
|
+
key: out_buf.read_bytes(key_length) }
|
84
|
+
end
|
85
|
+
end # module
|
86
|
+
end # module
|
87
|
+
|
data/lib/botan/mac.rb
ADDED
@@ -0,0 +1,90 @@
|
|
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/utils'
|
10
|
+
|
11
|
+
module Botan
|
12
|
+
# Message Authentication Code
|
13
|
+
#
|
14
|
+
# == Examples
|
15
|
+
# === examples/mac.rb
|
16
|
+
# {include:file:examples/mac.rb}
|
17
|
+
class MAC
|
18
|
+
# @param algo [String] the MAC algorithm name
|
19
|
+
def initialize(algo)
|
20
|
+
flags = 0
|
21
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
22
|
+
Botan.call_ffi(:botan_mac_init, ptr, algo, flags)
|
23
|
+
ptr = ptr.read_pointer
|
24
|
+
raise Botan::Error, 'botan_mac_init returned NULL' if ptr.null?
|
25
|
+
@ptr = FFI::AutoPointer.new(ptr, self.class.method(:destroy))
|
26
|
+
end
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
def self.destroy(ptr)
|
30
|
+
LibBotan.botan_mac_destroy(ptr)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Resets the instace back to a clean state, as if no key and
|
34
|
+
# input have been supplied.
|
35
|
+
#
|
36
|
+
# @return [self]
|
37
|
+
def reset
|
38
|
+
Botan.call_ffi(:botan_mac_clear, @ptr)
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
# Retrieve the output length of the MAC.
|
43
|
+
#
|
44
|
+
# @return [Integer]
|
45
|
+
def output_length
|
46
|
+
length_ptr = FFI::MemoryPointer.new(:size_t)
|
47
|
+
Botan.call_ffi(:botan_mac_output_length, @ptr, length_ptr)
|
48
|
+
length_ptr.read(:size_t)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sets the key for the MAC.
|
52
|
+
# This must be called before {#update}.
|
53
|
+
#
|
54
|
+
# @param [String] key
|
55
|
+
def key=(key)
|
56
|
+
Botan.call_ffi(:botan_mac_set_key, @ptr, key, key.bytesize)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Adds input to the MAC computation.
|
60
|
+
#
|
61
|
+
# @param [String] data
|
62
|
+
# @return [self]
|
63
|
+
def update(data)
|
64
|
+
Botan.call_ffi(:botan_mac_update, @ptr, data, data.bytesize)
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def digest
|
69
|
+
out_buf = FFI::MemoryPointer.new(:uint8, output_length)
|
70
|
+
Botan.call_ffi(:botan_mac_final, @ptr, out_buf)
|
71
|
+
out_buf.read_bytes(out_buf.size)
|
72
|
+
end
|
73
|
+
|
74
|
+
def hexdigest
|
75
|
+
Botan.hex_encode(digest)
|
76
|
+
end
|
77
|
+
|
78
|
+
def inspect
|
79
|
+
Botan.inspect_ptr(self)
|
80
|
+
end
|
81
|
+
|
82
|
+
alias << update
|
83
|
+
|
84
|
+
# TODO: it's not safe to do this at the moment, since these
|
85
|
+
# methods mutate the state.
|
86
|
+
# alias inspect hexdigest
|
87
|
+
# alias to_s hexdigest
|
88
|
+
end # class
|
89
|
+
end # module
|
90
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# (c) 2017 Ribose Inc.
|
4
|
+
|
5
|
+
require 'ffi'
|
6
|
+
|
7
|
+
require 'botan/ffi/libbotan'
|
8
|
+
require 'botan/utils'
|
9
|
+
|
10
|
+
module Botan
|
11
|
+
module PK
|
12
|
+
# Encrypts with McEliece.
|
13
|
+
#
|
14
|
+
# @param public_key [Botan::PK::PublicKey] the public key
|
15
|
+
# @param plaintext [String] the data to encrypt
|
16
|
+
# @param ad [String] the associated data
|
17
|
+
# @param aead [String] the (AEAD) cipher+mode
|
18
|
+
# @param rng [Botan::RNG] the RNG to use
|
19
|
+
# @return [String] the encrypted data
|
20
|
+
def self.mceies_encrypt(public_key:, plaintext:, ad:,
|
21
|
+
aead: DEFAULT_AEAD,
|
22
|
+
rng: Botan::RNG.new)
|
23
|
+
pt_buf = FFI::MemoryPointer.from_data(plaintext)
|
24
|
+
ad_buf = FFI::MemoryPointer.from_data(ad)
|
25
|
+
Botan.call_ffi_with_buffer(lambda { |b, bl|
|
26
|
+
LibBotan.botan_mceies_encrypt(public_key.ptr,
|
27
|
+
rng.ptr,
|
28
|
+
aead,
|
29
|
+
pt_buf,
|
30
|
+
pt_buf.size,
|
31
|
+
ad_buf,
|
32
|
+
ad_buf.size,
|
33
|
+
b,
|
34
|
+
bl)
|
35
|
+
})
|
36
|
+
end
|
37
|
+
|
38
|
+
# Decrypts with McEliece.
|
39
|
+
#
|
40
|
+
# @param private_key [Botan::PK::PrivateKey] the private key
|
41
|
+
# @param ciphertext [String] the data to decrypt
|
42
|
+
# @param ad [String] the associated data
|
43
|
+
# @param aead [String] the (AEAD) cipher+mode
|
44
|
+
# @return [String] the decrypted data
|
45
|
+
def self.mceies_decrypt(private_key:, ciphertext:, ad:,
|
46
|
+
aead: DEFAULT_AEAD)
|
47
|
+
ct_buf = FFI::MemoryPointer.from_data(ciphertext)
|
48
|
+
ad_buf = FFI::MemoryPointer.from_data(ad)
|
49
|
+
Botan.call_ffi_with_buffer(lambda { |b, bl|
|
50
|
+
LibBotan.botan_mceies_decrypt(private_key.ptr,
|
51
|
+
aead,
|
52
|
+
ct_buf,
|
53
|
+
ct_buf.size,
|
54
|
+
ad_buf,
|
55
|
+
ad.size,
|
56
|
+
b,
|
57
|
+
bl)
|
58
|
+
})
|
59
|
+
end
|
60
|
+
end # module
|
61
|
+
end # module
|
62
|
+
|
@@ -0,0 +1,59 @@
|
|
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/privatekey'
|
11
|
+
require 'botan/utils'
|
12
|
+
|
13
|
+
module Botan
|
14
|
+
module PK
|
15
|
+
# Public Key Decrypt Operation
|
16
|
+
#
|
17
|
+
# See {Botan::PK::PrivateKey#decrypt} for a simpler interface.
|
18
|
+
class Decrypt
|
19
|
+
# @param key [Botan::PK::PrivateKey] the private key
|
20
|
+
# @param padding [String] the padding method name
|
21
|
+
def initialize(key:, padding: nil)
|
22
|
+
padding ||= Botan::DEFAULT_EME
|
23
|
+
unless key.instance_of?(PrivateKey)
|
24
|
+
raise Botan::Error, 'Decryption requires an instance of PrivateKey'
|
25
|
+
end
|
26
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
27
|
+
flags = 0
|
28
|
+
Botan.call_ffi(:botan_pk_op_decrypt_create,
|
29
|
+
ptr, key.ptr, padding, flags)
|
30
|
+
ptr = ptr.read_pointer
|
31
|
+
if ptr.null?
|
32
|
+
raise Botan::Error, 'botan_pk_op_decrypt_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_decrypt_destroy(ptr)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Decrypts the provided data.
|
43
|
+
#
|
44
|
+
# @param msg [String] the data
|
45
|
+
# @return [String] the decrypted data
|
46
|
+
def decrypt(msg)
|
47
|
+
msg_buf = FFI::MemoryPointer.from_data(msg)
|
48
|
+
Botan.call_ffi_with_buffer(lambda { |b, bl|
|
49
|
+
LibBotan.botan_pk_op_decrypt(@ptr, b, bl, msg_buf, msg_buf.size)
|
50
|
+
})
|
51
|
+
end
|
52
|
+
|
53
|
+
def inspect
|
54
|
+
Botan.inspect_ptr(self)
|
55
|
+
end
|
56
|
+
end # class
|
57
|
+
end # module
|
58
|
+
end # module
|
59
|
+
|
@@ -0,0 +1,62 @@
|
|
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/rng'
|
12
|
+
require 'botan/utils'
|
13
|
+
|
14
|
+
module Botan
|
15
|
+
module PK
|
16
|
+
# Public Key Encrypt Operation
|
17
|
+
#
|
18
|
+
# See {Botan::PK::PublicKey#encrypt} for a simpler interface.
|
19
|
+
class Encrypt
|
20
|
+
# @param key [Botan::PK::PublicKey] the public key
|
21
|
+
# @param padding [String] the padding method name
|
22
|
+
def initialize(key:, padding: nil)
|
23
|
+
padding ||= Botan::DEFAULT_EME
|
24
|
+
unless key.instance_of?(PublicKey)
|
25
|
+
raise Botan::Error, 'Encryption requires an instance of PublicKey'
|
26
|
+
end
|
27
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
28
|
+
flags = 0
|
29
|
+
Botan.call_ffi(:botan_pk_op_encrypt_create,
|
30
|
+
ptr, key.ptr, padding, flags)
|
31
|
+
ptr = ptr.read_pointer
|
32
|
+
if ptr.null?
|
33
|
+
raise Botan::Error, 'botan_pk_op_encrypt_create returned NULL'
|
34
|
+
end
|
35
|
+
@ptr = FFI::AutoPointer.new(ptr, self.class.method(:destroy))
|
36
|
+
end
|
37
|
+
|
38
|
+
# @api private
|
39
|
+
def self.destroy(ptr)
|
40
|
+
LibBotan.botan_pk_op_encrypt_destroy(ptr)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Encrypts the provided data.
|
44
|
+
#
|
45
|
+
# @param msg [String] the data
|
46
|
+
# @param rng [Botan::PK::RNG] the RNG to use
|
47
|
+
# @return [String] the encrypted data
|
48
|
+
def encrypt(msg, rng: Botan::RNG.new)
|
49
|
+
msg_buf = FFI::MemoryPointer.from_data(msg)
|
50
|
+
Botan.call_ffi_with_buffer(lambda { |b, bl|
|
51
|
+
LibBotan.botan_pk_op_encrypt(@ptr, rng.ptr, b, bl,
|
52
|
+
msg_buf, msg_buf.size)
|
53
|
+
})
|
54
|
+
end
|
55
|
+
|
56
|
+
def inspect
|
57
|
+
Botan.inspect_ptr(self)
|
58
|
+
end
|
59
|
+
end # class
|
60
|
+
end # module
|
61
|
+
end # module
|
62
|
+
|
@@ -0,0 +1,59 @@
|
|
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/privatekey'
|
11
|
+
require 'botan/utils'
|
12
|
+
|
13
|
+
module Botan
|
14
|
+
module PK
|
15
|
+
# Public Key Key Agreement Operation
|
16
|
+
class KeyAgreement
|
17
|
+
attr_reader :public_value
|
18
|
+
# @param key [Botan::PK::PrivateKey] the private key
|
19
|
+
# @param kdf [String] the KDF algorithm name
|
20
|
+
def initialize(key:, kdf: Botan::DEFAULT_KDF_ALGO)
|
21
|
+
unless key.instance_of?(PrivateKey)
|
22
|
+
raise Botan::Error, 'KeyAgreement requires an instance of PrivateKey'
|
23
|
+
end
|
24
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
25
|
+
flags = 0
|
26
|
+
Botan.call_ffi(:botan_pk_op_key_agreement_create,
|
27
|
+
ptr, key.ptr, kdf, flags)
|
28
|
+
ptr = ptr.read_pointer
|
29
|
+
if ptr.null?
|
30
|
+
raise Botan::Error, 'botan_pk_op_key_agreement_create returned NULL'
|
31
|
+
end
|
32
|
+
@ptr = FFI::AutoPointer.new(ptr, self.class.method(:destroy))
|
33
|
+
@public_value = Botan.call_ffi_with_buffer(lambda { |b, bl|
|
34
|
+
LibBotan.botan_pk_op_key_agreement_export_public(key.ptr, b, bl)
|
35
|
+
})
|
36
|
+
end
|
37
|
+
|
38
|
+
# @api private
|
39
|
+
def self.destroy(ptr)
|
40
|
+
LibBotan.botan_pk_op_key_agreement_destroy(ptr)
|
41
|
+
end
|
42
|
+
|
43
|
+
def agree(other_key:, key_length:, salt:)
|
44
|
+
other_buf = FFI::MemoryPointer.from_data(other_key)
|
45
|
+
salt_buf = FFI::MemoryPointer.from_data(salt)
|
46
|
+
Botan.call_ffi_with_buffer(lambda { |b, bl|
|
47
|
+
LibBotan.botan_pk_op_key_agreement(@ptr, b, bl,
|
48
|
+
other_buf, other_buf.size,
|
49
|
+
salt_buf, salt_buf.size)
|
50
|
+
}, guess: key_length)
|
51
|
+
end
|
52
|
+
|
53
|
+
def inspect
|
54
|
+
Botan.inspect_ptr(self)
|
55
|
+
end
|
56
|
+
end # class
|
57
|
+
end # module
|
58
|
+
end # module
|
59
|
+
|
@@ -0,0 +1,68 @@
|
|
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/privatekey'
|
11
|
+
require 'botan/rng'
|
12
|
+
require 'botan/utils'
|
13
|
+
|
14
|
+
module Botan
|
15
|
+
module PK
|
16
|
+
# Public Key Sign Operation
|
17
|
+
#
|
18
|
+
# See {Botan::PK::PrivateKey#sign} for a simpler interface.
|
19
|
+
class Sign
|
20
|
+
# @param key [Botan::PK::PrivateKey] the private key
|
21
|
+
# @param padding [String] the padding method name
|
22
|
+
def initialize(key:, padding: nil)
|
23
|
+
padding ||= Botan::DEFAULT_EMSA[key.algo]
|
24
|
+
unless key.instance_of?(PrivateKey)
|
25
|
+
raise Botan::Error, 'Signing requires an instance of PrivateKey'
|
26
|
+
end
|
27
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
28
|
+
flags = 0
|
29
|
+
Botan.call_ffi(:botan_pk_op_sign_create, ptr, key.ptr, padding, flags)
|
30
|
+
ptr = ptr.read_pointer
|
31
|
+
raise Botan::Error, 'botan_pk_op_sign_create returned NULL' if ptr.null?
|
32
|
+
@ptr = FFI::AutoPointer.new(ptr, self.class.method(:destroy))
|
33
|
+
end
|
34
|
+
|
35
|
+
# @api private
|
36
|
+
def self.destroy(ptr)
|
37
|
+
LibBotan.botan_pk_op_sign_destroy(ptr)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Adds data to the message currently being signed.
|
41
|
+
#
|
42
|
+
# @param msg [String] the data to add
|
43
|
+
# @return [self]
|
44
|
+
def update(msg)
|
45
|
+
msg_buf = FFI::MemoryPointer.from_data(msg)
|
46
|
+
Botan.call_ffi(:botan_pk_op_sign_update, @ptr, msg_buf, msg_buf.size)
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Finalizes the signature operation.
|
51
|
+
#
|
52
|
+
# @param rng [Botan::PK::RNG] the RNG to use
|
53
|
+
# @return [String] the signature
|
54
|
+
def finish(rng = Botan::RNG.new)
|
55
|
+
Botan.call_ffi_with_buffer(lambda { |b, bl|
|
56
|
+
LibBotan.botan_pk_op_sign_finish(@ptr, rng.ptr, b, bl)
|
57
|
+
})
|
58
|
+
end
|
59
|
+
|
60
|
+
def inspect
|
61
|
+
Botan.inspect_ptr(self)
|
62
|
+
end
|
63
|
+
|
64
|
+
alias << update
|
65
|
+
end # class
|
66
|
+
end # module
|
67
|
+
end # module
|
68
|
+
|