Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_RS256_parse_verify(self):
key = CoseKey.parse(cbor.decode(_RS256_KEY))
self.assertIsInstance(key, RS256)
self.assertEqual(
key,
{
1: 3,
3: -257,
-1: a2b_hex(
b"B610DCE84B65029FAE24F7BF8A1730D37BC91435642A628E691E9B030BF3F7CEC59FF91CBE82C54DE16C136FA4FA8A58939B5A950B32E03073592FEC8D8B33601C04F70E5E2D5CF7B4E805E1990EA5A86928A1B390EB9026527933ACC03E6E41DC0BE40AA5EB7B9B460743E4DD80895A758FB3F3F794E5E9B8310D3A60C28F2410D95CF6E732749A243A30475267628B456DE770BC2185BBED1D451ECB0062A3D132C0E4D842E0DDF93A444A3EE33A85C2E913156361713155F1F1DC64E8E68ED176466553BBDE669EB82810B104CB4407D32AE6316C3BD6F382EC3AE2C5FD49304986D64D92ED11C25B6C5CF1287233545A987E9A3E169F99790603DBA5C8AD" # noqa E501
),
-2: a2b_hex(b"010001"),
},
)
key.verify(
a2b_hex(
b"0021F5FC0B85CD22E60623BCD7D1CA48948909249B4776EB515154E57B66AE12010000002E" # noqa E501
+ b"CC9340FD84950987BA667DBE9B2C97C7241E15E2B54869A0DD1CE2013C4064B8"
def test_ES256_parse_verify(self):
key = CoseKey.parse(cbor.decode(_ES256_KEY))
self.assertIsInstance(key, ES256)
self.assertEqual(
key,
{
1: 2,
3: -7,
-1: 1,
-2: a2b_hex(
b"A5FD5CE1B1C458C530A54FA61B31BF6B04BE8B97AFDE54DD8CBB69275A8A1BE1"
),
-3: a2b_hex(
b"FA3A3231DD9DEED9D1897BE5A6228C59501E4BCD12975D3DFF730F01278EA61C"
),
},
)
key.verify(
alg = statement["alg"]
x5c = statement.get("x5c")
cert_info = statement["certInfo"]
if x5c:
cert = x509.load_der_x509_certificate(x5c[0], default_backend())
_validate_attestation_certificate(
cert,
auth_data.credential_data.aaguid,
check_subject=False,
enforce_empty_subject=True,
has_subject_alternative_name=True,
has_aik_certificate=True,
)
pub_key = CoseKey.for_alg(alg).from_cryptography_key(cert.public_key())
else:
pub_key = CoseKey.parse(auth_data.credential_data.public_key)
if pub_key.ALGORITHM != alg:
raise InvalidData("Wrong algorithm of public key!")
try:
pub_area = TpmPublicFormat.parse(statement["pubArea"])
except Exception as e:
raise InvalidData("unable to parse pubArea", e)
# Verify that the public key specified by the parameters and unique
# fields of pubArea is identical to the credentialPublicKey in the
# attestedCredentialData in authenticatorData.
if (
auth_data.credential_data.public_key.from_cryptography_key(
pub_area.public_key()
def for_name(name):
"""Get a subclass of CoseKey corresponding to an algorithm identifier.
:param alg: The COSE identifier of the algorithm.
:return: A CoseKey.
"""
for cls in CoseKey.__subclasses__():
if cls.__name__ == name:
return cls
return UnsupportedKey
def parse(cose):
"""Create a CoseKey from a dict"""
alg = cose.get(3)
if not alg:
raise ValueError("COSE alg identifier must be provided.")
return CoseKey.for_alg(alg)(cose)
alg = cose.get(3)
if not alg:
raise ValueError("COSE alg identifier must be provided.")
return CoseKey.for_alg(alg)(cose)
@staticmethod
def supported_algorithms():
"""Get a list of all supported algorithm identifiers"""
if ed25519:
algs = (ES256, EdDSA, PS256, RS256)
else:
algs = (ES256, PS256, RS256)
return [cls.ALGORITHM for cls in algs]
class UnsupportedKey(CoseKey):
"""A COSE key with an unsupported algorithm."""
class ES256(CoseKey):
ALGORITHM = -7
_HASH_ALG = hashes.SHA256()
def verify(self, message, signature):
if self[-1] != 1:
raise ValueError("Unsupported elliptic curve")
ec.EllipticCurvePublicNumbers(
bytes2int(self[-2]), bytes2int(self[-3]), ec.SECP256R1()
).public_key(default_backend()).verify(
signature, message, ec.ECDSA(self._HASH_ALG)
)
def parse(data):
"""Parse the components of an AttestedCredentialData from a binary
string, and return them.
:param data: A binary string containing an attested credential data.
:return: AAGUID, credential ID, public key, and remaining data.
"""
reader = ByteBuffer(data)
aaguid = reader.read(16)
cred_id = reader.read(reader.unpack(">H"))
pub_key, rest = cbor.decode_from(reader.read())
return aaguid, cred_id, CoseKey.parse(pub_key), rest
class RS256(CoseKey):
ALGORITHM = -257
_HASH_ALG = hashes.SHA256()
def verify(self, message, signature):
rsa.RSAPublicNumbers(bytes2int(self[-2]), bytes2int(self[-1])).public_key(
default_backend()
).verify(signature, message, padding.PKCS1v15(), self._HASH_ALG)
@classmethod
def from_cryptography_key(cls, public_key):
pn = public_key.public_numbers()
return cls({1: 3, 3: cls.ALGORITHM, -1: int2bytes(pn.n), -2: int2bytes(pn.e)})
class PS256(CoseKey):
ALGORITHM = -37
_HASH_ALG = hashes.SHA256()
def verify(self, message, signature):
rsa.RSAPublicNumbers(bytes2int(self[-2]), bytes2int(self[-1])).public_key(
default_backend()
).verify(
signature,
message,
padding.PSS(
mgf=padding.MGF1(self._HASH_ALG), salt_length=padding.PSS.MAX_LENGTH
),
self._HASH_ALG,
)
@classmethod
-2: int2bytes(pn.x, 32),
-3: int2bytes(pn.y, 32),
}
)
@classmethod
def from_ctap1(cls, data):
"""Creates an ES256 key from a CTAP1 formatted public key byte string.
:param data: A 65 byte SECP256R1 public key.
:return: A ES256 key.
"""
return cls({1: 2, 3: cls.ALGORITHM, -1: 1, -2: data[1:33], -3: data[33:65]})
class RS256(CoseKey):
ALGORITHM = -257
_HASH_ALG = hashes.SHA256()
def verify(self, message, signature):
rsa.RSAPublicNumbers(bytes2int(self[-2]), bytes2int(self[-1])).public_key(
default_backend()
).verify(signature, message, padding.PKCS1v15(), self._HASH_ALG)
@classmethod
def from_cryptography_key(cls, public_key):
pn = public_key.public_numbers()
return cls({1: 3, 3: cls.ALGORITHM, -1: int2bytes(pn.n), -2: int2bytes(pn.e)})
class PS256(CoseKey):
ALGORITHM = -37
def __init__(
self, rp, attestation=None, verify_origin=None, attestation_types=None
):
self.rp = PublicKeyCredentialRpEntity._wrap(rp)
self._verify = verify_origin or _verify_origin_for_rp(self.rp.id)
self.timeout = None
self.attestation = AttestationConveyancePreference._wrap(attestation)
self.allowed_algorithms = [
PublicKeyCredentialParameters("public-key", alg)
for alg in CoseKey.supported_algorithms()
]
self._attestation_types = attestation_types or _default_attestations()