diff --git a/.github/scripts/macos-signing/notarize_macos_binary_with_akv.sh b/.github/scripts/macos-signing/notarize_macos_binary_with_akv.sh index 9e053a97b3..90268aa8bf 100755 --- a/.github/scripts/macos-signing/notarize_macos_binary_with_akv.sh +++ b/.github/scripts/macos-signing/notarize_macos_binary_with_akv.sh @@ -70,7 +70,6 @@ done missing_environment=0 for variable_name in \ - APPLE_NOTARIZATION_ISSUER_ID \ APPLE_NOTARIZATION_AKV_KEY_NAME \ AZURE_KEYVAULT_NAME do diff --git a/.github/scripts/macos-signing/notarize_macos_dmg_with_akv.sh b/.github/scripts/macos-signing/notarize_macos_dmg_with_akv.sh index 3433bacc46..79609dbfa8 100755 --- a/.github/scripts/macos-signing/notarize_macos_dmg_with_akv.sh +++ b/.github/scripts/macos-signing/notarize_macos_dmg_with_akv.sh @@ -68,7 +68,6 @@ fi missing_environment=0 for variable_name in \ - APPLE_NOTARIZATION_ISSUER_ID \ APPLE_NOTARIZATION_AKV_KEY_NAME \ AZURE_KEYVAULT_NAME do diff --git a/.github/scripts/macos-signing/notarize_with_akv.py b/.github/scripts/macos-signing/notarize_with_akv.py index ece64dca3f..df4362e570 100644 --- a/.github/scripts/macos-signing/notarize_with_akv.py +++ b/.github/scripts/macos-signing/notarize_with_akv.py @@ -46,7 +46,6 @@ class NotarizationConfiguration: """Load and validate the notarization configuration.""" required = { - "issuer_id": "APPLE_NOTARIZATION_ISSUER_ID", "vault_name": "AZURE_KEYVAULT_NAME", "vault_key_name": "APPLE_NOTARIZATION_AKV_KEY_NAME", } @@ -79,7 +78,8 @@ class NotarizationConfiguration: command.extend( [ "--query", - '{id:key.kid,apple_key_id:tags."apple-key-id"}', + '{id:key.kid,apple_key_id:tags."apple-key-id",' + 'apple_issuer_id:tags."apple-issuer-id"}', "--output", "json", "--only-show-errors", @@ -95,6 +95,7 @@ class NotarizationConfiguration: metadata = json.loads(result.stdout) returned_key_id = metadata["id"] apple_key_id = metadata["apple_key_id"] + apple_issuer_id = metadata["apple_issuer_id"] except (json.JSONDecodeError, KeyError, TypeError) as error: raise NotarizationError("Notarization key metadata is invalid") from error @@ -112,7 +113,16 @@ class NotarizationConfiguration: raise NotarizationError("Unexpected notarization key version") if not isinstance(apple_key_id, str) or not apple_key_id.strip(): raise NotarizationError("Notarization key must have an apple-key-id tag") + if not isinstance(apple_issuer_id, str) or not apple_issuer_id.strip(): + raise NotarizationError("Notarization key must have an apple-issuer-id tag") + if not re.fullmatch( + r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-" + r"[0-9a-fA-F]{4}-[0-9a-fA-F]{12}", + apple_issuer_id.strip(), + ): + raise NotarizationError("Notarization apple-issuer-id tag must contain a valid UUID") + values["issuer_id"] = apple_issuer_id.strip() values["apple_key_id"] = apple_key_id.strip() values["vault_key_version"] = returned_key_version return cls(**values) diff --git a/.github/scripts/macos-signing/test_notarize_with_akv.py b/.github/scripts/macos-signing/test_notarize_with_akv.py index 2a5f0b5457..7f40c6a3eb 100644 --- a/.github/scripts/macos-signing/test_notarize_with_akv.py +++ b/.github/scripts/macos-signing/test_notarize_with_akv.py @@ -15,14 +15,13 @@ sys.path.insert(0, str(SIGNING_DIRECTORY)) import notarize_with_akv as notary # noqa: E402 CONFIGURATION = notary.NotarizationConfiguration( - "issuer-id", + "01234567-89ab-cdef-0123-456789abcdef", "APPLEKEY01", "notary-vault", "example-signing-key", "0123456789abcdef" * 2, ) ENVIRONMENT = { - "APPLE_NOTARIZATION_ISSUER_ID": CONFIGURATION.issuer_id, "AZURE_KEYVAULT_NAME": CONFIGURATION.vault_name, "APPLE_NOTARIZATION_AKV_KEY_NAME": CONFIGURATION.vault_key_name, } @@ -44,8 +43,12 @@ def azure_response(payload): class NotarizationTest(unittest.TestCase): - def test_validates_the_apple_key_tag_and_pins_its_version(self) -> None: - metadata = {"id": CONFIGURATION.versioned_key_id, "apple_key_id": "APPLEKEY01"} + def test_validates_the_apple_key_tags_and_pins_its_version(self) -> None: + metadata = { + "id": CONFIGURATION.versioned_key_id, + "apple_key_id": "APPLEKEY01", + "apple_issuer_id": CONFIGURATION.issuer_id, + } with ( patch.dict(os.environ, ENVIRONMENT, clear=True), patch.object( @@ -61,7 +64,19 @@ class NotarizationTest(unittest.TestCase): show.return_value = azure_response({**metadata, "apple_key_id": None}) with self.assertRaisesRegex(notary.NotarizationError, "apple-key-id tag"): notary.NotarizationConfiguration.from_environment() - self.assertIn('{id:key.kid,apple_key_id:tags."apple-key-id"}', show.call_args.args[0]) + for issuer_id in (None, "", " "): + with self.subTest(issuer_id=issuer_id): + show.return_value = azure_response({**metadata, "apple_issuer_id": issuer_id}) + with self.assertRaisesRegex(notary.NotarizationError, "apple-issuer-id tag"): + notary.NotarizationConfiguration.from_environment() + show.return_value = azure_response({**metadata, "apple_issuer_id": "invalid-issuer"}) + with self.assertRaisesRegex(notary.NotarizationError, "valid UUID"): + notary.NotarizationConfiguration.from_environment() + self.assertIn( + '{id:key.kid,apple_key_id:tags."apple-key-id",' + 'apple_issuer_id:tags."apple-issuer-id"}', + show.call_args.args[0], + ) invalid_environment = {**ENVIRONMENT, "APPLE_NOTARIZATION_AKV_KEY_NAME": "../bad"} with ( @@ -80,6 +95,9 @@ class NotarizationTest(unittest.TestCase): token = notary.create_apple_jwt(CONFIGURATION, issued_at=1_780_000_000) header, claims, encoded_signature = token.split(".") self.assertEqual(json.loads(notary.base64url_decode(header))["kid"], "APPLEKEY01") + self.assertEqual( + json.loads(notary.base64url_decode(claims))["iss"], CONFIGURATION.issuer_id + ) self.assertEqual( json.loads(notary.base64url_decode(claims))["scope"], ["/notary/v2"], diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index 72b6e23895..f6c10f7a09 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -538,7 +538,6 @@ jobs: env: TARGET: ${{ matrix.target }} BINARIES: ${{ matrix.binaries }} - APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }} APPLE_NOTARIZATION_AKV_KEY_NAME: ${{ secrets.AKV_NOTARIZATION_KEY_NAME }} APPLE_NOTARIZATION_AKV_KEY_VERSION: ${{ secrets.AKV_NOTARIZATION_KEY_VERSION }} run: | @@ -589,7 +588,6 @@ jobs: shell: bash env: TARGET: ${{ matrix.target }} - APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }} APPLE_NOTARIZATION_AKV_KEY_NAME: ${{ secrets.AKV_NOTARIZATION_KEY_NAME }} APPLE_NOTARIZATION_AKV_KEY_VERSION: ${{ secrets.AKV_NOTARIZATION_KEY_VERSION }} run: | @@ -923,7 +921,6 @@ jobs: shell: bash env: TARGET: ${{ matrix.target }} - APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }} APPLE_NOTARIZATION_AKV_KEY_NAME: ${{ secrets.AKV_NOTARIZATION_KEY_NAME }} APPLE_NOTARIZATION_AKV_KEY_VERSION: ${{ secrets.AKV_NOTARIZATION_KEY_VERSION }} run: |