mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Problem: Public key type not verfied during validation
Solution: Validate public key type and write correspoding tests
This commit is contained in:
parent
3811e9ff74
commit
bda1fb7708
@ -125,7 +125,7 @@ def run_upsert_validator_new(args, bigchain):
|
|||||||
|
|
||||||
new_validator = {
|
new_validator = {
|
||||||
'public_key': {'value': public_key_from_base64(args.public_key),
|
'public_key': {'value': public_key_from_base64(args.public_key),
|
||||||
'type': 'ed25519-base58'},
|
'type': 'ed25519-base16'},
|
||||||
'power': args.power,
|
'power': args.power,
|
||||||
'node_id': args.node_id
|
'node_id': args.node_id
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,3 +112,7 @@ class UnequalValidatorSet(ValidationError):
|
|||||||
|
|
||||||
class InvalidPowerChange(ValidationError):
|
class InvalidPowerChange(ValidationError):
|
||||||
"""Raised if proposed power change in validator set is >=1/3 total power"""
|
"""Raised if proposed power change in validator set is >=1/3 total power"""
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidPublicKey(ValidationError):
|
||||||
|
"""Raised if proposed power change in validator set is >=1/3 total power"""
|
||||||
|
|||||||
@ -19,7 +19,9 @@ from bigchaindb.common.schema import (_validate_schema,
|
|||||||
TX_SCHEMA_COMMON,
|
TX_SCHEMA_COMMON,
|
||||||
TX_SCHEMA_CREATE)
|
TX_SCHEMA_CREATE)
|
||||||
from . import ValidatorElectionVote
|
from . import ValidatorElectionVote
|
||||||
from .validator_utils import (new_validator_set, encode_validator)
|
from .validator_utils import (new_validator_set,
|
||||||
|
encode_validator,
|
||||||
|
validate_asset_public_key)
|
||||||
|
|
||||||
|
|
||||||
class ValidatorElection(Transaction):
|
class ValidatorElection(Transaction):
|
||||||
@ -155,6 +157,7 @@ class ValidatorElection(Transaction):
|
|||||||
_validate_schema(TX_SCHEMA_COMMON, tx)
|
_validate_schema(TX_SCHEMA_COMMON, tx)
|
||||||
_validate_schema(TX_SCHEMA_CREATE, tx)
|
_validate_schema(TX_SCHEMA_CREATE, tx)
|
||||||
_validate_schema(TX_SCHEMA_VALIDATOR_ELECTION, tx)
|
_validate_schema(TX_SCHEMA_VALIDATOR_ELECTION, tx)
|
||||||
|
validate_asset_public_key(tx['asset']['data']['public_key'])
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, tx_signers, recipients, metadata=None, asset=None):
|
def create(cls, tx_signers, recipients, metadata=None, asset=None):
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
import codecs
|
import codecs
|
||||||
|
import base64
|
||||||
|
import binascii
|
||||||
|
|
||||||
from abci.types_pb2 import (Validator,
|
from abci.types_pb2 import (Validator,
|
||||||
PubKey)
|
PubKey)
|
||||||
from bigchaindb.tendermint_utils import public_key_to_base64
|
from bigchaindb.tendermint_utils import public_key_to_base64
|
||||||
|
from bigchaindb.common.exceptions import InvalidPublicKey
|
||||||
|
|
||||||
|
|
||||||
def encode_validator(v):
|
def encode_validator(v):
|
||||||
@ -35,3 +38,24 @@ def new_validator_set(validators, updates):
|
|||||||
|
|
||||||
new_validators_dict = {**validators_dict, **updates_dict}
|
new_validators_dict = {**validators_dict, **updates_dict}
|
||||||
return list(new_validators_dict.values())
|
return list(new_validators_dict.values())
|
||||||
|
|
||||||
|
|
||||||
|
def validate_asset_public_key(pk):
|
||||||
|
pk_binary = pk['value'].encode('utf-8')
|
||||||
|
encoding = pk['type']
|
||||||
|
decoder = base64.b64decode
|
||||||
|
|
||||||
|
if encoding == 'ed25519-base16':
|
||||||
|
decoder = base64.b16decode
|
||||||
|
elif encoding == 'ed25519-base32':
|
||||||
|
decoder = base64.b32decode
|
||||||
|
elif encoding == 'ed25519-base64':
|
||||||
|
decoder = base64.b64decode
|
||||||
|
|
||||||
|
try:
|
||||||
|
pk_decoded = decoder(pk_binary)
|
||||||
|
if len(pk_decoded) != 32:
|
||||||
|
raise InvalidPublicKey('Public key should be of size 32 bytes')
|
||||||
|
|
||||||
|
except binascii.Error as e:
|
||||||
|
raise InvalidPublicKey('Invalid `type` specified for public key `value`')
|
||||||
|
|||||||
@ -352,7 +352,7 @@ def test_upsert_validator_new_with_tendermint(b, priv_validator_path, user_sk, v
|
|||||||
from bigchaindb.commands.bigchaindb import run_upsert_validator_new
|
from bigchaindb.commands.bigchaindb import run_upsert_validator_new
|
||||||
|
|
||||||
new_args = Namespace(action='new',
|
new_args = Namespace(action='new',
|
||||||
public_key='8eJ8q9ZQpReWyQT5aFCiwtZ5wDZC4eDnCen88p3tQ6ie',
|
public_key='HHG0IQRybpT6nJMIWWFWhMczCLHt6xcm7eP52GnGuPY=',
|
||||||
power=1,
|
power=1,
|
||||||
node_id='unique_node_id_for_test_upsert_validator_new_with_tendermint',
|
node_id='unique_node_id_for_test_upsert_validator_new_with_tendermint',
|
||||||
sk=priv_validator_path,
|
sk=priv_validator_path,
|
||||||
@ -429,6 +429,7 @@ def test_upsert_validator_new_election_invalid_power(caplog, b, priv_validator_p
|
|||||||
assert caplog.records[0].msg.__class__ == InvalidPowerChange
|
assert caplog.records[0].msg.__class__ == InvalidPowerChange
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.google
|
||||||
@pytest.mark.abci
|
@pytest.mark.abci
|
||||||
def test_upsert_validator_approve_with_tendermint(b, priv_validator_path, user_sk, validators):
|
def test_upsert_validator_approve_with_tendermint(b, priv_validator_path, user_sk, validators):
|
||||||
from bigchaindb.commands.bigchaindb import (run_upsert_validator_new,
|
from bigchaindb.commands.bigchaindb import (run_upsert_validator_new,
|
||||||
@ -443,6 +444,7 @@ def test_upsert_validator_approve_with_tendermint(b, priv_validator_path, user_s
|
|||||||
config={})
|
config={})
|
||||||
|
|
||||||
election_id = run_upsert_validator_new(new_args, b)
|
election_id = run_upsert_validator_new(new_args, b)
|
||||||
|
assert election_id
|
||||||
|
|
||||||
args = Namespace(action='approve',
|
args = Namespace(action='approve',
|
||||||
election_id=election_id,
|
election_id=election_id,
|
||||||
|
|||||||
@ -687,6 +687,6 @@ def new_validator():
|
|||||||
node_id = 'fake_node_id'
|
node_id = 'fake_node_id'
|
||||||
|
|
||||||
return {'public_key': {'value': public_key,
|
return {'public_key': {'value': public_key,
|
||||||
'type': 'ed25519-base58'},
|
'type': 'ed25519-base16'},
|
||||||
'power': power,
|
'power': power,
|
||||||
'node_id': node_id}
|
'node_id': node_id}
|
||||||
|
|||||||
@ -419,10 +419,10 @@ def test_new_validator_set(b):
|
|||||||
'value': 'FxjS2/8AFYoIUqF6AcePTc87qOT7e4WGgH+sGCpTUDQ='},
|
'value': 'FxjS2/8AFYoIUqF6AcePTc87qOT7e4WGgH+sGCpTUDQ='},
|
||||||
'voting_power': 10}
|
'voting_power': 10}
|
||||||
node1_new_power = {'public_key': {'value': '1718D2DBFF00158A0852A17A01C78F4DCF3BA8E4FB7B8586807FAC182A535034',
|
node1_new_power = {'public_key': {'value': '1718D2DBFF00158A0852A17A01C78F4DCF3BA8E4FB7B8586807FAC182A535034',
|
||||||
'type': 'ed25519-base58'},
|
'type': 'ed25519-base16'},
|
||||||
'power': 20}
|
'power': 20}
|
||||||
node2 = {'public_key': {'value': '1888A353B181715CA2554701D06C1665BC42C5D936C55EA9C5DBCBDB8B3F02A3',
|
node2 = {'public_key': {'value': '1888A353B181715CA2554701D06C1665BC42C5D936C55EA9C5DBCBDB8B3F02A3',
|
||||||
'type': 'ed25519-base58'},
|
'type': 'ed25519-base16'},
|
||||||
'power': 10}
|
'power': 10}
|
||||||
|
|
||||||
validators = [node1]
|
validators = [node1]
|
||||||
|
|||||||
@ -24,6 +24,19 @@ def test_upsert_validator_valid_election(b_mock, new_validator, node_key):
|
|||||||
assert election.validate(b_mock)
|
assert election.validate(b_mock)
|
||||||
|
|
||||||
|
|
||||||
|
def test_upsert_validator_invalid_election_public_key(b_mock, new_validator, node_key):
|
||||||
|
from bigchaindb.common.exceptions import InvalidPublicKey
|
||||||
|
|
||||||
|
for iv in ['ed25519-base32', 'ed25519-base64']:
|
||||||
|
new_validator['public_key']['type'] = iv
|
||||||
|
voters = ValidatorElection.recipients(b_mock)
|
||||||
|
|
||||||
|
with pytest.raises(InvalidPublicKey):
|
||||||
|
ValidatorElection.generate([node_key.public_key],
|
||||||
|
voters,
|
||||||
|
new_validator, None).sign([node_key.private_key])
|
||||||
|
|
||||||
|
|
||||||
def test_upsert_validator_invalid_power_election(b_mock, new_validator, node_key):
|
def test_upsert_validator_invalid_power_election(b_mock, new_validator, node_key):
|
||||||
voters = ValidatorElection.recipients(b_mock)
|
voters = ValidatorElection.recipients(b_mock)
|
||||||
new_validator['power'] = 30
|
new_validator['power'] = 30
|
||||||
|
|||||||
@ -238,7 +238,7 @@ def test_upsert_validator(b, node_key, node_keys, ed25519_node_keys):
|
|||||||
power = 1
|
power = 1
|
||||||
public_key = '9B3119650DF82B9A5D8A12E38953EA47475C09F0C48A4E6A0ECE182944B24403'
|
public_key = '9B3119650DF82B9A5D8A12E38953EA47475C09F0C48A4E6A0ECE182944B24403'
|
||||||
public_key64 = public_key_to_base64(public_key)
|
public_key64 = public_key_to_base64(public_key)
|
||||||
new_validator = {'public_key': {'value': public_key, 'type': 'ed25519-base58'},
|
new_validator = {'public_key': {'value': public_key, 'type': 'ed25519-base16'},
|
||||||
'node_id': 'some_node_id',
|
'node_id': 'some_node_id',
|
||||||
'power': power}
|
'power': power}
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ def test_get_validator_update(b, node_keys, node_key, ed25519_node_keys):
|
|||||||
power = 1
|
power = 1
|
||||||
public_key = '9B3119650DF82B9A5D8A12E38953EA47475C09F0C48A4E6A0ECE182944B24403'
|
public_key = '9B3119650DF82B9A5D8A12E38953EA47475C09F0C48A4E6A0ECE182944B24403'
|
||||||
public_key64 = public_key_to_base64(public_key)
|
public_key64 = public_key_to_base64(public_key)
|
||||||
new_validator = {'public_key': {'value': public_key, 'type': 'ed25519-base58'},
|
new_validator = {'public_key': {'value': public_key, 'type': 'ed25519-base16'},
|
||||||
'node_id': 'some_node_id',
|
'node_id': 'some_node_id',
|
||||||
'power': power}
|
'power': power}
|
||||||
voters = ValidatorElection.recipients(b)
|
voters = ValidatorElection.recipients(b)
|
||||||
@ -315,7 +315,7 @@ def test_get_validator_update(b, node_keys, node_key, ed25519_node_keys):
|
|||||||
|
|
||||||
# remove validator
|
# remove validator
|
||||||
power = 0
|
power = 0
|
||||||
new_validator = {'public_key': {'value': public_key, 'type': 'ed25519-base58'},
|
new_validator = {'public_key': {'value': public_key, 'type': 'ed25519-base16'},
|
||||||
'node_id': 'some_node_id',
|
'node_id': 'some_node_id',
|
||||||
'power': power}
|
'power': power}
|
||||||
voters = ValidatorElection.recipients(b)
|
voters = ValidatorElection.recipients(b)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user