34
34
KEY_LEN = 32
35
35
36
36
37
+ class _InvalidPublicKey (Exception ):
38
+ """
39
+ A custom exception raised when trying to convert bytes
40
+ into an elliptic curve public key.
41
+ """
42
+ pass
43
+
44
+
37
45
def generate_privkey () -> datatypes .PrivateKey :
38
46
"""Generate a new SECP256K1 private key and return it"""
39
47
privkey = ec .generate_private_key (CURVE , default_backend ())
@@ -45,8 +53,15 @@ def ecdh_agree(privkey: datatypes.PrivateKey, pubkey: datatypes.PublicKey) -> by
45
53
privkey_as_int = int (cast (int , privkey ))
46
54
ec_privkey = ec .derive_private_key (privkey_as_int , CURVE , default_backend ())
47
55
pubkey_bytes = b'\x04 ' + pubkey .to_bytes ()
48
- pubkey_nums = ec .EllipticCurvePublicNumbers .from_encoded_point (CURVE , pubkey_bytes )
49
- ec_pubkey = pubkey_nums .public_key (default_backend ())
56
+ try :
57
+ # either of these can raise a ValueError:
58
+ pubkey_nums = ec .EllipticCurvePublicNumbers .from_encoded_point (CURVE , pubkey_bytes )
59
+ ec_pubkey = pubkey_nums .public_key (default_backend ())
60
+ except ValueError as exc :
61
+ # Not all bytes can be made into valid public keys, see the warning at
62
+ # https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/
63
+ # under EllipticCurvePublicNumbers(x, y)
64
+ raise _InvalidPublicKey (str (exc )) from exc
50
65
return ec_privkey .exchange (ec .ECDH (), ec_pubkey )
51
66
52
67
@@ -100,7 +115,12 @@ def decrypt(data: bytes, privkey: datatypes.PrivateKey, shared_mac_data: bytes =
100
115
101
116
# 1) generate shared-secret = kdf( ecdhAgree(myPrivKey, msg[1:65]) )
102
117
shared = data [1 :1 + PUBKEY_LEN ]
103
- key_material = ecdh_agree (privkey , keys .PublicKey (shared ))
118
+ try :
119
+ key_material = ecdh_agree (privkey , keys .PublicKey (shared ))
120
+ except _InvalidPublicKey as exc :
121
+ raise DecryptionError (
122
+ f"Failed to generate shared secret with pubkey { shared } : { exc } "
123
+ ) from exc
104
124
key = kdf (key_material )
105
125
key_enc , key_mac = key [:KEY_LEN // 2 ], key [KEY_LEN // 2 :]
106
126
key_mac = sha256 (key_mac ).digest ()
0 commit comments