def test_getAuthenticateRequest(self): reqdata = AuthenticateRequestData( authenticateRequests=[{ 'keyHandle': 'a' }, { 'keyHandle': 'b' }]) response = SignResponse(keyHandle='b') self.assertEqual({'keyHandle': 'b'}, reqdata.getAuthenticateRequest(response)) self.assertTrue( isinstance(reqdata.getAuthenticateRequest(response), SignRequest))
def verify_authenticate(device, request, response, valid_facets=None): device = DeviceRegistration.wrap(device) request = SignRequest.wrap(request) response = SignResponse.wrap(response) _validate_client_data(response.clientData, request.challenge, "navigator.id.getAssertion", valid_facets) raw_response = RawAuthenticationResponse(device.appParam, response.clientParam, response.signatureData) raw_response.verify_signature(websafe_decode(device.publicKey)) return raw_response.counter_int, raw_response.user_presence
def getAssertion(self, request, facet="https://www.example.com"): """ signData = { 'version': "U2F_V2", 'challenge': websafe_encode(self.challenge), 'appId': self.binding.app_id, 'keyHandle': websafe_encode(self.binding.key_handle), } """ if not isinstance(request, SignRequest): request = SignRequest(request) if request.version != "U2F_V2": raise ValueError("Unsupported U2F version: %s" % request.version) key_handle = websafe_decode(request.keyHandle) if key_handle not in self.keys: raise ValueError("Unknown key handle!") # Client data client_data = ClientData( typ="navigator.id.getAssertion", challenge=request['challenge'], origin=facet ) client_data = client_data.json.encode('utf-8') client_param = sha_256(client_data) # Unwrap: priv_key, app_param = self.keys[key_handle] # Increment counter self.counter += 1 # Create signature touch = int2byte(1) counter = struct.pack('>I', self.counter) data = app_param + touch + counter + client_param signer = priv_key.signer(ec.ECDSA(hashes.SHA256())) signer.update(data) signature = signer.finalize() raw_response = touch + counter + signature return SignResponse( clientData=websafe_encode(client_data), signatureData=websafe_encode(raw_response), keyHandle=request.keyHandle )
def verify_authenticate(devices, request_data, response, valid_facets=None): request_data = AuthenticateRequestData.wrap(request_data) response = SignResponse.wrap(response) sign_request = request_data.getAuthenticateRequest(response) device = next(d for d in devices if d.keyHandle == sign_request.keyHandle) return u2f_v2.verify_authenticate( device, sign_request, response, valid_facets )
def verify_authenticate(device, request, response, valid_facets=None): device = DeviceRegistration.wrap(device) request = SignRequest.wrap(request) response = SignResponse.wrap(response) _validate_client_data(response.clientData, request.challenge, "navigator.id.getAssertion", valid_facets) raw_response = RawAuthenticationResponse( device.appParam, response.clientParam, response.signatureData ) raw_response.verify_signature(websafe_decode(device.publicKey)) return raw_response.counter_int, raw_response.user_presence
def getAssertion(self, request, facet="https://www.example.com", touch=False): """ signData = { 'version': "U2F_V2", 'challenge': websafe_encode(self.challenge), 'appId': self.binding.app_id, 'keyHandle': websafe_encode(self.binding.key_handle), } """ if not isinstance(request, SignRequest): request = SignRequest(request) if request.version != "U2F_V2": raise ValueError("Unsupported U2F version: %s" % request.version) key_handle = websafe_decode(request.keyHandle) if key_handle not in self.keys: raise ValueError("Unknown key handle!") # Client data client_data = ClientData(typ="navigator.id.getAssertion", challenge=request['challenge'], origin=facet) client_data = client_data.json client_param = H(client_data) # Unwrap: privu, app_param = self.keys[key_handle] # Increment counter self.counter += 1 # Create signature touch = chr(1 if touch else 0) counter = struct.pack('>I', self.counter) digest = H(app_param + touch + counter + client_param) signature = privu.sign_dsa_asn1(digest) raw_response = touch + counter + signature return SignResponse(clientData=websafe_encode(client_data), signatureData=websafe_encode(raw_response), keyHandle=request.keyHandle)
def validate(self, response): """ signResponse = { "clientData": string, //b64 encoded JSON of ClientData "signatureData": string, //b64 encoded raw sign response "challenge": string, //b64 encoded challenge } """ if not isinstance(response, SignResponse): response = SignResponse(response) self._validate_client_data(response.clientData) raw_response = RawAuthenticationResponse( self.app_param, response.clientParam, websafe_decode( response['signatureData'])) raw_response.verify_signature(self.binding.pub_key) return raw_response.counter_int, raw_response.user_presence
def test_signatureData(self): response = SignResponse(signatureData='eyJhIjoxfQ') self.assertEqual('{"a":1}', response.signatureData)
def test_clientParam(self): obj = SignResponse(clientData='eyJhIjoxfQ') self.assertEqual("\x01Z\xbd\x7f\\\xc5z-\xd9Ku\x90\xf0J\xd8\x08" "Bs\x90^\xe3>\xc5\xce\xbe\xaeb'j\x97\xf8b", obj.clientParam)
def test_clientData(self): obj = SignResponse(clientData='eyJhIjoxfQ') self.assertEqual({'a': 1}, obj.clientData) self.assertTrue(isinstance(obj.clientData, ClientData))
def authenticateResponse(self): return SignResponse(self['authenticateResponse'])