def testGetHacked(self, promiscuous_client): seed = libnacl.randombytes(libnacl.crypto_sign_SEEDBYTES) vk, sk, did, body = eddsa.genDidHistory(seed, signer=0, numSigners=2, method="fake") vk = h.bytesToStr64u(vk) signature = eddsa.signResource(body, sk) headers = {"Signature": 'signer="{0}"'.format(signature)} response = promiscuous_client.simulate_post(HISTORY_BASE_PATH, body=body, headers=headers) assert response.status == falcon.HTTP_201 seed = libnacl.randombytes(libnacl.crypto_sign_SEEDBYTES) vk2, sk2, did2, body2 = eddsa.genDidHistory(seed, signer=0, numSigners=2) vk2 = h.bytesToStr64u(vk2) body2 = json.loads(body2) body2["id"] = did body2 = json.dumps(body2).encode() signature2 = eddsa.signResource(body2, sk2) headers2 = {"Signature": 'signer="{0}"'.format(signature2)} response = promiscuous_client.simulate_post(HISTORY_BASE_PATH, body=body2, headers=headers2) assert response.status == falcon.HTTP_201 response = promiscuous_client.simulate_get("{}/{}".format( EVENTS_BASE_PATH, did)) exp_result = [ [{ "event": json.loads(body2.decode()), "signatures": { "signer": signature2 } }], [{ "event": json.loads(body.decode()), "signatures": { "signer": signature } }], ] assert response.status == falcon.HTTP_200 assert json.loads(response.content) == exp_result
def testGetAll(self, race_client): seed = libnacl.randombytes(libnacl.crypto_sign_SEEDBYTES) vk, sk, did, body = eddsa.genDidHistory(seed, signer=0, numSigners=2) vk = h.bytesToStr64u(vk) signature = eddsa.signResource(body, sk) headers = {"Signature": 'signer="{0}"'.format(signature)} race_client.simulate_post(HISTORY_BASE_PATH, body=body, headers=headers) seed = libnacl.randombytes(libnacl.crypto_sign_SEEDBYTES) vk2, sk2, did2, body2 = eddsa.genDidHistory(seed, signer=0, numSigners=2) vk2 = h.bytesToStr64u(vk2) signature2 = eddsa.signResource(body2, sk2) headers2 = {"Signature": 'signer="{0}"'.format(signature2)} race_client.simulate_post(HISTORY_BASE_PATH, body=body2, headers=headers2) response = race_client.simulate_get(EVENTS_BASE_PATH) exp_result = { "data": [[[{ "event": json.loads(body.decode()), "signatures": { "signer": signature } }]], [[{ "event": json.loads(body2.decode()), "signatures": { "signer": signature2 } }]]] } response_data = json.loads(response.content) assert response.status == falcon.HTTP_200 assert len(response_data["data"]) == 2 # response_data order is unreliable # make sure that each history exists only once in response for result in exp_result['data']: matches = 0 for data in response_data['data']: if data == result: matches += 1 assert matches == 1
def testGet(self, race_client): seed = libnacl.randombytes(libnacl.crypto_sign_SEEDBYTES) vk, sk, did, body = eddsa.genDidHistory(seed, signer=0, numSigners=2) vk = h.bytesToStr64u(vk) signature = eddsa.signResource(body, sk) headers = {"Signature": 'signer="{0}"'.format(signature)} race_client.simulate_post(HISTORY_BASE_PATH, body=body, headers=headers) response = race_client.simulate_get("{}/{}".format( EVENTS_BASE_PATH, did)) exp_result = [[{ "event": json.loads(body.decode()), "signatures": { "signer": signature } }]] assert response.status == falcon.HTTP_200 assert json.loads(response.content) == exp_result
def testPutUnchangedSignerField(client): # send updated history with new public key but unchanged signer field seed = libnacl.randombytes(libnacl.crypto_sign_SEEDBYTES) vk, sk, did, body = eddsa.genDidHistory(seed, signer=0, numSigners=2) vk = h.bytesToStr64u(vk) headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format(eddsa.signResource(body, sk), eddsa.signResource(body, sk)) } # send inception event client.simulate_post(HISTORY_BASE_PATH, body=body, headers=headers) # Add did to database body = json.loads(body) body['changed'] = "2000-01-01T00:00:02+00:00" body['signer'] = 1 body['signers'].append(vk) headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format( eddsa.signResource( json.dumps(body, ensure_ascii=False).encode(), sk), eddsa.signResource( json.dumps(body, ensure_ascii=False).encode(), sk)) } # rotate once client.simulate_put("{0}/{1}".format(HISTORY_BASE_PATH, did), body=json.dumps(body).encode(), headers=headers) # Add new pre-rotated key but don't update signer field body['signers'].append(vk) body['changed'] = "2000-01-01T00:00:03+00:00" headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format( eddsa.signResource( json.dumps(body, ensure_ascii=False).encode(), sk), eddsa.signResource( json.dumps(body, ensure_ascii=False).encode(), sk)) } exp_result = { "title": "Validation Error", "description": "signer field must be one greater than previous." } verifyRequest(client.simulate_put, "{0}/{1}".format(HISTORY_BASE_PATH, did), body, headers, exp_result=exp_result, exp_status=falcon.HTTP_400)
def testHackerRevocation(client): # Make sure that a hacker can't revoke someone elses keys. seed = libnacl.randombytes(libnacl.crypto_sign_SEEDBYTES) vk, sk, did, body = eddsa.genDidHistory(seed, signer=0, numSigners=2) vk = h.bytesToStr64u(vk) headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format(eddsa.signResource(body, sk), eddsa.signResource(body, sk)) } # send inception event client.simulate_post(HISTORY_BASE_PATH, body=body, headers=headers) # Add did to database seed = libnacl.randombytes(libnacl.crypto_sign_SEEDBYTES) hacked_vk, hacked_sk = eddsa.generateByteKeys(seed) hacked_vk = h.bytesToStr64u(hacked_vk) body = json.loads(body) body['changed'] = "2000-01-01T00:00:02+00:00" body['signer'] = 5 body['signers'].append(hacked_vk) body['signers'].append(hacked_vk) body['signers'].append(hacked_vk) body['signers'].append(None) headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format( eddsa.signResource( json.dumps(body, ensure_ascii=False).encode(), hacked_sk), eddsa.signResource( json.dumps(body, ensure_ascii=False).encode(), hacked_sk)) } exp_result = { "title": "Authorization Error", "description": "Could not validate the request signature for rotation field. Unverifiable signature." } verifyRequest(client.simulate_put, "{0}/{1}".format(HISTORY_BASE_PATH, did), body, headers, exp_result=exp_result, exp_status=falcon.HTTP_401)
def testPutChangeVerifiedKeys(client): # Test that previously verified keys have not been changed seed = b'\x03\xa7w\xa6\x8c\xf3-&\xbf)\xdf\tk\xb5l\xc0-ry\x9bq\xecC\xbd\x1e\xe7\xdd\xe8\xad\x80\x95\x89' vk, sk, did, body = eddsa.genDidHistory(seed, signer=0, numSigners=4) headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format(eddsa.signResource(body, sk), eddsa.signResource(body, sk)) } client.simulate_post(HISTORY_BASE_PATH, body=body, headers=headers) # Add did to database body = json.loads(body) body['signer'] = 1 body['changed'] = "2000-01-01T00:00:01+00:00" del body['signers'][3] body['signers'].append("Xq5YqaL6L48pf0fu7IUhL0JRaU2_RxFP0AL43wYn148=") body['signers'].append("Xq5YqaL6L48pf0fu7IUhL0JRaU2_RxFP0AL43wYn148=") headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format( eddsa.signResource( json.dumps(body, ensure_ascii=False).encode('utf-8'), sk), eddsa.signResource( json.dumps(body, ensure_ascii=False).encode('utf-8'), sk)) } exp_result = { "title": "Validation Error", "description": "signers field missing previously verified keys." } verifyRequest(client.simulate_put, "{0}/{1}".format(HISTORY_BASE_PATH, did), body, headers, exp_result=exp_result, exp_status=falcon.HTTP_400)
def testPutSignerFieldMissingKeys(client): seed = b'\x03\xa7w\xa6\x8c\xf3-&\xbf)\xdf\tk\xb5l\xc0-ry\x9bq\xecC\xbd\x1e\xe7\xdd\xe8\xad\x80\x95\x89' vk, sk, did, body = eddsa.genDidHistory(seed, signer=0, numSigners=4) headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format(eddsa.signResource(body, sk), eddsa.signResource(body, sk)) } client.simulate_post(HISTORY_BASE_PATH, body=body, headers=headers) # Add did to database body = json.loads(body) body['signer'] = 1 body['changed'] = "2000-01-01T00:00:01+00:00" del body['signers'][3] headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format( eddsa.signResource( json.dumps(body, ensure_ascii=False).encode('utf-8'), sk), eddsa.signResource( json.dumps(body, ensure_ascii=False).encode('utf-8'), sk)) } exp_result = { "title": "Validation Error", "description": "signers field is missing keys." } verifyRequest(client.simulate_put, "{0}/{1}".format(HISTORY_BASE_PATH, did), body, headers, exp_result=exp_result, exp_status=falcon.HTTP_400)
def testPutChangedFieldMustUpdate(client): # Test that changed field is greater than previous date seed = b'\x03\xa7w\xa6\x8c\xf3-&\xbf)\xdf\tk\xb5l\xc0-ry\x9bq\xecC\xbd\x1e\xe7\xdd\xe8\xad\x80\x95\x89' vk, sk, did, body = eddsa.genDidHistory(seed, signer=0, numSigners=4) headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format(eddsa.signResource(body, sk), eddsa.signResource(body, sk)) } client.simulate_post(HISTORY_BASE_PATH, body=body, headers=headers) # Add did to database body = json.loads(body) body['signer'] = 1 headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format( eddsa.signResource( json.dumps(body, ensure_ascii=False).encode('utf-8'), sk), eddsa.signResource( json.dumps(body, ensure_ascii=False).encode('utf-8'), sk)) } exp_result = { "title": "Validation Error", "description": "\"changed\" field not later than previous update." } verifyRequest(client.simulate_put, "{0}/{1}".format(HISTORY_BASE_PATH, did), body, headers, exp_result=exp_result, exp_status=falcon.HTTP_400)
def testGetAllMultiEvent(self, race_client): seed = libnacl.randombytes(libnacl.crypto_sign_SEEDBYTES) vk, sk, did, body = eddsa.genDidHistory(seed, signer=0, numSigners=2) vk = h.bytesToStr64u(vk) signature = eddsa.signResource(body, sk) headers = {"Signature": 'signer="{0}"'.format(signature)} race_client.simulate_post(HISTORY_BASE_PATH, body=body, headers=headers) body2 = json.loads(body) body2['changed'] = "2000-01-01T00:00:01+00:00" body2['signer'] = 1 body2['signers'].append(vk) body2 = json.dumps(body2).encode() signer = eddsa.signResource(body2, sk) rotation = eddsa.signResource(body2, sk) headers = { "Signature": 'signer="{0}"; rotation="{1}"'.format(signer, rotation) } response = race_client.simulate_put("{}/{}".format( HISTORY_BASE_PATH, did), body=body2, headers=headers) assert response.status == falcon.HTTP_200 seed = libnacl.randombytes(libnacl.crypto_sign_SEEDBYTES) vk3, sk3, did3, body3 = eddsa.genDidHistory(seed, signer=0, numSigners=2) vk3 = h.bytesToStr64u(vk3) signature3 = eddsa.signResource(body3, sk3) headers3 = {"Signature": 'signer="{0}"'.format(signature3)} race_client.simulate_post(HISTORY_BASE_PATH, body=body3, headers=headers3) response = race_client.simulate_get(EVENTS_BASE_PATH) exp_result = { "data": [[[{ "event": json.loads(body2.decode()), "signatures": { "signer": signer, "rotation": rotation } }, { "event": json.loads(body.decode()), "signatures": { "signer": signature } }]], [[{ "event": json.loads(body3.decode()), "signatures": { "signer": signature3 } }]]] } response_data = json.loads(response.content) assert response.status == falcon.HTTP_200 assert len(response_data["data"]) == 2 # response_data order is unreliable # make sure that each history exists only once in response for result in exp_result['data']: matches = 0 for data in response_data['data']: if data == result: matches += 1 assert matches == 1
def testGenDidHistoryChanged(): changed = "2018-12-01T00:00:00+00:00" vk, sk, did, body = eddsa.genDidHistory(changed=changed) assert json.loads(body.decode())['changed'] == changed
def testGenDidHistorySigner(): signer = 1 vk, sk, did, body = eddsa.genDidHistory(signer=signer) assert json.loads(body.decode())['signer'] == signer
def testGenDidHistoryNumSigners(): numSigners = 2 vk, sk, did, body = eddsa.genDidHistory(numSigners=numSigners) assert len(json.loads(body.decode())['signers']) == numSigners