def recipe_signatures_are_correct(app_configs, **kwargs): errors = [] try: Recipe = apps.get_model("recipes", "Recipe") # pre-fetch signatures, to avoid race condition with deleted signatures signed_recipes = list( Recipe.objects.exclude(signature=None).select_related("signature")) except (ProgrammingError, OperationalError, ImproperlyConfigured) as e: errors.append( Info(f"Could not retrieve recipes: {e}", id=INFO_COULD_NOT_RETRIEVE_RECIPES)) return errors try: for recipe in signed_recipes: data = recipe.canonical_json() signature = recipe.signature.signature pubkey = recipe.signature.public_key try: signing.verify_signature(data, signature, pubkey) except signing.BadSignature as e: msg = "Recipe '{recipe}' (id={recipe.id}) has a bad signature: {detail}".format( recipe=recipe, detail=e.detail) errors.append(Error(msg, id=ERROR_INVALID_RECIPE_SIGNATURE)) except (ProgrammingError, OperationalError, ImproperlyConfigured) as e: errors.append( Warning(f"Could not check signatures: {e}", id=WARNING_COULD_NOT_CHECK_SIGNATURES)) return errors
def action_signatures_are_correct(app_configs, **kwargs): errors = [] try: Action = apps.get_model("recipes", "Action") # pre-fetch signatures, to avoid race condition with deleted signatures signed_actions = list( Action.objects.exclude(signature=None).select_related("signature")) except (ProgrammingError, OperationalError, ImproperlyConfigured) as e: msg = f"Could not retrieve actions: f{e}" errors.append(Info(msg, id=INFO_COULD_NOT_RETRIEVE_ACTIONS)) return errors try: for action in signed_actions: data = action.canonical_json() signature = action.signature.signature pubkey = action.signature.public_key try: signing.verify_signature(data, signature, pubkey) except signing.BadSignature as e: msg = f"Action '{action}' (id={action.id}) has a bad signature: {e.detail}" errors.append(Error(msg, id=ERROR_INVALID_ACTION_SIGNATURE)) except (ProgrammingError, OperationalError, ImproperlyConfigured) as e: errors.append( Warning(f"Could not check signatures: {e}", id=WARNING_COULD_NOT_CHECK_SIGNATURES)) return errors
def recipe_signatures_are_correct(app_configs, **kwargs): errors = [] try: Recipe = apps.get_model('recipes', 'Recipe') signed_recipes = list(Recipe.objects.exclude(signature=None)) except (ProgrammingError, OperationalError, ImproperlyConfigured): errors.append(Info('Could not retrieve recipes', id=INFO_COULD_NOT_RETRIEVE_RECIPES)) else: for recipe in signed_recipes: data = recipe.canonical_json() signature = recipe.signature.signature pubkey = recipe.signature.public_key try: signing.verify_signature(data, signature, pubkey) except signing.BadSignature as e: msg = ("Recipe '{recipe}' (id={recipe.id}) has a bad signature: {detail}" .format(recipe=recipe, detail=e.detail)) errors.append(Warning(msg, id=WARNING_INVALID_RECIPE_SIGNATURE)) return errors
def action_signatures_are_correct(app_configs, **kwargs): errors = [] try: Action = apps.get_model('recipes', 'Action') signed_actions = list(Action.objects.exclude(signature=None)) except (ProgrammingError, OperationalError, ImproperlyConfigured) as e: msg = f'Could not retrieve actions: f{e}' errors.append(Info(msg, id=INFO_COULD_NOT_RETRIEVE_ACTIONS)) else: for action in signed_actions: data = action.canonical_json() signature = action.signature.signature pubkey = action.signature.public_key try: signing.verify_signature(data, signature, pubkey) except signing.BadSignature as e: msg = f"Action '{action}' (id={action.id}) has a bad signature: {e.detail}" errors.append(Warning(msg, id=WARNING_INVALID_ACTION_SIGNATURE)) return errors
def action_signatures_are_correct(app_configs, **kwargs): errors = [] try: Action = apps.get_model("recipes", "Action") # pre-fetch signatures, to avoid race condition with deleted signatures signed_actions = list(Action.objects.exclude(signature=None).select_related("signature")) except (ProgrammingError, OperationalError, ImproperlyConfigured) as e: msg = f"Could not retrieve actions: f{e}" errors.append(Info(msg, id=INFO_COULD_NOT_RETRIEVE_ACTIONS)) else: for action in signed_actions: data = action.canonical_json() signature = action.signature.signature pubkey = action.signature.public_key try: signing.verify_signature(data, signature, pubkey) except signing.BadSignature as e: msg = f"Action '{action}' (id={action.id}) has a bad signature: {e.detail}" errors.append(Error(msg, id=ERROR_INVALID_ACTION_SIGNATURE)) return errors
def recipe_signatures_are_correct(app_configs, **kwargs): errors = [] try: Recipe = apps.get_model("recipes", "Recipe") # pre-fetch signatures, to avoid race condition with deleted signatures signed_recipes = list(Recipe.objects.exclude(signature=None).select_related("signature")) except (ProgrammingError, OperationalError, ImproperlyConfigured) as e: errors.append(Info(f"Could not retrieve recipes: {e}", id=INFO_COULD_NOT_RETRIEVE_RECIPES)) else: for recipe in signed_recipes: data = recipe.canonical_json() signature = recipe.signature.signature pubkey = recipe.signature.public_key try: signing.verify_signature(data, signature, pubkey) except signing.BadSignature as e: msg = "Recipe '{recipe}' (id={recipe.id}) has a bad signature: {detail}".format( recipe=recipe, detail=e.detail ) errors.append(Error(msg, id=ERROR_INVALID_RECIPE_SIGNATURE)) return errors
def test_recipe_signatures(conf, requests_session): r = requests_session.get(conf.getoption("server") + "/api/v1/recipe/signed/") r.raise_for_status() data = r.json() if len(data) == 0: pytest.skip("No signed recipes") cert_urls = set() for item in data: canonical_recipe = canonical_json(item["recipe"]) signature = item["signature"]["signature"] pubkey = item["signature"]["public_key"] cert_urls.add(item["signature"]["x5u"]) assert signing.verify_signature(canonical_recipe, signature, pubkey) for url in cert_urls: signing.verify_x5u(url)
def test_action_signatures(conf, requests_session): r = requests_session.get(conf.getoption("server") + "/api/v1/action/signed/") r.raise_for_status() data = r.json() if len(data) == 0: pytest.skip("No signed actions") cert_urls = set() for item in data: canonical_action = canonical_json(item["action"]) signature = item["signature"]["signature"] pubkey = item["signature"]["public_key"] cert_urls.add(item["signature"]["x5u"]) assert signing.verify_signature(canonical_action, signature, pubkey) for url in cert_urls: signing.verify_x5u(url)
def test_recipe_signatures(conf, requests_session): r = requests_session.get( conf.getoption('server') + '/api/v1/recipe/signed/') r.raise_for_status() data = r.json() if len(data) == 0: pytest.skip('No signed recipes') cert_urls = set() for item in data: canonical_recipe = canonical_json(item['recipe']) signature = item['signature']['signature'] pubkey = item['signature']['public_key'] cert_urls.add(item['signature']['x5u']) assert signing.verify_signature(canonical_recipe, signature, pubkey) for url in cert_urls: signing.verify_x5u(url)
def test_raises_nice_error_for_too_short_signatures_bad_padding(self): signature = 'a_too_short_signature' with pytest.raises(signing.WrongSignatureSize): signing.verify_signature(self.data, signature, self.pubkey)
def test_known_good_signature(self): assert signing.verify_signature(self.data, self.signature, self.pubkey)
def test_raises_nice_error_for_too_short_signatures_bad_padding(self): signature = "a_too_short_signature" with pytest.raises(signing.WrongSignatureSize): signing.verify_signature(self.data, signature, self.pubkey)
def test_raises_nice_error_for_wrong_signature(self): # change the signature, but keep it a valid signature signature = self.signature.replace("s", "S") with pytest.raises(signing.SignatureDoesNotMatch): signing.verify_signature(self.data, signature, self.pubkey)
def test_raises_nice_error_for_too_short_signatures_good_base64(self): signature = "aa==" with pytest.raises(signing.WrongSignatureSize): signing.verify_signature(self.data, signature, self.pubkey)
def test_raises_nice_error_for_too_short_signatures_good_base64(self): signature = 'aa==' with pytest.raises(signing.WrongSignatureSize): signing.verify_signature(self.data, signature, self.pubkey)
def test_raises_nice_error_for_wrong_signature(self): # change the signature, but keep it a valid signature signature = self.signature.replace('s', 'S') with pytest.raises(signing.SignatureDoesNotMatch): signing.verify_signature(self.data, signature, self.pubkey)
def test_known_good_signature(self): assert signing.verify_signature(self.data, self.signature, self.pubkey)