Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def verify(self, statement, auth_data, client_data_hash):
jwt = statement["response"]
header, payload, sig = (websafe_decode(x) for x in jwt.split(b"."))
data = json.loads(payload.decode("utf8"))
if not self.allow_rooted and data["ctsProfileMatch"] is not True:
raise InvalidData("ctsProfileMatch must be true!")
expected_nonce = sha256(auth_data + client_data_hash)
if not bytes_eq(expected_nonce, websafe_decode(data["nonce"])):
raise InvalidData("Nonce does not match!")
data = json.loads(header.decode("utf8"))
certs = [
x509.load_der_x509_certificate(websafe_decode(x), default_backend())
for x in data["x5c"]
]
certs.append(self._ca)
cert = certs.pop(0)
cn = cert.subject.get_attributes_for_oid(x509.NameOID.COMMON_NAME)
if cn[0].value != "attest.android.com":
raise InvalidData("Certificate not issued to attest.android.com!")
CoseKey.for_name(data["alg"]).from_cryptography_key(cert.public_key()).verify(
event.wait = mock.MagicMock()
resp = client.sign(
APP_ID,
"challenge",
[{"version": "U2F_V2", "keyHandle": "a2V5"}],
event=event,
)
event.wait.assert_called()
client.ctap.get_version.assert_called_with()
client.ctap.authenticate.assert_called()
client_param, app_param, key_handle = client.ctap.authenticate.call_args[0]
self.assertEqual(client_param, sha256(websafe_decode(resp["clientData"])))
self.assertEqual(app_param, sha256(APP_ID.encode()))
self.assertEqual(key_handle, b"key")
self.assertEqual(websafe_decode(resp["signatureData"]), SIG_DATA)
def test_sign(self):
client = U2fClient(None, APP_ID)
client.ctap = mock.MagicMock()
client.ctap.get_version.return_value = "U2F_V2"
client.ctap.authenticate.return_value = SIG_DATA
resp = client.sign(
APP_ID, "challenge", [{"version": "U2F_V2", "keyHandle": "a2V5"}]
)
client.ctap.get_version.assert_called_with()
client.ctap.authenticate.assert_called_once()
client_param, app_param, key_handle = client.ctap.authenticate.call_args[0]
self.assertEqual(client_param, sha256(websafe_decode(resp["clientData"])))
self.assertEqual(app_param, sha256(APP_ID.encode()))
self.assertEqual(key_handle, b"key")
self.assertEqual(websafe_decode(resp["signatureData"]), SIG_DATA)
resp = client.sign(
APP_ID,
"challenge",
[{"version": "U2F_V2", "keyHandle": "a2V5"}],
event=event,
)
event.wait.assert_called()
client.ctap.get_version.assert_called_with()
client.ctap.authenticate.assert_called()
client_param, app_param, key_handle = client.ctap.authenticate.call_args[0]
self.assertEqual(client_param, sha256(websafe_decode(resp["clientData"])))
self.assertEqual(app_param, sha256(APP_ID.encode()))
self.assertEqual(key_handle, b"key")
self.assertEqual(websafe_decode(resp["signatureData"]), SIG_DATA)
from fido2.pcsc import CtapPcscDevice
from fido2.utils import sha256
from fido2.ctap1 import CTAP1
import sys
dev = next(CtapPcscDevice.list_devices(), None)
if not dev:
print("No NFC u2f device found")
sys.exit(1)
chal = sha256(b"AAA")
appid = sha256(b"BBB")
ctap1 = CTAP1(dev)
print("version:", ctap1.get_version())
# True - make extended APDU and send it to key
# ISO 7816-3:2006. page 33, 12.1.3 Decoding conventions for command APDUs
# ISO 7816-3:2006. page 34, 12.2 Command-response pair transmission by T=0
# False - make group of short (less than 255 bytes length) APDU
# and send them to key. ISO 7816-3:2005, page 9, 5.1.1.1 Command chaining
dev.use_ext_apdu = False
reg = ctap1.register(chal, appid)
print("register:", reg)
dev = next(Acr122uSamPcscDevice.list_devices())
print("CONNECT: %s" % dev)
print("version: %s" % dev.reader_version())
print("atr: %s" % bytes(dev.get_atr()).hex())
print("ats: %s" % dev.ats.hex())
# uncomment if you want to see parameters from card's selection
# dev.get_ats(True)
# dev._select()
dev.led_control(False, True, 0)
chal = sha256(b"AAA")
appid = sha256(b"BBB")
ctap1 = CTAP1(dev)
print("ctap1 version:", ctap1.get_version())
reg = ctap1.register(chal, appid)
print("u2f register:", reg)
reg.verify(appid, chal)
print("Register message verify OK")
auth = ctap1.authenticate(chal, appid, reg.key_handle)
print("u2f authenticate: ", auth)
res = auth.verify(appid, chal, reg.public_key)
print("Authenticate message verify OK")
dev.led_control()
:param credentialid: credentialid
"""
self.ui = ui
self._clients = None
self._has_prompted = False
self._cancel = Event()
self._credentialId = base64.urlsafe_b64decode(credentialId)
self._appId = sha256(appId.encode())
self._version = 'U2F_V2'
self._signature = None
self._clientData = json.dumps({
"challenge": nonce,
"origin": appId,
"typ": "navigator.id.getAssertion"
}).encode()
self._nonce = sha256(self._clientData)
if e.code == APDU.USE_NOT_SATISFIED:
raise ClientError.ERR.DEVICE_INELIGIBLE()
except CtapError as e:
raise _ctap2client_err(e)
for request in register_requests:
if request["version"] == version:
challenge = request["challenge"]
break
else:
raise ClientError.ERR.DEVICE_INELIGIBLE()
client_data = ClientData.build(
typ=U2F_TYPE.REGISTER, challenge=challenge, origin=self.origin
)
app_param = sha256(app_id.encode())
reg_data = _call_polling(
self.poll_delay,
event,
on_keepalive,
self.ctap.register,
client_data.hash,
app_param,
)
return {"registrationData": reg_data.b64, "clientData": client_data.b64}
def hash(self):
return sha256(self)
def __init__(self, ui, appId, nonce, credentialId):
"""
:param appId: Base URL string for Okta IDP e.g. https://xxxx.okta.com'
:param nonce: nonce
:param credentialid: credentialid
"""
self.ui = ui
self._clients = None
self._has_prompted = False
self._cancel = Event()
self._credentialId = base64.urlsafe_b64decode(credentialId)
self._appId = sha256(appId.encode())
self._version = 'U2F_V2'
self._signature = None
self._clientData = json.dumps({
"challenge": nonce,
"origin": appId,
"typ": "navigator.id.getAssertion"
}).encode()
self._nonce = sha256(self._clientData)