Migrated xcbc plugin to INIT/METHOD macros
This commit is contained in:
@@ -27,10 +27,11 @@ typedef struct private_xcbc_t private_xcbc_t;
|
|||||||
* The variable names are the same as in the RFC.
|
* The variable names are the same as in the RFC.
|
||||||
*/
|
*/
|
||||||
struct private_xcbc_t {
|
struct private_xcbc_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public xcbc_t interface.
|
* Public xcbc_t interface.
|
||||||
*/
|
*/
|
||||||
xcbc_t xcbc;
|
xcbc_t public;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Block size, in bytes
|
* Block size, in bytes
|
||||||
@@ -135,9 +136,9 @@ static void final(private_xcbc_t *this, u_int8_t *out)
|
|||||||
if (this->remaining_bytes == this->b && !this->zero)
|
if (this->remaining_bytes == this->b && !this->zero)
|
||||||
{
|
{
|
||||||
/* a) If the blocksize of M[n] is 128 bits:
|
/* a) If the blocksize of M[n] is 128 bits:
|
||||||
* XOR M[n] with E[n-1] and Key K2, then encrypt the result with
|
* XOR M[n] with E[n-1] and Key K2, then encrypt the result with
|
||||||
* Key K1, yielding E[n].
|
* Key K1, yielding E[n].
|
||||||
*/
|
*/
|
||||||
memxor(this->e, this->remaining, this->b);
|
memxor(this->e, this->remaining, this->b);
|
||||||
memxor(this->e, this->k2, this->b);
|
memxor(this->e, this->k2, this->b);
|
||||||
this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
|
this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
|
||||||
@@ -147,20 +148,20 @@ static void final(private_xcbc_t *this, u_int8_t *out)
|
|||||||
/* b) If the blocksize of M[n] is less than 128 bits:
|
/* b) If the blocksize of M[n] is less than 128 bits:
|
||||||
*
|
*
|
||||||
* i) Pad M[n] with a single "1" bit, followed by the number of
|
* i) Pad M[n] with a single "1" bit, followed by the number of
|
||||||
* "0" bits (possibly none) required to increase M[n]'s
|
* "0" bits (possibly none) required to increase M[n]'s
|
||||||
* blocksize to 128 bits.
|
* blocksize to 128 bits.
|
||||||
*/
|
*/
|
||||||
if (this->remaining_bytes < this->b)
|
if (this->remaining_bytes < this->b)
|
||||||
{
|
{
|
||||||
this->remaining[this->remaining_bytes] = 0x80;
|
this->remaining[this->remaining_bytes] = 0x80;
|
||||||
while (++this->remaining_bytes < this->b)
|
while (++this->remaining_bytes < this->b)
|
||||||
{
|
{
|
||||||
this->remaining[this->remaining_bytes] = 0x00;
|
this->remaining[this->remaining_bytes] = 0x00;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* ii) XOR M[n] with E[n-1] and Key K3, then encrypt the result
|
/* ii) XOR M[n] with E[n-1] and Key K3, then encrypt the result
|
||||||
* with Key K1, yielding E[n].
|
* with Key K1, yielding E[n].
|
||||||
*/
|
*/
|
||||||
memxor(this->e, this->remaining, this->b);
|
memxor(this->e, this->remaining, this->b);
|
||||||
memxor(this->e, this->k3, this->b);
|
memxor(this->e, this->k3, this->b);
|
||||||
this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
|
this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
|
||||||
@@ -174,10 +175,8 @@ static void final(private_xcbc_t *this, u_int8_t *out)
|
|||||||
this->zero = TRUE;
|
this->zero = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(xcbc_t, get_mac, void,
|
||||||
* Implementation of xcbc_t.get_mac.
|
private_xcbc_t *this, chunk_t data, u_int8_t *out)
|
||||||
*/
|
|
||||||
static void get_mac(private_xcbc_t *this, chunk_t data, u_int8_t *out)
|
|
||||||
{
|
{
|
||||||
/* update E, do not process last block */
|
/* update E, do not process last block */
|
||||||
update(this, data);
|
update(this, data);
|
||||||
@@ -188,18 +187,14 @@ static void get_mac(private_xcbc_t *this, chunk_t data, u_int8_t *out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(xcbc_t, get_block_size, size_t,
|
||||||
* Implementation of xcbc_t.get_block_size.
|
private_xcbc_t *this)
|
||||||
*/
|
|
||||||
static size_t get_block_size(private_xcbc_t *this)
|
|
||||||
{
|
{
|
||||||
return this->b;
|
return this->b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(xcbc_t, set_key, void,
|
||||||
* Implementation of xcbc_t.set_key.
|
private_xcbc_t *this, chunk_t key)
|
||||||
*/
|
|
||||||
static void set_key(private_xcbc_t *this, chunk_t key)
|
|
||||||
{
|
{
|
||||||
chunk_t iv, k1, lengthened;
|
chunk_t iv, k1, lengthened;
|
||||||
|
|
||||||
@@ -228,11 +223,11 @@ static void set_key(private_xcbc_t *this, chunk_t key)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (1) Derive 3 128-bit keys (K1, K2 and K3) from the 128-bit secret
|
* (1) Derive 3 128-bit keys (K1, K2 and K3) from the 128-bit secret
|
||||||
* key K, as follows:
|
* key K, as follows:
|
||||||
* K1 = 0x01010101010101010101010101010101 encrypted with Key K
|
* K1 = 0x01010101010101010101010101010101 encrypted with Key K
|
||||||
* K2 = 0x02020202020202020202020202020202 encrypted with Key K
|
* K2 = 0x02020202020202020202020202020202 encrypted with Key K
|
||||||
* K3 = 0x03030303030303030303030303030303 encrypted with Key K
|
* K3 = 0x03030303030303030303030303030303 encrypted with Key K
|
||||||
*/
|
*/
|
||||||
this->k1->set_key(this->k1, lengthened);
|
this->k1->set_key(this->k1, lengthened);
|
||||||
memset(this->k2, 0x02, this->b);
|
memset(this->k2, 0x02, this->b);
|
||||||
this->k1->encrypt(this->k1, chunk_create(this->k2, this->b), iv, NULL);
|
this->k1->encrypt(this->k1, chunk_create(this->k2, this->b), iv, NULL);
|
||||||
@@ -243,10 +238,8 @@ static void set_key(private_xcbc_t *this, chunk_t key)
|
|||||||
this->k1->set_key(this->k1, k1);
|
this->k1->set_key(this->k1, k1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(xcbc_t, destroy, void,
|
||||||
* Implementation of xcbc_t.destroy.
|
private_xcbc_t *this)
|
||||||
*/
|
|
||||||
static void destroy(private_xcbc_t *this)
|
|
||||||
{
|
{
|
||||||
this->k1->destroy(this->k1);
|
this->k1->destroy(this->k1);
|
||||||
free(this->k2);
|
free(this->k2);
|
||||||
@@ -263,35 +256,38 @@ xcbc_t *xcbc_create(encryption_algorithm_t algo, size_t key_size)
|
|||||||
{
|
{
|
||||||
private_xcbc_t *this;
|
private_xcbc_t *this;
|
||||||
crypter_t *crypter;
|
crypter_t *crypter;
|
||||||
|
u_int8_t b;
|
||||||
|
|
||||||
crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size);
|
crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size);
|
||||||
if (!crypter)
|
if (!crypter)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
b = crypter->get_block_size(crypter);
|
||||||
/* input and output of crypter must be equal for xcbc */
|
/* input and output of crypter must be equal for xcbc */
|
||||||
if (crypter->get_block_size(crypter) != key_size)
|
if (b != key_size)
|
||||||
{
|
{
|
||||||
crypter->destroy(crypter);
|
crypter->destroy(crypter);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
this = malloc_thing(private_xcbc_t);
|
INIT(this,
|
||||||
this->xcbc.get_mac = (void (*)(xcbc_t *,chunk_t,u_int8_t*))get_mac;
|
.public = {
|
||||||
this->xcbc.get_block_size = (size_t (*)(xcbc_t *))get_block_size;
|
.get_mac = _get_mac,
|
||||||
this->xcbc.set_key = (void (*)(xcbc_t *,chunk_t))set_key;
|
.get_block_size = _get_block_size,
|
||||||
this->xcbc.destroy = (void (*)(xcbc_t *))destroy;
|
.set_key = _set_key,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.b = b,
|
||||||
|
.k1 = crypter,
|
||||||
|
.k2 = malloc(b),
|
||||||
|
.k3 = malloc(b),
|
||||||
|
.e = malloc(b),
|
||||||
|
.remaining = malloc(b),
|
||||||
|
.zero = TRUE,
|
||||||
|
);
|
||||||
|
memset(this->e, 0, b);
|
||||||
|
|
||||||
this->b = crypter->get_block_size(crypter);
|
return &this->public;
|
||||||
this->k1 = crypter;
|
|
||||||
this->k2 = malloc(this->b);
|
|
||||||
this->k3 = malloc(this->b);
|
|
||||||
this->e = malloc(this->b);
|
|
||||||
memset(this->e, 0, this->b);
|
|
||||||
this->remaining = malloc(this->b);
|
|
||||||
this->remaining_bytes = 0;
|
|
||||||
this->zero = TRUE;
|
|
||||||
|
|
||||||
return &this->xcbc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,10 +32,8 @@ struct private_xcbc_plugin_t {
|
|||||||
xcbc_plugin_t public;
|
xcbc_plugin_t public;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
METHOD(plugin_t, destroy, void,
|
||||||
* Implementation of xcbc_plugin_t.xcbctroy
|
private_xcbc_plugin_t *this)
|
||||||
*/
|
|
||||||
static void destroy(private_xcbc_plugin_t *this)
|
|
||||||
{
|
{
|
||||||
lib->crypto->remove_prf(lib->crypto,
|
lib->crypto->remove_prf(lib->crypto,
|
||||||
(prf_constructor_t)xcbc_prf_create);
|
(prf_constructor_t)xcbc_prf_create);
|
||||||
@@ -49,9 +47,11 @@ static void destroy(private_xcbc_plugin_t *this)
|
|||||||
*/
|
*/
|
||||||
plugin_t *xcbc_plugin_create()
|
plugin_t *xcbc_plugin_create()
|
||||||
{
|
{
|
||||||
private_xcbc_plugin_t *this = malloc_thing(private_xcbc_plugin_t);
|
private_xcbc_plugin_t *this;
|
||||||
|
|
||||||
this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
|
INIT(this,
|
||||||
|
.public.plugin.destroy = _destroy,
|
||||||
|
);
|
||||||
|
|
||||||
lib->crypto->add_prf(lib->crypto, PRF_AES128_XCBC,
|
lib->crypto->add_prf(lib->crypto, PRF_AES128_XCBC,
|
||||||
(prf_constructor_t)xcbc_prf_create);
|
(prf_constructor_t)xcbc_prf_create);
|
||||||
|
|||||||
@@ -35,18 +35,14 @@ struct private_xcbc_prf_t {
|
|||||||
xcbc_t *xcbc;
|
xcbc_t *xcbc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
METHOD(prf_t, get_bytes, void,
|
||||||
* Implementation of prf_t.get_bytes.
|
private_xcbc_prf_t *this, chunk_t seed, u_int8_t *buffer)
|
||||||
*/
|
|
||||||
static void get_bytes(private_xcbc_prf_t *this, chunk_t seed, u_int8_t *buffer)
|
|
||||||
{
|
{
|
||||||
this->xcbc->get_mac(this->xcbc, seed, buffer);
|
this->xcbc->get_mac(this->xcbc, seed, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(prf_t, allocate_bytes, void,
|
||||||
* Implementation of prf_t.allocate_bytes.
|
private_xcbc_prf_t *this, chunk_t seed, chunk_t *chunk)
|
||||||
*/
|
|
||||||
static void allocate_bytes(private_xcbc_prf_t *this, chunk_t seed, chunk_t *chunk)
|
|
||||||
{
|
{
|
||||||
if (chunk)
|
if (chunk)
|
||||||
{
|
{
|
||||||
@@ -59,35 +55,27 @@ static void allocate_bytes(private_xcbc_prf_t *this, chunk_t seed, chunk_t *chun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(prf_t, get_block_size, size_t,
|
||||||
* Implementation of prf_t.get_block_size.
|
private_xcbc_prf_t *this)
|
||||||
*/
|
|
||||||
static size_t get_block_size(private_xcbc_prf_t *this)
|
|
||||||
{
|
{
|
||||||
return this->xcbc->get_block_size(this->xcbc);
|
return this->xcbc->get_block_size(this->xcbc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(prf_t, get_key_size, size_t,
|
||||||
* Implementation of prf_t.get_block_size.
|
private_xcbc_prf_t *this)
|
||||||
*/
|
|
||||||
static size_t get_key_size(private_xcbc_prf_t *this)
|
|
||||||
{
|
{
|
||||||
/* in xcbc, block and key size are always equal */
|
/* in xcbc, block and key size are always equal */
|
||||||
return this->xcbc->get_block_size(this->xcbc);
|
return this->xcbc->get_block_size(this->xcbc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(prf_t, set_key, void,
|
||||||
* Implementation of prf_t.set_key.
|
private_xcbc_prf_t *this, chunk_t key)
|
||||||
*/
|
|
||||||
static void set_key(private_xcbc_prf_t *this, chunk_t key)
|
|
||||||
{
|
{
|
||||||
this->xcbc->set_key(this->xcbc, key);
|
this->xcbc->set_key(this->xcbc, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(prf_t, destroy, void,
|
||||||
* Implementation of prf_t.destroy.
|
private_xcbc_prf_t *this)
|
||||||
*/
|
|
||||||
static void destroy(private_xcbc_prf_t *this)
|
|
||||||
{
|
{
|
||||||
this->xcbc->destroy(this->xcbc);
|
this->xcbc->destroy(this->xcbc);
|
||||||
free(this);
|
free(this);
|
||||||
@@ -114,15 +102,17 @@ xcbc_prf_t *xcbc_prf_create(pseudo_random_function_t algo)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
this = malloc_thing(private_xcbc_prf_t);
|
INIT(this,
|
||||||
this->xcbc = xcbc;
|
.public.prf = {
|
||||||
|
.get_bytes = _get_bytes,
|
||||||
this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
|
.allocate_bytes = _allocate_bytes,
|
||||||
this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
|
.get_block_size = _get_block_size,
|
||||||
this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
|
.get_key_size = _get_key_size,
|
||||||
this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
|
.set_key = _set_key,
|
||||||
this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
|
.destroy = _destroy,
|
||||||
this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
|
},
|
||||||
|
.xcbc = xcbc,
|
||||||
|
);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ typedef struct xcbc_prf_t xcbc_prf_t;
|
|||||||
struct xcbc_prf_t {
|
struct xcbc_prf_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic prf_t interface for this xcbc_prf_t class.
|
* Implements prf_t interface.
|
||||||
*/
|
*/
|
||||||
prf_t prf_interface;
|
prf_t prf;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,11 +41,8 @@ struct private_xcbc_signer_t {
|
|||||||
size_t block_size;
|
size_t block_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
METHOD(signer_t, get_signature, void,
|
||||||
* Implementation of signer_t.get_signature.
|
private_xcbc_signer_t *this, chunk_t data, u_int8_t *buffer)
|
||||||
*/
|
|
||||||
static void get_signature(private_xcbc_signer_t *this,
|
|
||||||
chunk_t data, u_int8_t *buffer)
|
|
||||||
{
|
{
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
{ /* append mode */
|
{ /* append mode */
|
||||||
@@ -60,11 +57,8 @@ static void get_signature(private_xcbc_signer_t *this,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(signer_t, allocate_signature, void,
|
||||||
* Implementation of signer_t.allocate_signature.
|
private_xcbc_signer_t *this, chunk_t data, chunk_t *chunk)
|
||||||
*/
|
|
||||||
static void allocate_signature (private_xcbc_signer_t *this,
|
|
||||||
chunk_t data, chunk_t *chunk)
|
|
||||||
{
|
{
|
||||||
if (chunk == NULL)
|
if (chunk == NULL)
|
||||||
{ /* append mode */
|
{ /* append mode */
|
||||||
@@ -83,11 +77,8 @@ static void allocate_signature (private_xcbc_signer_t *this,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(signer_t, verify_signature, bool,
|
||||||
* Implementation of signer_t.verify_signature.
|
private_xcbc_signer_t *this, chunk_t data, chunk_t signature)
|
||||||
*/
|
|
||||||
static bool verify_signature(private_xcbc_signer_t *this,
|
|
||||||
chunk_t data, chunk_t signature)
|
|
||||||
{
|
{
|
||||||
u_int8_t mac[this->xcbc->get_block_size(this->xcbc)];
|
u_int8_t mac[this->xcbc->get_block_size(this->xcbc)];
|
||||||
|
|
||||||
@@ -100,38 +91,29 @@ static bool verify_signature(private_xcbc_signer_t *this,
|
|||||||
return memeq(signature.ptr, mac, this->block_size);
|
return memeq(signature.ptr, mac, this->block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(signer_t, get_key_size, size_t,
|
||||||
* Implementation of signer_t.get_key_size.
|
private_xcbc_signer_t *this)
|
||||||
*/
|
|
||||||
static size_t get_key_size(private_xcbc_signer_t *this)
|
|
||||||
{
|
{
|
||||||
return this->xcbc->get_block_size(this->xcbc);
|
return this->xcbc->get_block_size(this->xcbc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(signer_t, get_block_size, size_t,
|
||||||
* Implementation of signer_t.get_block_size.
|
private_xcbc_signer_t *this)
|
||||||
*/
|
|
||||||
static size_t get_block_size(private_xcbc_signer_t *this)
|
|
||||||
{
|
{
|
||||||
return this->block_size;
|
return this->block_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(signer_t, set_key, void,
|
||||||
* Implementation of signer_t.set_key.
|
private_xcbc_signer_t *this, chunk_t key)
|
||||||
*/
|
|
||||||
static void set_key(private_xcbc_signer_t *this, chunk_t key)
|
|
||||||
{
|
{
|
||||||
this->xcbc->set_key(this->xcbc, key);
|
this->xcbc->set_key(this->xcbc, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
METHOD(signer_t, destroy, void,
|
||||||
* Implementation of signer_t.destroy.
|
private_xcbc_signer_t *this)
|
||||||
*/
|
|
||||||
static status_t destroy(private_xcbc_signer_t *this)
|
|
||||||
{
|
{
|
||||||
this->xcbc->destroy(this->xcbc);
|
this->xcbc->destroy(this->xcbc);
|
||||||
free(this);
|
free(this);
|
||||||
return SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -157,18 +139,19 @@ xcbc_signer_t *xcbc_signer_create(integrity_algorithm_t algo)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
this = malloc_thing(private_xcbc_signer_t);
|
INIT(this,
|
||||||
this->xcbc = xcbc;
|
.public.signer = {
|
||||||
this->block_size = min(trunc, xcbc->get_block_size(xcbc));
|
.get_signature = _get_signature,
|
||||||
|
.allocate_signature = _allocate_signature,
|
||||||
/* interface functions */
|
.verify_signature = _verify_signature,
|
||||||
this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature;
|
.get_key_size = _get_key_size,
|
||||||
this->public.signer_interface.allocate_signature = (void (*) (signer_t*, chunk_t, chunk_t*))allocate_signature;
|
.get_block_size = _get_block_size,
|
||||||
this->public.signer_interface.verify_signature = (bool (*) (signer_t*, chunk_t, chunk_t))verify_signature;
|
.set_key = _set_key,
|
||||||
this->public.signer_interface.get_key_size = (size_t (*) (signer_t*))get_key_size;
|
.destroy = _destroy,
|
||||||
this->public.signer_interface.get_block_size = (size_t (*) (signer_t*))get_block_size;
|
},
|
||||||
this->public.signer_interface.set_key = (void (*) (signer_t*,chunk_t))set_key;
|
.xcbc = xcbc,
|
||||||
this->public.signer_interface.destroy = (void (*) (signer_t*))destroy;
|
.block_size = min(trunc, xcbc->get_block_size(xcbc)),
|
||||||
|
);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ typedef struct xcbc_signer_t xcbc_signer_t;
|
|||||||
struct xcbc_signer_t {
|
struct xcbc_signer_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* generic signer_t interface for this signer
|
* Implements signer_t interface.
|
||||||
*/
|
*/
|
||||||
signer_t signer_interface;
|
signer_t signer;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user