detached as a parameter instead of class attribute
This commit is contained in:
parent
523c4c86a9
commit
d7ebf50602
3 changed files with 19 additions and 18 deletions
|
@ -164,9 +164,9 @@ class ClaimDict(OrderedDict):
|
||||||
signer = get_signer(curve).load_pem(private_key)
|
signer = get_signer(curve).load_pem(private_key)
|
||||||
return cls.load_protobuf(signer.certificate)
|
return cls.load_protobuf(signer.certificate)
|
||||||
|
|
||||||
def sign(self, private_key, claim_address, cert_claim_id, curve=SECP256k1, name=None):
|
def sign(self, private_key, claim_address, cert_claim_id, curve=SECP256k1, name=None, force_detached=False):
|
||||||
signer = get_signer(curve).load_pem(private_key)
|
signer = get_signer(curve).load_pem(private_key)
|
||||||
signed, signature = signer.sign_stream_claim(self, claim_address, cert_claim_id, name)
|
signed, signature = signer.sign_stream_claim(self, claim_address, cert_claim_id, name, force_detached)
|
||||||
return ClaimDict.load_protobuf(signed, signature)
|
return ClaimDict.load_protobuf(signed, signature)
|
||||||
|
|
||||||
def validate_signature(self, claim_address, certificate, name=None):
|
def validate_signature(self, claim_address, certificate, name=None):
|
||||||
|
|
|
@ -16,7 +16,6 @@ class NIST_ECDSASigner(object):
|
||||||
CURVE_NAME = None
|
CURVE_NAME = None
|
||||||
HASHFUNC = hashlib.sha256
|
HASHFUNC = hashlib.sha256
|
||||||
HASHFUNC_NAME = SHA256
|
HASHFUNC_NAME = SHA256
|
||||||
DETACHED = False
|
|
||||||
|
|
||||||
def __init__(self, private_key):
|
def __init__(self, private_key):
|
||||||
self._private_key = private_key
|
self._private_key = private_key
|
||||||
|
@ -47,9 +46,9 @@ class NIST_ECDSASigner(object):
|
||||||
def generate(cls):
|
def generate(cls):
|
||||||
return cls(ecdsa.SigningKey.generate(curve=cls.CURVE, hashfunc=cls.HASHFUNC_NAME))
|
return cls(ecdsa.SigningKey.generate(curve=cls.CURVE, hashfunc=cls.HASHFUNC_NAME))
|
||||||
|
|
||||||
def sign_stream_claim(self, claim, claim_address, cert_claim_id, name):
|
def sign_stream_claim(self, claim, claim_address, cert_claim_id, name, detached=False):
|
||||||
to_sign = bytearray()
|
to_sign = bytearray()
|
||||||
if self.DETACHED:
|
if detached:
|
||||||
assert name, "Name is required for detached signatures"
|
assert name, "Name is required for detached signatures"
|
||||||
assert self.CURVE_NAME == SECP256k1, f"Only SECP256k1 is supported, not: {self.CURVE_NAME}"
|
assert self.CURVE_NAME == SECP256k1, f"Only SECP256k1 is supported, not: {self.CURVE_NAME}"
|
||||||
to_sign.extend(name.lower().encode())
|
to_sign.extend(name.lower().encode())
|
||||||
|
@ -63,10 +62,11 @@ class NIST_ECDSASigner(object):
|
||||||
to_sign.extend(raw_cert_id)
|
to_sign.extend(raw_cert_id)
|
||||||
|
|
||||||
digest = self.HASHFUNC(to_sign).digest()
|
digest = self.HASHFUNC(to_sign).digest()
|
||||||
if self.DETACHED:
|
if detached:
|
||||||
return Claim.load(decode_b64_fields(claim.protobuf_dict)), Signature(
|
return Claim.load(decode_b64_fields(claim.protobuf_dict)), Signature(
|
||||||
self.private_key.sign_digest_deterministic(digest, hashfunc=self.HASHFUNC), raw_cert_id
|
self.private_key.sign_digest_deterministic(digest, hashfunc=self.HASHFUNC), raw_cert_id
|
||||||
)
|
)
|
||||||
|
# -- Legacy signer (signature inside protobuf) --
|
||||||
|
|
||||||
if not isinstance(self.private_key, ecdsa.SigningKey):
|
if not isinstance(self.private_key, ecdsa.SigningKey):
|
||||||
raise Exception("Not given a signing key")
|
raise Exception("Not given a signing key")
|
||||||
|
|
|
@ -333,8 +333,8 @@ class TestDetachedNamedSECP256k1Signatures(UnitTest):
|
||||||
def test_validate_detached_named_ecdsa_signature(self):
|
def test_validate_detached_named_ecdsa_signature(self):
|
||||||
cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
|
cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
|
||||||
self.assertDictEqual(cert.claim_dict, secp256k1_cert)
|
self.assertDictEqual(cert.claim_dict, secp256k1_cert)
|
||||||
signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_2,
|
signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_2, claim_id_1,
|
||||||
claim_id_1, curve=SECP256k1, name='example')
|
curve=SECP256k1, name='example', force_detached=True)
|
||||||
#self.assertDictEqual(signed.claim_dict, claim_010_signed_secp256k1)
|
#self.assertDictEqual(signed.claim_dict, claim_010_signed_secp256k1)
|
||||||
signed_copy = ClaimDict.deserialize(signed.serialized)
|
signed_copy = ClaimDict.deserialize(signed.serialized)
|
||||||
self.assertEqual(signed_copy.validate_signature(claim_address_2, cert, name='example'), True)
|
self.assertEqual(signed_copy.validate_signature(claim_address_2, cert, name='example'), True)
|
||||||
|
@ -343,13 +343,13 @@ class TestDetachedNamedSECP256k1Signatures(UnitTest):
|
||||||
cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
|
cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
|
||||||
self.assertDictEqual(cert.claim_dict, secp256k1_cert)
|
self.assertDictEqual(cert.claim_dict, secp256k1_cert)
|
||||||
self.assertRaises(Exception, ClaimDict.load_dict(example_010).sign, secp256k1_private_key,
|
self.assertRaises(Exception, ClaimDict.load_dict(example_010).sign, secp256k1_private_key,
|
||||||
None, claim_id_1, curve=SECP256k1, name='example')
|
None, claim_id_1, curve=SECP256k1, name='example', force_detached=True)
|
||||||
|
|
||||||
def test_fail_to_validate_with_no_claim_address(self):
|
def test_fail_to_validate_with_no_claim_address(self):
|
||||||
cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
|
cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
|
||||||
self.assertDictEqual(cert.claim_dict, secp256k1_cert)
|
self.assertDictEqual(cert.claim_dict, secp256k1_cert)
|
||||||
signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_2,
|
signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_2, claim_id_1,
|
||||||
claim_id_1, curve=SECP256k1, name='example')
|
curve=SECP256k1, name='example', force_detached=True)
|
||||||
#self.assertDictEqual(signed.claim_dict, claim_010_signed_secp256k1)
|
#self.assertDictEqual(signed.claim_dict, claim_010_signed_secp256k1)
|
||||||
signed_copy = ClaimDict.load_protobuf(signed.protobuf)
|
signed_copy = ClaimDict.load_protobuf(signed.protobuf)
|
||||||
self.assertRaises(Exception, signed_copy.validate_signature, None, cert, name='example')
|
self.assertRaises(Exception, signed_copy.validate_signature, None, cert, name='example')
|
||||||
|
@ -357,20 +357,21 @@ class TestDetachedNamedSECP256k1Signatures(UnitTest):
|
||||||
def test_fail_to_validate_with_no_name(self):
|
def test_fail_to_validate_with_no_name(self):
|
||||||
cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
|
cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
|
||||||
self.assertDictEqual(cert.claim_dict, secp256k1_cert)
|
self.assertDictEqual(cert.claim_dict, secp256k1_cert)
|
||||||
signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_2,
|
signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_2, claim_id_1,
|
||||||
claim_id_1, curve=SECP256k1, name='example')
|
curve=SECP256k1, name='example', force_detached=True)
|
||||||
#self.assertDictEqual(signed.claim_dict, claim_010_signed_secp256k1)
|
#self.assertDictEqual(signed.claim_dict, claim_010_signed_secp256k1)
|
||||||
signed_copy = ClaimDict.load_protobuf(signed.protobuf)
|
signed_copy = ClaimDict.load_protobuf(signed.protobuf)
|
||||||
self.assertRaises(Exception, signed_copy.validate_signature, None, cert, name=None)
|
self.assertRaises(Exception, signed_copy.validate_signature, None, cert, name=None)
|
||||||
|
|
||||||
def test_remove_signature_equals_unsigned(self):
|
def test_remove_signature_equals_unsigned(self):
|
||||||
unsigned = ClaimDict.load_dict(example_010)
|
unsigned = ClaimDict.load_dict(example_010)
|
||||||
signed = unsigned.sign(secp256k1_private_key, claim_address_1, claim_id_1, curve=SECP256k1, name='example')
|
signed = unsigned.sign(secp256k1_private_key, claim_address_1, claim_id_1,
|
||||||
|
curve=SECP256k1, name='example', force_detached=True)
|
||||||
self.assertEqual(unsigned.serialized, signed.serialized_no_signature)
|
self.assertEqual(unsigned.serialized, signed.serialized_no_signature)
|
||||||
|
|
||||||
def test_fail_to_validate_fake_ecdsa_signature(self):
|
def test_fail_to_validate_fake_ecdsa_signature(self):
|
||||||
signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_1,
|
signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_1, claim_id_1,
|
||||||
claim_id_1, curve=SECP256k1, name='example')
|
curve=SECP256k1, name='example', force_detached=True)
|
||||||
signed_copy = ClaimDict.deserialize(signed.serialized)
|
signed_copy = ClaimDict.deserialize(signed.serialized)
|
||||||
fake_key = get_signer(SECP256k1).generate().private_key.to_pem()
|
fake_key = get_signer(SECP256k1).generate().private_key.to_pem()
|
||||||
fake_cert = ClaimDict.generate_certificate(fake_key, curve=SECP256k1)
|
fake_cert = ClaimDict.generate_certificate(fake_key, curve=SECP256k1)
|
||||||
|
@ -379,8 +380,8 @@ class TestDetachedNamedSECP256k1Signatures(UnitTest):
|
||||||
|
|
||||||
def test_fail_to_validate_ecdsa_sig_for_altered_claim(self):
|
def test_fail_to_validate_ecdsa_sig_for_altered_claim(self):
|
||||||
cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
|
cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
|
||||||
altered = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_1,
|
altered = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_1, claim_id_1,
|
||||||
claim_id_1, curve=SECP256k1, name='example')
|
curve=SECP256k1, name='example', force_detached=True)
|
||||||
sd_hash = altered['stream']['source']['source']
|
sd_hash = altered['stream']['source']['source']
|
||||||
altered['stream']['source']['source'] = sd_hash[::-1]
|
altered['stream']['source']['source'] = sd_hash[::-1]
|
||||||
altered_copy = ClaimDict.deserialize(altered.serialized)
|
altered_copy = ClaimDict.deserialize(altered.serialized)
|
||||||
|
|
Loading…
Add table
Reference in a new issue