├── .cargo └── config.toml ├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ ├── rcodesign.yml │ ├── sign-apple-exe.yml │ ├── sphinx.yml │ └── workspace.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── Cargo.lock ├── Cargo.toml ├── Justfile ├── README.md ├── apfs-derive ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ └── lib.rs ├── apfs-types ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── btree.rs │ ├── common.rs │ ├── container.rs │ ├── data_stream.rs │ ├── efi_jumpstart.rs │ ├── encryption.rs │ ├── encryption_rolling.rs │ ├── filesystem.rs │ ├── filesystem_extended_fields.rs │ ├── fusion.rs │ ├── lib.rs │ ├── object.rs │ ├── object_map.rs │ ├── pod.rs │ ├── reaper.rs │ ├── sealed_volume.rs │ ├── sibling.rs │ ├── snapshot.rs │ ├── space_manager.rs │ └── volume.rs ├── app-store-connect ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── api_key.rs │ ├── api_token.rs │ ├── bundle_api.rs │ ├── certs_api.rs │ ├── cli.rs │ ├── device_api.rs │ ├── lib.rs │ ├── main.rs │ ├── notary_api.rs │ └── profile_api.rs ├── apple-bom ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── builder.rs │ ├── dumpbom.rs │ ├── error.rs │ ├── format.rs │ ├── lib.rs │ ├── path.rs │ └── testdata │ └── python-applications.bom ├── apple-bundles ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ ├── directory_bundle.rs │ ├── lib.rs │ └── macos_application_bundle.rs ├── apple-codesign ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md ├── docs │ ├── Makefile │ ├── apple_codesign.rst │ ├── apple_codesign_actions_initiator_output.png │ ├── apple_codesign_actions_signer_output.png │ ├── apple_codesign_actions_sjs_join.png │ ├── apple_codesign_certificate_management.rst │ ├── apple_codesign_concepts.rst │ ├── apple_codesign_custom_assessment_policies.rst │ ├── apple_codesign_debugging.rst │ ├── apple_codesign_developer_guide.rst │ ├── apple_codesign_gatekeeper.rst │ ├── apple_codesign_getting_started.rst │ ├── apple_codesign_github_actions.rst │ ├── apple_codesign_quirks.rst │ ├── apple_codesign_rcodesign.rst │ ├── apple_codesign_rcodesign_config_files.rst │ ├── apple_codesign_rcodesign_notarizing.rst │ ├── apple_codesign_rcodesign_signing.rst │ ├── apple_codesign_remote_signing.rst │ ├── apple_codesign_remote_signing_design.rst │ ├── apple_codesign_remote_signing_protocol.rst │ ├── apple_codesign_settings_scope.rst │ ├── apple_codesign_smartcard.rst │ ├── conf.py │ └── index.rst ├── src │ ├── apple-certs │ │ ├── AppleAAI2CA.cer │ │ ├── AppleAAICA.cer │ │ ├── AppleAAICAG3.cer │ │ ├── AppleApplicationIntegrationCA5G1.cer │ │ ├── AppleApplicationIntegrationCA7G1.cer │ │ ├── AppleComputerRootCertificate.cer │ │ ├── AppleISTCA2G1.cer │ │ ├── AppleISTCA8G1.cer │ │ ├── AppleIncRootCertificate.cer │ │ ├── AppleRootCA-G2.cer │ │ ├── AppleRootCA-G3.cer │ │ ├── AppleSoftwareUpdateCertificationAuthority.cer │ │ ├── AppleTimestampCA.cer │ │ ├── AppleWWDRCA.cer │ │ ├── AppleWWDRCAG2.cer │ │ ├── AppleWWDRCAG3.cer │ │ ├── AppleWWDRCAG4.cer │ │ ├── AppleWWDRCAG5.cer │ │ ├── AppleWWDRCAG6.cer │ │ ├── AppleWWDRCAG7.cer │ │ ├── AppleWWDRCAG8.cer │ │ ├── DevAuthCA.cer │ │ ├── DeveloperIDCA.cer │ │ └── DeveloperIDG2CA.cer │ ├── apple-codesign-testuser.p12 │ ├── apple_certificates.rs │ ├── bundle_signing.rs │ ├── certificate.rs │ ├── cli │ │ ├── certificate_source.rs │ │ ├── config.rs │ │ ├── debug_commands.rs │ │ ├── extract_commands.rs │ │ └── mod.rs │ ├── code_directory.rs │ ├── code_requirement.rs │ ├── code_resources.rs │ ├── cryptography.rs │ ├── dmg.rs │ ├── embedded_signature.rs │ ├── embedded_signature_builder.rs │ ├── entitlements.rs │ ├── environment_constraints.rs │ ├── error.rs │ ├── lib.rs │ ├── macho.rs │ ├── macho_builder.rs │ ├── macho_signing.rs │ ├── macho_universal.rs │ ├── macos.rs │ ├── main.rs │ ├── notarization.rs │ ├── plist_der.rs │ ├── policy.rs │ ├── reader.rs │ ├── remote_signing │ │ ├── mod.rs │ │ └── session_negotiation.rs │ ├── signing.rs │ ├── signing_settings.rs │ ├── specification.rs │ ├── stapling.rs │ ├── testdata │ │ ├── apple-signed-3rd-party-mac.cer │ │ ├── apple-signed-apple-development.cer │ │ ├── apple-signed-apple-distribution.cer │ │ ├── apple-signed-developer-id-application.cer │ │ ├── apple-signed-developer-id-application.pem │ │ ├── apple-signed-developer-id-installer.cer │ │ ├── ed25519.pk8 │ │ ├── rsa-2048.pk8 │ │ ├── secp256r1.pk8 │ │ ├── self-signed-ed25519-apple-development.p12 │ │ ├── self-signed-ed25519-apple-development.pem │ │ ├── self-signed-ed25519-apple-distribution.p12 │ │ ├── self-signed-ed25519-apple-distribution.pem │ │ ├── self-signed-ed25519-developer-id-application.p12 │ │ ├── self-signed-ed25519-developer-id-application.pem │ │ ├── self-signed-ed25519-developer-id-installer.p12 │ │ ├── self-signed-ed25519-developer-id-installer.pem │ │ ├── self-signed-ed25519-mac-installer-distribution.p12 │ │ ├── self-signed-ed25519-mac-installer-distribution.pem │ │ ├── self-signed-rsa-apple-development.p12 │ │ ├── self-signed-rsa-apple-development.pem │ │ ├── self-signed-rsa-apple-distribution.p12 │ │ ├── self-signed-rsa-apple-distribution.pem │ │ ├── self-signed-rsa-developer-id-application.p12 │ │ ├── self-signed-rsa-developer-id-application.pem │ │ ├── self-signed-rsa-developer-id-application2.pem │ │ ├── self-signed-rsa-developer-id-installer.p12 │ │ ├── self-signed-rsa-developer-id-installer.pem │ │ ├── self-signed-rsa-mac-installer-distribution.p12 │ │ └── self-signed-rsa-mac-installer-distribution.pem │ ├── ticket_lookup.rs │ ├── verify.rs │ ├── windows.rs │ └── yubikey.rs └── tests │ ├── cli_tests.rs │ └── cmd │ ├── analyze-certificate.trycmd │ ├── compute-code-hashes.trycmd │ ├── debug-create-macho.trycmd │ ├── diff-signatures.trycmd │ ├── encode-app-store-connect-api-key.trycmd │ ├── extract.trycmd │ ├── generate-csr.trycmd │ ├── generate-self-signed-cert.trycmd │ ├── help.trycmd │ ├── keychain-export-certificate-chain.trycmd │ ├── keychain-print-certificates.trycmd │ ├── macho-universal-create.trycmd │ ├── notary-log.trycmd │ ├── notary-submit.trycmd │ ├── notary-wait.trycmd │ ├── parse-code-signing-requirement.trycmd │ ├── print-signature-info.trycmd │ ├── remote-sign.trycmd │ ├── sign-binary-identifier.trycmd │ ├── sign-bundle-dsym.trycmd │ ├── sign-bundle-electron.trycmd │ ├── sign-bundle-exclude.trycmd │ ├── sign-bundle-framework-shallow.trycmd │ ├── sign-bundle-framework.trycmd │ ├── sign-bundle-macho-universal.trycmd │ ├── sign-bundle-multiple-macho.trycmd │ ├── sign-bundle-nested-macho-identifier.trycmd │ ├── sign-bundle-nested-outside-nested-directory.trycmd │ ├── sign-bundle-nested-symlinks.trycmd │ ├── sign-bundle-storybook-bundle.trycmd │ ├── sign-bundle-symlink-overwrite.trycmd │ ├── sign-bundle-with-nested-framework.trycmd │ ├── sign-bundle.trycmd │ ├── sign-cms.trycmd │ ├── sign-code-requirements.trycmd │ ├── sign-code-signature-flags.trycmd │ ├── sign-constraints.trycmd │ ├── sign-digests.trycmd │ ├── sign-entitlements.trycmd │ ├── sign-for-notarization.trycmd │ ├── sign-macho-info-plist.trycmd │ ├── sign-macho-reconcile-identifier.trycmd │ ├── sign-macho-text-segment-offset.trycmd │ ├── sign-macho-universal.trycmd │ ├── sign-p12.trycmd │ ├── sign.trycmd │ ├── smartcard-generate-key.trycmd │ ├── smartcard-import.trycmd │ ├── smartcard-scan.trycmd │ ├── staple.trycmd │ ├── verify.trycmd │ ├── windows-store-export-certificate-chain.trycmd │ ├── windows-store-print-certificates.trycmd │ └── x509-oids.trycmd ├── apple-dmg ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── assets │ └── example.dmg └── src │ ├── blkx.rs │ ├── koly.rs │ ├── lib.rs │ └── xml.rs ├── apple-flat-package ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ ├── component_package.rs │ ├── distribution.rs │ ├── lib.rs │ ├── package_info.rs │ └── reader.rs ├── apple-sdk ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── lib.rs │ ├── parsed_sdk.rs │ ├── search.rs │ ├── simple_sdk.rs │ └── testfiles │ ├── macosx10.10-settings.plist │ ├── macosx10.15-settings.json │ ├── macosx10.9-settings.plist │ └── macosx11.3-settings.json ├── apple-xar ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ ├── format.rs │ ├── lib.rs │ ├── reader.rs │ ├── signing.rs │ └── table_of_contents.rs ├── ci └── developer-id-application.pem ├── cpio-archive ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ ├── lib.rs │ ├── newc.rs │ └── odc.rs ├── release.toml ├── scripts └── secure_download.py └── terraform-modules └── remote-code-signing ├── README.rst ├── main.tf └── websocket.py /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [profile.dev.package."*"] 2 | opt-level = 2 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [Makefile] 2 | indent_style = tab 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [indygreg] 2 | -------------------------------------------------------------------------------- /.github/workflows/rcodesign.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | tags-ignore: 6 | - '**' 7 | pull_request: 8 | schedule: 9 | - cron: '12 15 * * *' 10 | workflow_dispatch: 11 | jobs: 12 | exes: 13 | uses: indygreg/actions/.github/workflows/rust-exe.yml@214a8641784d19c45f4261ed8e5a57db81ae6b4e 14 | with: 15 | actions_ref: "214a8641784d19c45f4261ed8e5a57db81ae6b4e" 16 | bin: rcodesign 17 | extra_build_args_macos: '--all-features' 18 | extra_build_args_windows: '--all-features' 19 | just_bootstrap: true 20 | sccache_s3_bucket: apple-platform-rs-sccache 21 | secrets: 22 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 23 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 24 | -------------------------------------------------------------------------------- /.github/workflows/sign-apple-exe.yml: -------------------------------------------------------------------------------- 1 | name: Remotely code sign an Apple executable 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | workflow: 6 | description: 'Workflow file name or ID' 7 | required: true 8 | type: string 9 | run_id: 10 | description: 'Workflow run ID to use' 11 | required: true 12 | type: string 13 | artifact: 14 | description: 'Name of artifact to download' 15 | required: true 16 | type: string 17 | exe_name: 18 | description: 'Name of executable file to sign' 19 | required: true 20 | type: string 21 | rcodesign_branch: 22 | description: 'Name of branch to obtain rcodesign executable from' 23 | required: false 24 | default: main 25 | 26 | jobs: 27 | sign: 28 | name: Sign ${{ github.event.inputs.exe_name }} 29 | runs-on: 'ubuntu-22.04' 30 | timeout-minutes: 10 31 | steps: 32 | - uses: actions/checkout@v3 33 | 34 | - name: Download rcodesign Linux executable 35 | uses: dawidd6/action-download-artifact@9662f5cf4983f094c5b142e8fec9ddea560ca302 36 | with: 37 | repo: ${{github.repository}} 38 | workflow: '.github/workflows/rcodesign.yml' 39 | workflow_conclusion: success 40 | branch: ${{ github.event.inputs.rcodesign_branch }} 41 | event: push 42 | name: exe-rcodesign-x86_64-unknown-linux-musl 43 | path: bins/ 44 | 45 | - name: Download artifact to sign 46 | uses: dawidd6/action-download-artifact@9662f5cf4983f094c5b142e8fec9ddea560ca302 47 | with: 48 | repo: ${{ github.repository }} 49 | workflow: ${{ github.event.inputs.workflow }} 50 | run_id: ${{ github.event.inputs.run_id }} 51 | workflow_conclusion: completed 52 | name: ${{ github.event.inputs.artifact }} 53 | path: dist/input 54 | 55 | - name: Perform remote code signing 56 | run: | 57 | # Just in case. 58 | chmod +x bins/rcodesign 59 | 60 | bins/rcodesign sign \ 61 | --remote-signer \ 62 | --remote-public-key-pem-file ci/developer-id-application.pem \ 63 | --code-signature-flags runtime \ 64 | dist/input/${{ github.event.inputs.exe_name }} \ 65 | dist/output/${{ github.event.inputs.exe_name }} 66 | 67 | - name: Upload 68 | uses: actions/upload-artifact@v3 69 | with: 70 | name: exe-${{ github.event.inputs.exe_name }} 71 | path: dist/output/${{ github.event.inputs.exe_name }} 72 | -------------------------------------------------------------------------------- /.github/workflows/sphinx.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | tags-ignore: 6 | - '**' 7 | pull_request: 8 | schedule: 9 | - cron: '12 15 * * *' 10 | workflow_dispatch: 11 | jobs: 12 | sphinx: 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | dir: 17 | - apple-codesign/docs 18 | runs-on: ubuntu-22.04 19 | steps: 20 | - uses: actions/checkout@v3 21 | - uses: actions/setup-python@v2 22 | with: 23 | python-version: '3.10' 24 | - name: Run Sphinx 25 | run: | 26 | python3.10 -m pip install Sphinx==5.1.1 27 | make -C ${{ matrix.dir }} html 28 | -------------------------------------------------------------------------------- /.github/workflows/workspace.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | tags-ignore: 6 | - '**' 7 | pull_request: 8 | schedule: 9 | - cron: '12 15 * * *' 10 | workflow_dispatch: 11 | jobs: 12 | build-and-test: 13 | uses: indygreg/actions/.github/workflows/rust-workspace-build-and-test.yml@10a44fe88eeb39ae10b317766e420dfa0898d183 14 | with: 15 | actions_ref: "10a44fe88eeb39ae10b317766e420dfa0898d183" 16 | msrv: "1.81.0" 17 | sccache_s3_bucket: apple-platform-rs-sccache 18 | no_default_features: true 19 | secrets: 20 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 21 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | apple-codesign/docs/_build/ 3 | dist/ 4 | target/ 5 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | 'apfs-derive', 4 | 'apfs-types', 5 | 'apple-bom', 6 | 'apple-bundles', 7 | 'apple-codesign', 8 | 'apple-dmg', 9 | 'apple-flat-package', 10 | 'apple-sdk', 11 | 'apple-xar', 12 | 'app-store-connect', 13 | 'cpio-archive', 14 | ] 15 | resolver = "2" 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # apple-platform-rs 2 | 3 | This repository contains a collection of Rust crates to support Apple 4 | platforms. 5 | 6 | See the various project directories for more. 7 | 8 | The most notable project is `apple-codesign`, which contains a pure Rust 9 | (re)implementation of Apple code signing and notarization. This enables 10 | you to sign, notarize, and release Apple software without macOS and without 11 | Apple hardware. 12 | -------------------------------------------------------------------------------- /apfs-derive/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # apfs-derive Crate Changelog 2 | 3 | 4 | 5 | ## Unreleased 6 | 7 | Released on ReleaseDate. 8 | -------------------------------------------------------------------------------- /apfs-derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "apfs-derive" 3 | version = "0.1.0" 4 | edition = "2021" 5 | license = "MIT OR Apache-2.0" 6 | readme = "README.md" 7 | authors = ["Gregory Szorc "] 8 | description = "Apple File System (APFS) support macros" 9 | keywords = ["apple", "apfs", "filesystem"] 10 | homepage = "https://github.com/indygreg/apple-platform-rs" 11 | repository = "https://github.com/indygreg/apple-platform-rs.git" 12 | 13 | [lib] 14 | proc-macro = true 15 | 16 | [dependencies] 17 | indoc = "2.0.5" 18 | proc-macro2 = "1.0.92" 19 | syn = { version = "2.0.89", features = ["extra-traits", "full"] } 20 | quote = "1.0.37" 21 | -------------------------------------------------------------------------------- /apfs-derive/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright 2022 Gregory Szorc 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to use, 6 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 7 | Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | 20 | -------------------------------------------------------------------------------- /apfs-derive/README.md: -------------------------------------------------------------------------------- 1 | # apfs-derive 2 | 3 | `apfs-derive` defines procedural macros used by various `apfs-*` crates. 4 | -------------------------------------------------------------------------------- /apfs-types/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # apfs-types Crate Changelog 2 | 3 | 4 | 5 | ## Unreleased 6 | 7 | Released on ReleaseDate. 8 | 9 | * Initial version. Implements (hopefully) all the types defined 10 | in the 2020-06-22 dated version of 11 | https://developer.apple.com/support/downloads/Apple-File-System-Reference.pdf. 12 | -------------------------------------------------------------------------------- /apfs-types/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "apfs-types" 3 | version = "0.1.0" 4 | edition = "2021" 5 | license = "MIT OR Apache-2.0" 6 | readme = "README.md" 7 | authors = ["Gregory Szorc "] 8 | description = "Apple File System (APFS) data structures and constants" 9 | keywords = ["apple", "apfs", "filesystem"] 10 | homepage = "https://github.com/indygreg/apple-platform-rs" 11 | repository = "https://github.com/indygreg/apple-platform-rs.git" 12 | 13 | [dependencies] 14 | bitflags = "2.6.0" 15 | bytes = { version = "1.9.0", optional = true, default-features = false } 16 | chrono = { version = "0.4.38", default-features = false } 17 | num_enum = { version = "0.7.3", features = ["complex-expressions"] } 18 | thiserror = "2.0.3" 19 | 20 | [dependencies.apfs-derive] 21 | path = "../apfs-derive" 22 | version = "0.1.0" 23 | optional = true 24 | 25 | [features] 26 | default = ["derive"] 27 | derive = ["dep:bytes", "dep:apfs-derive"] 28 | std = [] 29 | -------------------------------------------------------------------------------- /apfs-types/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright 2022 Gregory Szorc 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to use, 6 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 7 | Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | 20 | -------------------------------------------------------------------------------- /apfs-types/README.md: -------------------------------------------------------------------------------- 1 | # apfs-types 2 | 3 | `apfs-types` defines data structures, enums, and constants used by the Apple 4 | file system (APFS). 5 | -------------------------------------------------------------------------------- /apfs-types/src/efi_jumpstart.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Gregory Szorc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | //! EFI Jumpstart 10 | 11 | use crate::{common::PhysicalAddressRangeRaw, object::ObjectHeaderRaw, DynamicSized}; 12 | use core::ops::Range; 13 | 14 | #[cfg(feature = "derive")] 15 | use { 16 | crate::{DynamicSizedParse, ParseError}, 17 | apfs_derive::ApfsData, 18 | }; 19 | 20 | pub const EFI_JUMPSTART_MAGIC: &[u8; 4] = b"RDSJ"; 21 | 22 | pub const EFI_JUMPSTART_VERSION: u32 = 1; 23 | 24 | /// Block holding information about the embedded EFI driver (`nx_efi_jumpstart_t`). 25 | #[derive(Clone, Debug)] 26 | #[cfg_attr(feature = "derive", derive(ApfsData))] 27 | #[repr(C)] 28 | pub struct EfiJumpstartBlockRaw { 29 | /// Common object header (`nej_o`). 30 | pub object: ObjectHeaderRaw, 31 | 32 | /// Value to confirm reading of EFI jumpstart data (`nej_magic`). 33 | /// 34 | /// Value is always [EFI_JUMPSTART_MAGIC]. 35 | pub magic: u32, 36 | 37 | /// The version of this data structure (`nej_version`). 38 | /// 39 | /// Value is always [EFI_JUMPSTART_VERSION]. 40 | pub version: u32, 41 | 42 | /// Size in bytes of embedded EFI driver (`nej_efi_file_len`). 43 | pub efi_file_length: u32, 44 | 45 | /// The number of extents in this record (`nej_num_extents`). 46 | pub number_extents: u32, 47 | 48 | /// Reserved (`nej_reserved`). 49 | /// 50 | /// Populate with 0 and preserve value during modification. 51 | pub reserved: [u64; 16], 52 | 53 | /// Locations where the EFI driver is stored (`nej_rec_extents`). 54 | /// 55 | /// Array length defined by the [Self::number_extents] field. 56 | #[cfg_attr( 57 | feature = "derive", 58 | apfs( 59 | trailing_data = "crate::pod::MemoryBackedArray" 60 | ) 61 | )] 62 | pub record_extents: [PhysicalAddressRangeRaw; 0], 63 | } 64 | 65 | impl DynamicSized for EfiJumpstartBlockRaw { 66 | type RangeBounds = Range; 67 | 68 | fn trailing_data_bounds(&self) -> Self::RangeBounds { 69 | let size = self.number_extents as usize * core::mem::size_of::(); 70 | 71 | 0..size 72 | } 73 | } 74 | 75 | #[cfg(feature = "derive")] 76 | impl DynamicSizedParse for EfiJumpstartBlockRaw { 77 | type TrailingData = crate::pod::MemoryBackedArray< 78 | PhysicalAddressRangeRaw, 79 | crate::common::PhysicalAddressRangeParsed, 80 | >; 81 | 82 | fn parse_trailing_data(&self, data: bytes::Bytes) -> Result { 83 | crate::pod::MemoryBackedArray::new(data, self.number_extents as _) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /apfs-types/src/fusion.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Gregory Szorc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | //! Fusion. 10 | //! 11 | //! Fusion is a mode where a container is backed by multiple devices, 12 | //! typically a fast SSD and a slow HD. 13 | 14 | use crate::{ 15 | common::{ObjectIdentifierRaw, PhysicalAddressRangeRaw, PhysicalAddressRaw}, 16 | object::ObjectHeaderRaw, 17 | DynamicSized, 18 | }; 19 | use bitflags::bitflags; 20 | use core::ops::RangeFrom; 21 | 22 | #[cfg(feature = "derive")] 23 | use apfs_derive::ApfsData; 24 | 25 | /// Fusion writeback cache block (`fusion_wbc_phys_t`). 26 | #[derive(Clone, Copy, Debug)] 27 | #[cfg_attr(feature = "derive", derive(ApfsData))] 28 | #[repr(C)] 29 | pub struct FusionWritebackCacheBlockRaw { 30 | /// (`fwp_objHdr`). 31 | pub object: ObjectHeaderRaw, 32 | /// (`fwp_version`). 33 | pub version: u64, 34 | /// (`fwp_listHeadOid`). 35 | pub list_head_oid: ObjectIdentifierRaw, 36 | /// (`fwp_listTailOid`). 37 | pub list_tail_oid: ObjectIdentifierRaw, 38 | /// (`fwp_stableHeadOffset`). 39 | pub stable_head_offset: u64, 40 | /// (`fwp_stableTailOffset`). 41 | pub stable_tail_offset: u64, 42 | /// (`fwp_listBlocksCount`). 43 | pub list_blocks_count: u32, 44 | /// (`fwp_reserved`). 45 | pub reserved: u32, 46 | /// (`fwp_usedByRC`). 47 | pub used_by_rc: u64, 48 | /// (`fwp_rcStash`). 49 | pub rc_stash: PhysicalAddressRangeRaw, 50 | } 51 | 52 | /// Fusion writeback cache list entry (`fusion_wbc_list_entry_t`). 53 | #[derive(Clone, Copy, Debug)] 54 | #[cfg_attr(feature = "derive", derive(ApfsData))] 55 | #[repr(C)] 56 | pub struct FusionWritebackCacheListEntryRaw { 57 | /// (`fwle_wbcLba`). 58 | pub writeback_cache_lba: PhysicalAddressRaw, 59 | /// (`fwle_targetLba`). 60 | pub target_lba: PhysicalAddressRaw, 61 | /// (`fwle_length`). 62 | pub length: u64, 63 | } 64 | 65 | /// Fusion writeback cache list block (`fusion_wbc_list_phys_t`). 66 | /// 67 | /// Keeps track of data from the hard drive that's cached on SSD. 68 | #[derive(Clone, Debug)] 69 | #[cfg_attr(feature = "derive", derive(ApfsData))] 70 | #[repr(C)] 71 | pub struct FusionWritebackCacheListBlockRaw { 72 | /// (`fwlp_objHdr`). 73 | pub object: ObjectHeaderRaw, 74 | /// (`fwlp_version`). 75 | pub version: u64, 76 | /// (`fwlp_tailOffset`). 77 | pub tail_offset: u64, 78 | /// (`fwlp_indexBegin`). 79 | pub index_begin: u32, 80 | /// (`fwlp_indexEnd`). 81 | pub index_end: u32, 82 | /// (`fwlp_indexMax`). 83 | pub index_max: u32, 84 | /// (`fwlp_reserved`). 85 | pub reserved: u32, 86 | /// (`fwlp_listEntries`). 87 | #[cfg_attr(feature = "derive", apfs(trailing_data))] 88 | pub entries: [FusionWritebackCacheListEntryRaw; 0], 89 | } 90 | 91 | impl DynamicSized for FusionWritebackCacheListBlockRaw { 92 | type RangeBounds = RangeFrom; 93 | 94 | fn trailing_data_bounds(&self) -> Self::RangeBounds { 95 | 0.. 96 | } 97 | } 98 | 99 | /// Fusion middle-tree key (`fusion_mt_key_t`). 100 | pub type FusionMiddleTreeKey = PhysicalAddressRaw; 101 | 102 | bitflags! { 103 | /// Fusion middle-tree flags. 104 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] 105 | #[cfg_attr(feature = "derive", derive(ApfsData), apfs(bitflags_u32))] 106 | pub struct FusionMiddleTreeFlagsRaw: u32 { 107 | const Dirty = 1; 108 | const Tenant = 2; 109 | const _ = !0; 110 | } 111 | } 112 | 113 | /// Fusion middle-tree value (`fusion_mt_val_t`). 114 | #[derive(Clone, Debug)] 115 | #[cfg_attr(feature = "derive", derive(ApfsData))] 116 | #[repr(C)] 117 | pub struct FusionMiddleTreeValueRaw { 118 | /// (`fmv_lba`). 119 | pub lba: PhysicalAddressRaw, 120 | /// (`fmv_length`). 121 | pub length: u32, 122 | /// (`fmv_flags`). 123 | pub flags: FusionMiddleTreeFlagsRaw, 124 | } 125 | -------------------------------------------------------------------------------- /apfs-types/src/sibling.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Gregory Szorc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | //! Siblings. 10 | //! 11 | //! Siblings are hard links that refer to the same inode. Each sibling 12 | //! has its own identifier distinct from the inode's. 13 | //! 14 | //! The sibling with the lowest number is the "primary link." 15 | 16 | use crate::{filesystem::FileSystemKeyRaw, DynamicSized}; 17 | use core::ops::Range; 18 | 19 | #[cfg(feature = "derive")] 20 | use { 21 | crate::{DynamicSizedParse, ParseError}, 22 | apfs_derive::ApfsData, 23 | }; 24 | 25 | /// Sibling link record key (`j_sibling_key_t`). 26 | #[derive(Clone, Copy, Debug)] 27 | #[cfg_attr(feature = "derive", derive(ApfsData), apfs(filesystem_key))] 28 | #[repr(C, packed)] 29 | pub struct SiblingLinkRecordKeyRaw { 30 | /// Common filesystem object header. 31 | /// 32 | /// Identifier is inode number. 33 | pub header: FileSystemKeyRaw, 34 | 35 | /// The sibling's unique identifier. 36 | pub sibling_id: u64, 37 | } 38 | 39 | /// Sibling link record value (`j_sibling_val_t`). 40 | #[derive(Clone, Debug)] 41 | #[cfg_attr(feature = "derive", derive(ApfsData), apfs(filesystem_value))] 42 | #[repr(C, packed)] 43 | pub struct SiblingLinkRecordValueRaw { 44 | /// Filesystem object identifier for the parent directory's inode. 45 | pub parent_id: u64, 46 | 47 | /// Length of the name in bytes, including trailing NULL. 48 | /// 49 | /// The use of a u64 is likely for padding reasons. Names should never 50 | /// be anywhere close to that long. 51 | /// 52 | /// Our [DynamicSized] implementation will panic if this value is 53 | /// larger than usize. 54 | pub name_length: u64, 55 | 56 | /// The name as a NULL terminated UTF-8 string. 57 | #[cfg_attr(feature = "derive", apfs(trailing_data = "crate::pod::ApfsString"))] 58 | pub name: [u8; 0], 59 | } 60 | 61 | impl DynamicSized for SiblingLinkRecordValueRaw { 62 | type RangeBounds = Range; 63 | 64 | fn trailing_data_bounds(&self) -> Self::RangeBounds { 65 | if self.name_length > usize::MAX as u64 { 66 | panic!("invalid name length; cannot be larger than machine native integer"); 67 | } 68 | 69 | 0..self.name_length as usize 70 | } 71 | } 72 | 73 | #[cfg(feature = "derive")] 74 | impl DynamicSizedParse for SiblingLinkRecordValueRaw { 75 | type TrailingData = crate::pod::ApfsString; 76 | 77 | fn parse_trailing_data(&self, data: bytes::Bytes) -> Result { 78 | crate::pod::ApfsString::from_bytes(data) 79 | } 80 | } 81 | 82 | /// A sibling map record key (`j_sibling_map_key_t`). 83 | #[derive(Clone, Copy, Debug)] 84 | #[cfg_attr(feature = "derive", derive(ApfsData), apfs(filesystem_key))] 85 | #[repr(C, packed)] 86 | pub struct SiblingMapRecordKeyRaw { 87 | /// Common filesystem object header. 88 | /// 89 | /// Object ID is the sibling's unique identifier. Should match the 90 | /// `sibling_id` field on [SiblingLinkRecordKeyRaw]. 91 | pub header: FileSystemKeyRaw, 92 | } 93 | 94 | /// A sibling map record value (`j_sibling_map_val_t`). 95 | #[derive(Clone, Copy, Debug)] 96 | #[cfg_attr(feature = "derive", derive(ApfsData), apfs(filesystem_value))] 97 | #[repr(C, packed)] 98 | pub struct SiblingMapRecordValueRaw { 99 | /// The inode number of the underlying file. 100 | pub file_id: u64, 101 | } 102 | -------------------------------------------------------------------------------- /app-store-connect/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # app-store-connect Crate Changelog 2 | 3 | 4 | 5 | ## Unreleased 6 | 7 | Released on ReleaseDate. 8 | 9 | ## 0.7.0 10 | 11 | Released on 2024-11-29. 12 | 13 | * MSRV 1.78 -> 1.81. 14 | * `clap` 4.4 -> 4.5. 15 | * `jsonwebtoken` 9.2 -> 9.3. 16 | * `thiserror` 1.0 -> 2.0. 17 | 18 | ## 0.6.0 19 | 20 | Released on 2024-11-03. 21 | 22 | * New APIs and CLI commands to: list capabilities with a bundle ID; 23 | list profiles associated with a bundle ID; get bundle ID associated with 24 | a profile; list certificates associated with a profile; enable capacity 25 | for a bundle ID. (#164) 26 | * Added `IosDistribution` variant to `CertificateType` enum. 27 | * Enabled `http2` feature of `reqwest` crate. This may provide better HTTP/2.0 28 | compatibility. 29 | * MSRV 1.70 -> 1.78. 30 | * `base64` 0.21 -> 0.22. 31 | * `env_logger` 0.10 -> 0.11. 32 | * `reqwest` 0.11 -> 0.12 33 | * `x509-certificate` 0.23 -> 0.24. 34 | 35 | ## 0.5.0 36 | 37 | Released on 2024-01-17. 38 | 39 | ## 0.4.0 40 | 41 | Released on 2023-11-15. 42 | 43 | ## 0.3.0 44 | 45 | Released on 2023-11-09. 46 | 47 | * x509-certificate 0.22 -> 0.23. 48 | 49 | ## 0.2.0 50 | 51 | Released on 2023-11-06. 52 | 53 | * Minimum supported Rust version changed from 1.62 to 1.64. 54 | * CLI code moved from `main.rs` to a `cli` module. 55 | * HTTP requests now use the operating system's trusted X.509 certificates 56 | instead of a default set (based off Mozilla's maintained list). This should 57 | allow connections to HTTP proxies using custom/private certificate authorities 58 | to work, assuming certificates are installed on the local system. (#85) 59 | * jsonwebtoken 8.3 -> 9.1. 60 | * pem 1.1 -> 3.0. 61 | * rsa 0.7 -> 0.8. 62 | * x509-certificate 0.16 -> 0.22. 63 | * dirs 4.0.0 -> 5.0.0. 64 | * Minimum supported Rust version is now 1.70. 65 | 66 | ## 0.1.0 67 | 68 | Released on 2022-12-21. 69 | 70 | * Initial version of crate. Code borrowed and extended from apple-codesign crate. 71 | -------------------------------------------------------------------------------- /app-store-connect/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "app-store-connect" 3 | version = "0.7.0" 4 | edition = "2021" 5 | rust-version = "1.81" 6 | license = "Apache-2.0 OR MIT" 7 | description = "Apple App Store Connect API and client" 8 | keywords = ["apple"] 9 | homepage = "https://github.com/indygreg/apple-platform-rs" 10 | repository = "https://github.com/indygreg/apple-platform-rs.git" 11 | readme = "README.md" 12 | 13 | [dependencies] 14 | anyhow = "1.0.93" 15 | base64 = "0.22.1" 16 | clap = { version = "4.5.21", features = ["derive"] } 17 | dirs = "5.0.1" 18 | env_logger = "0.11.5" 19 | jsonwebtoken = "9.3.0" 20 | log = "0.4.22" 21 | pem = "3.0.4" 22 | rand = "0.8.5" 23 | reqwest = { version = "0.12.9", default-features = false, features = ["blocking", "http2", "json", "rustls-tls-native-roots"] } 24 | rsa = "0.9.7" 25 | serde = { version = "1.0.215", features = ["derive"] } 26 | serde_json = "1.0.133" 27 | thiserror = "2.0.3" 28 | x509-certificate = "0.24.0" 29 | -------------------------------------------------------------------------------- /app-store-connect/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright 2022 David Craven and Gregory Szorc 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to use, 6 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 7 | Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | 20 | -------------------------------------------------------------------------------- /app-store-connect/README.md: -------------------------------------------------------------------------------- 1 | # app-store-connect 2 | 3 | This library and application crate implements a client for Apple's 4 | [App Store Connect](https://appstoreconnect.apple.com) API. 5 | -------------------------------------------------------------------------------- /app-store-connect/src/device_api.rs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 or the MIT license 3 | // , at your 4 | // option. This file may not be copied, modified, or distributed 5 | // except according to those terms. 6 | 7 | use crate::bundle_api::BundleIdPlatform; 8 | use crate::{AppStoreConnectClient, Result}; 9 | use serde::{Deserialize, Serialize}; 10 | 11 | const APPLE_CERTIFICATE_URL: &str = "https://api.appstoreconnect.apple.com/v1/devices"; 12 | 13 | impl AppStoreConnectClient { 14 | pub fn register_device( 15 | &self, 16 | name: &str, 17 | platform: BundleIdPlatform, 18 | udid: &str, 19 | ) -> Result { 20 | let token = self.get_token()?; 21 | let body = DeviceCreateRequest { 22 | data: DeviceCreateRequestData { 23 | attributes: DeviceCreateRequestAttributes { 24 | name: name.into(), 25 | platform: platform.to_string(), 26 | udid: udid.into(), 27 | }, 28 | r#type: "devices".into(), 29 | }, 30 | }; 31 | let req = self 32 | .client 33 | .post(APPLE_CERTIFICATE_URL) 34 | .bearer_auth(token) 35 | .header("Accept", "application/json") 36 | .header("Content-Type", "application/json") 37 | .json(&body); 38 | Ok(self.send_request(req)?.json()?) 39 | } 40 | 41 | pub fn list_devices(&self) -> Result { 42 | let token = self.get_token()?; 43 | let req = self 44 | .client 45 | .get(APPLE_CERTIFICATE_URL) 46 | .bearer_auth(token) 47 | .header("Accept", "application/json"); 48 | Ok(self.send_request(req)?.json()?) 49 | } 50 | 51 | pub fn get_device(&self, id: &str) -> Result { 52 | let token = self.get_token()?; 53 | let req = self 54 | .client 55 | .get(format!("{APPLE_CERTIFICATE_URL}/{id}")) 56 | .bearer_auth(token) 57 | .header("Accept", "application/json"); 58 | Ok(self.send_request(req)?.json()?) 59 | } 60 | } 61 | 62 | #[derive(Debug, Serialize)] 63 | #[serde(rename_all = "camelCase")] 64 | pub struct DeviceCreateRequest { 65 | pub data: DeviceCreateRequestData, 66 | } 67 | 68 | #[derive(Debug, Serialize)] 69 | #[serde(rename_all = "camelCase")] 70 | pub struct DeviceCreateRequestData { 71 | pub attributes: DeviceCreateRequestAttributes, 72 | pub r#type: String, 73 | } 74 | 75 | #[derive(Debug, Serialize)] 76 | #[serde(rename_all = "camelCase")] 77 | pub struct DeviceCreateRequestAttributes { 78 | pub name: String, 79 | pub platform: String, 80 | pub udid: String, 81 | } 82 | 83 | #[derive(Debug, Deserialize)] 84 | #[serde(rename_all = "camelCase")] 85 | pub struct DeviceResponse { 86 | pub data: Device, 87 | } 88 | 89 | #[derive(Debug, Deserialize)] 90 | #[serde(rename_all = "camelCase")] 91 | pub struct DevicesResponse { 92 | pub data: Vec, 93 | } 94 | 95 | #[derive(Debug, Deserialize)] 96 | #[serde(rename_all = "camelCase")] 97 | pub struct Device { 98 | pub attributes: DeviceAttributes, 99 | pub id: String, 100 | } 101 | 102 | #[derive(Debug, Deserialize)] 103 | #[serde(rename_all = "camelCase")] 104 | pub struct DeviceAttributes { 105 | pub device_class: String, 106 | pub model: Option, 107 | pub name: String, 108 | pub platform: String, 109 | pub status: String, 110 | pub udid: String, 111 | pub added_date: String, 112 | } 113 | -------------------------------------------------------------------------------- /app-store-connect/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 or the MIT license 3 | // , at your 4 | // option. This file may not be copied, modified, or distributed 5 | // except according to those terms. 6 | 7 | mod api_key; 8 | mod api_token; 9 | pub mod bundle_api; 10 | pub mod certs_api; 11 | pub mod cli; 12 | pub mod device_api; 13 | pub mod notary_api; 14 | pub mod profile_api; 15 | 16 | use { 17 | reqwest::blocking::{Client, ClientBuilder, RequestBuilder, Response}, 18 | serde_json::Value, 19 | std::{path::Path, sync::Mutex}, 20 | thiserror::Error, 21 | }; 22 | 23 | pub use crate::api_key::{InvalidPemPrivateKey, UnifiedApiKey}; 24 | pub use crate::api_token::{AppStoreConnectToken, ConnectTokenEncoder, MissingApiKey}; 25 | 26 | pub type Result = anyhow::Result; 27 | 28 | /// A client for App Store Connect API. 29 | /// 30 | /// The client isn't generic. Don't get any ideas. 31 | pub struct AppStoreConnectClient { 32 | client: Client, 33 | connect_token: ConnectTokenEncoder, 34 | token: Mutex>, 35 | } 36 | 37 | impl AppStoreConnectClient { 38 | pub fn from_json_path(path: &Path) -> Result { 39 | let key = UnifiedApiKey::from_json_path(path)?; 40 | AppStoreConnectClient::new(key.try_into()?) 41 | } 42 | 43 | /// Create a new client to the App Store Connect API. 44 | pub fn new(connect_token: ConnectTokenEncoder) -> Result { 45 | let client = ClientBuilder::default() 46 | .user_agent("asconnect crate (https://crates.io/crates/asconnect)") 47 | .build()?; 48 | Ok(Self { 49 | client, 50 | connect_token, 51 | token: Mutex::new(None), 52 | }) 53 | } 54 | 55 | pub fn get_token(&self) -> Result { 56 | let mut token = self.token.lock().unwrap(); 57 | 58 | // TODO need to handle token expiration. 59 | if token.is_none() { 60 | token.replace(self.connect_token.new_token(300)?); 61 | } 62 | 63 | Ok(token.as_ref().unwrap().clone()) 64 | } 65 | 66 | pub fn send_request(&self, request: RequestBuilder) -> Result { 67 | let request = request.build()?; 68 | let method = request.method().to_string(); 69 | let url = request.url().to_string(); 70 | 71 | log::debug!("{} {}", request.method(), url); 72 | 73 | let response = self.client.execute(request)?; 74 | 75 | if response.status().is_success() { 76 | Ok(response) 77 | } else { 78 | let body = response.bytes()?; 79 | 80 | let message = if let Ok(value) = serde_json::from_slice::(body.as_ref()) { 81 | serde_json::to_string_pretty(&value)? 82 | } else { 83 | String::from_utf8_lossy(body.as_ref()).into() 84 | }; 85 | 86 | Err(AppStoreConnectError { 87 | method, 88 | url, 89 | message, 90 | } 91 | .into()) 92 | } 93 | } 94 | } 95 | 96 | #[derive(Clone, Debug, Error)] 97 | #[error("appstore connect error:\n{method} {url}\n{message}")] 98 | pub struct AppStoreConnectError { 99 | method: String, 100 | url: String, 101 | message: String, 102 | } 103 | -------------------------------------------------------------------------------- /app-store-connect/src/main.rs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 or the MIT license 3 | // , at your 4 | // option. This file may not be copied, modified, or distributed 5 | // except according to those terms. 6 | 7 | use anyhow::Result; 8 | use app_store_connect::cli::Args; 9 | use clap::Parser; 10 | 11 | fn main() -> Result<()> { 12 | env_logger::init(); 13 | let args = Args::parse(); 14 | if let Some(api_key) = args.api_key.as_ref() { 15 | args.command.run(api_key) 16 | } else { 17 | anyhow::bail!("missing --api-key"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /apple-bom/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # apple-bom Crate Changelog 2 | 3 | 4 | 5 | ## Unreleased 6 | 7 | Released on ReleaseDate. 8 | 9 | * `clap` 4.4 -> 4.5. 10 | 11 | ## 0.3.0 12 | 13 | Released on 2024-11-03. 14 | 15 | * `crc32fast` 1.3 -> 1.4. 16 | 17 | ## 0.2.0 18 | 19 | Released on 2023-11-06. 20 | 21 | * Cargo.toml now defines patch version for all dependencies. 22 | * Minimum supported Rust version is now 1.70. 23 | -------------------------------------------------------------------------------- /apple-bom/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "apple-bom" 3 | version = "0.3.0" 4 | authors = ["Gregory Szorc "] 5 | edition = "2021" 6 | rust-version = "1.81" 7 | license = "MIT OR Apache-2.0" 8 | description = "Apple Bill of Materials (BOM) data format" 9 | keywords = ["bom", "apple", "macos", "pkg"] 10 | homepage = "https://github.com/indygreg/apple-platform-rs" 11 | repository = "https://github.com/indygreg/apple-platform-rs.git" 12 | readme = "README.md" 13 | 14 | [[bin]] 15 | name = "odumpbom" 16 | path = "src/dumpbom.rs" 17 | 18 | [dependencies] 19 | clap = "4.5.21" 20 | chrono = "0.4.38" 21 | crc32fast = "1.4.2" 22 | hex = "0.4.3" 23 | scroll = { version = "0.12.0", features = ["derive"] } 24 | simple-file-manifest = "0.11.0" 25 | thiserror = "2.0.3" 26 | -------------------------------------------------------------------------------- /apple-bom/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright 2022 Gregory Szorc 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to use, 6 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 7 | Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | 20 | -------------------------------------------------------------------------------- /apple-bom/README.md: -------------------------------------------------------------------------------- 1 | # apple-bom 2 | 3 | This crate supports parsing and serializing Apple Bill of Materials (BOM) 4 | files. These files are typically encountered in Apple `.pkg` installers. 5 | 6 | **This crate is a work in progress and doesn't yet implement all features 7 | correctly. Contributions are much welcomed.** 8 | -------------------------------------------------------------------------------- /apple-bom/src/dumpbom.rs: -------------------------------------------------------------------------------- 1 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 2 | // , at your 3 | // option. This file may not be copied, modified, or distributed 4 | // except according to those terms. 5 | 6 | #[allow(unused)] 7 | mod error; 8 | #[allow(unused)] 9 | mod format; 10 | #[allow(unused)] 11 | mod path; 12 | 13 | use { 14 | crate::{ 15 | error::Error, 16 | format::{BomBlock, ParsedBom}, 17 | }, 18 | clap::{value_parser, Arg, ArgAction, Command}, 19 | std::path::PathBuf, 20 | }; 21 | 22 | type BomResult = Result; 23 | 24 | fn main_impl() -> BomResult<()> { 25 | let matches = Command::new("Apple BOM Dumper") 26 | .arg_required_else_help(true) 27 | .version("0.1") 28 | .author("Gregory Szorc ") 29 | .about("Show information about Apple BOM data structures") 30 | .arg( 31 | Arg::new("path") 32 | .action(ArgAction::Set) 33 | .value_parser(value_parser!(PathBuf)) 34 | .num_args(1) 35 | .help("Path to BOM file"), 36 | ) 37 | .arg( 38 | Arg::new("action") 39 | .action(ArgAction::Set) 40 | .value_parser([ 41 | "blocks-index", 42 | "blocks", 43 | "bom-info", 44 | "header", 45 | "hl-index", 46 | "paths", 47 | "paths-short", 48 | "vars-index", 49 | "size64", 50 | "v-index", 51 | ]) 52 | .default_value("header") 53 | .help("Which content to show"), 54 | ) 55 | .get_matches(); 56 | 57 | let path = matches 58 | .get_one::("path") 59 | .expect("path should be required"); 60 | let action = matches 61 | .get_one::("action") 62 | .expect("action should be required"); 63 | 64 | let bom_data = std::fs::read(path)?; 65 | let bom = ParsedBom::parse(&bom_data)?; 66 | 67 | match action.as_str() { 68 | "blocks-index" => { 69 | println!("{} total blocks", bom.blocks.count); 70 | for (i, entry) in bom.blocks.blocks.iter().enumerate() { 71 | println!("#{i}: {entry:?}"); 72 | } 73 | } 74 | "blocks" => { 75 | println!("{} total blocks", bom.header.number_of_blocks); 76 | for i in 0..bom.header.number_of_blocks as usize + 1 { 77 | match BomBlock::try_parse(&bom, i) { 78 | Ok(block) => { 79 | println!("#{i}: {block:?}"); 80 | } 81 | Err(_) => { 82 | println!("#{}: (unknown) {}", i, hex::encode(bom.block_data(i)?)); 83 | } 84 | } 85 | } 86 | } 87 | "bom-info" => { 88 | println!("{:#?}", bom.bom_info()?); 89 | } 90 | "header" => { 91 | println!("{:#?}", bom.header); 92 | } 93 | "hl-index" => { 94 | println!("{:#?}", bom.hl_index()?); 95 | } 96 | "paths" => { 97 | println!("{:#?}", bom.paths()?); 98 | } 99 | "paths-short" => { 100 | for path in bom.paths()? { 101 | if let Some(link) = path.link_name() { 102 | println!("{} {} -> {}", path.symbolic_mode(), path.path(), link); 103 | } else { 104 | println!("{} {}", path.symbolic_mode(), path.path()); 105 | } 106 | } 107 | } 108 | "size64" => { 109 | println!("{:#?}", bom.size64()?); 110 | } 111 | "vars-index" => { 112 | println!("{:#?}", bom.vars); 113 | } 114 | "v-index" => { 115 | println!("{:#?}", bom.vindex()?); 116 | } 117 | _ => { 118 | return Err(Error::CliBadArgs(format!("unhandled action: {action}"))); 119 | } 120 | } 121 | 122 | Ok(()) 123 | } 124 | 125 | fn main() { 126 | let exit_code = match main_impl() { 127 | Ok(()) => 0, 128 | Err(err) => { 129 | eprintln!("Error: {err:?}"); 130 | 1 131 | } 132 | }; 133 | 134 | std::process::exit(exit_code) 135 | } 136 | -------------------------------------------------------------------------------- /apple-bom/src/error.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Gregory Szorc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | #[derive(Debug, thiserror::Error)] 10 | pub enum Error { 11 | #[error("(de)serialization error: {0}")] 12 | Scroll(#[from] scroll::Error), 13 | 14 | #[error("unable to parse variable name as UTF-8")] 15 | BadVariableString, 16 | 17 | #[error("bad index into BOM data")] 18 | BadIndex, 19 | 20 | #[error("data type {0} not found")] 21 | NoVar(String), 22 | 23 | #[error("illegal BOM path \"{0}\": {1}")] 24 | BadPath(String, &'static str), 25 | 26 | #[error("I/O error: {0}")] 27 | Io(#[from] std::io::Error), 28 | 29 | #[error("bad arguments: {0}")] 30 | CliBadArgs(String), 31 | 32 | #[error("unknown block type")] 33 | UnknownBlockType, 34 | 35 | #[error("invalid time value")] 36 | BadTime, 37 | } 38 | -------------------------------------------------------------------------------- /apple-bom/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Gregory Szorc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | //! Interact with Apple BOM files. 10 | //! 11 | //! Apple Bill of Materials (BOM) files are a file format / data structure 12 | //! for indexing file content with additional metadata. They are commonly 13 | //! found in flat packages (e.g. `.pkg` files). 14 | //! 15 | //! This crate provides an interface for reading and writing Apple BOM 16 | //! files. 17 | //! 18 | //! The gateway to reading support is [ParsedBom], which provides a read-only 19 | //! interface to a BOM data structure. 20 | //! 21 | //! Writing support is still a work in progress. 22 | 23 | pub mod builder; 24 | pub mod error; 25 | pub use error::Error; 26 | pub mod format; 27 | pub use format::ParsedBom; 28 | pub mod path; 29 | 30 | pub use path::{BomPath, BomPathType}; 31 | -------------------------------------------------------------------------------- /apple-bom/src/testdata/python-applications.bom: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-bom/src/testdata/python-applications.bom -------------------------------------------------------------------------------- /apple-bundles/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # apple-bundles Crate Changelog 2 | 3 | 4 | 5 | ## Unreleased 6 | 7 | Released on ReleaseDate. 8 | 9 | ## 0.21.0 10 | 11 | Released on 2024-11-29. 12 | 13 | ## 0.20.0 14 | 15 | Released on 2024-11-03. 16 | 17 | * `DirectoryBundle::info_plist_path()` now returns the path the instance was 18 | constructed with instead of deriving it at call time. Previously, the 19 | derivation logic could disagree with the constructed value. (#157) 20 | * `plist` 1.6.0 -> 1.7.0. 21 | * `walkdir` 2.4 -> 2.5. 22 | 23 | ## 0.19.0 24 | 25 | Released on 2024-01-17. 26 | 27 | ## 0.18.0 28 | 29 | Released on 2023-11-06. 30 | 31 | * Minimum supported Rust version is now 1.70. 32 | 33 | ## 0.17.0 34 | 35 | Released on 2022-12-21. 36 | 37 | * Cargo.toml now defines patch version for all dependencies. 38 | * Minimum supported Rust version is now 1.65. 39 | 40 | ## 0.16.0 41 | 42 | Released on 2022-12-18. 43 | 44 | * Look for `Info.plist` in correct location in shallow framework bundles. This 45 | fixes an issue where shallow framework bundles weren't correctly identified 46 | as such. (#46) 47 | 48 | ## 0.15.0 49 | 50 | Released on 2022-10-02. 51 | -------------------------------------------------------------------------------- /apple-bundles/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "apple-bundles" 3 | version = "0.21.0" 4 | authors = ["Gregory Szorc "] 5 | edition = "2021" 6 | rust-version = "1.81" 7 | license = "MPL-2.0" 8 | description = "Interface with Apple bundle primitives" 9 | keywords = ["apple", "macos", "bundle", "appbundle"] 10 | homepage = "https://github.com/indygreg/apple-platform-rs" 11 | repository = "https://github.com/indygreg/apple-platform-rs.git" 12 | readme = "README.md" 13 | 14 | [dependencies] 15 | anyhow = "1.0.93" 16 | plist = "1.7.0" 17 | simple-file-manifest = "0.11.0" 18 | walkdir = "2.5.0" 19 | 20 | [dev-dependencies] 21 | tempfile = "3.14.0" 22 | -------------------------------------------------------------------------------- /apple-bundles/README.md: -------------------------------------------------------------------------------- 1 | # apple-bundles 2 | 3 | `apple-bundles` is a library crate implementing functionality related 4 | to Apple *bundles*, a foundational primitive in Apple operating systems for 5 | encapsulating code and resources. (The ``.app`` *directories* in 6 | ``/Applications`` are *application bundles*, for example.) 7 | 8 | `apple-bundles` is part of the 9 | [apple-platform-rs](https://github.com/indygreg/apple-platform-rs) project and this 10 | crate is developed in that repository. 11 | 12 | While this crate is developed as part of a larger project, modifications 13 | to support its use outside of its primary use case are very much welcome! 14 | -------------------------------------------------------------------------------- /apple-bundles/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. 4 | 5 | mod directory_bundle; 6 | pub use directory_bundle::*; 7 | mod macos_application_bundle; 8 | pub use macos_application_bundle::*; 9 | 10 | /// Denotes the type of a bundle. 11 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 12 | pub enum BundlePackageType { 13 | /// Application bundle. 14 | App, 15 | /// Framework bundle. 16 | Framework, 17 | /// Generic bundle. 18 | Bundle, 19 | } 20 | 21 | impl ToString for BundlePackageType { 22 | fn to_string(&self) -> String { 23 | match self { 24 | Self::App => "APPL", 25 | Self::Framework => "FMWK", 26 | Self::Bundle => "BNDL", 27 | } 28 | .to_string() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /apple-codesign/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "apple-codesign" 3 | version = "0.29.0" 4 | authors = ["Gregory Szorc "] 5 | edition = "2021" 6 | rust-version = "1.81" 7 | license = "MPL-2.0" 8 | description = "Pure Rust interface to code signing on Apple platforms" 9 | keywords = ["apple", "macos", "codesign"] 10 | homepage = "https://github.com/indygreg/apple-platform-rs" 11 | repository = "https://github.com/indygreg/apple-platform-rs.git" 12 | readme = "README.md" 13 | 14 | [[bin]] 15 | name = "rcodesign" 16 | path = "src/main.rs" 17 | 18 | [dependencies] 19 | anyhow = "1.0.93" 20 | aws-config = { version = "1.5.10", optional = true } 21 | aws-sdk-s3 = { version = "1.63.0", optional = true } 22 | aws-smithy-http = { version = "0.60.11", optional = true } 23 | aws-smithy-types = { version = "1.2.9", optional = true } 24 | base64 = "0.22.1" 25 | bcder = "0.7.4" 26 | bitflags = "2.6.0" 27 | bytes = "1.9.0" 28 | clap = { version = "4.5.21", features = ["derive"] } 29 | chrono = "0.4.38" 30 | cryptographic-message-syntax = "0.27.0" 31 | der = { version = "0.7.9", features = ["alloc"] } 32 | dialoguer = "0.11.0" 33 | difference = "2.0.0" 34 | digest = "0.10.7" 35 | dirs = "5.0.1" 36 | elliptic-curve = { version = "0.13.8", features = ["arithmetic", "pkcs8"] } 37 | env_logger = "0.11.5" 38 | figment = { version = "0.10.19", features = ["env", "toml"] } 39 | filetime = "0.2.25" 40 | glob = "0.3.1" 41 | goblin = "0.9.2" 42 | hex = "0.4.3" 43 | log = "0.4.22" 44 | md-5 = "0.10.6" 45 | minicbor = { version = "0.25.1", features = ["derive", "std"] } 46 | num-traits = "0.2.19" 47 | object = { version = "0.36.5", features = ["write"] } 48 | oid-registry = "0.7.1" 49 | once_cell = "1.20.2" 50 | p12 = "0.6.3" 51 | p256 = { version = "0.13.2", default-features = false, features = ["arithmetic", "pkcs8", "std"] } 52 | pem = "3.0.4" 53 | pkcs1 = { version = "0.7.5", features = ["alloc", "std", "pkcs8"] } 54 | pkcs8 = { version = "0.10.2", features = ["alloc", "std"] } 55 | plist = "1.7.0" 56 | rand = "0.8.5" 57 | rasn = "0.20.2" 58 | rayon = "1.10.0" 59 | regex = "1.11.1" 60 | reqwest = { version = "0.12.9", default-features = false, features = ["blocking", "http2", "json", "rustls-tls-native-roots"] } 61 | ring = "0.17.8" 62 | rsa = "0.9.7" 63 | scroll = "0.12.0" 64 | sha2 = "0.10.8" 65 | semver = "1.0.23" 66 | serde = { version = "1.0.215", features = ["derive"] } 67 | serde_json = "1.0.133" 68 | serde_yaml = "0.9.34" 69 | signature = { version = "2.2.0", features = ["std"] } 70 | simple-file-manifest = "0.11.0" 71 | spake2 = "0.4.0" 72 | spki = { version = "0.7.3", features = ["pem"] } 73 | subtle = "2.6.1" 74 | tempfile = "3.14.0" 75 | thiserror = "2.0.3" 76 | tokio = { version = "1.41.1", features = ["rt"] } 77 | tungstenite = { version = "0.24.0", features = ["rustls-tls-native-roots"] } 78 | uuid = { version = "1.11.0", features = ["v4"] } 79 | walkdir = "2.5.0" 80 | x509 = "0.2.0" 81 | x509-certificate = "0.24.0" 82 | xml-rs = "0.8.23" 83 | yasna = "0.5.2" 84 | yubikey = { version = "0.8.0", optional = true, features = ["untested"] } 85 | zeroize = { version = "1.8.1", features = ["zeroize_derive"] } 86 | zip = { version = "2.2.1", default-features = false, features = ["deflate"] } 87 | zip_structs = "0.2.1" 88 | 89 | [dependencies.app-store-connect] 90 | path = "../app-store-connect" 91 | version = "0.7.0" 92 | optional = true 93 | 94 | [dependencies.apple-bundles] 95 | path = "../apple-bundles" 96 | version = "0.21.0" 97 | 98 | [dependencies.apple-flat-package] 99 | path = "../apple-flat-package" 100 | version = "0.20.0" 101 | 102 | [dependencies.apple-xar] 103 | path = "../apple-xar" 104 | version = "0.20.0" 105 | 106 | [target.'cfg(target_os = "macos")'.dependencies] 107 | security-framework = { version = "2.11.1", features = ["OSX_10_12"] } 108 | security-framework-sys = { version = "2.12.1", features = ["OSX_10_12"] } 109 | 110 | [target.'cfg(target_os = "windows")'.dependencies] 111 | widestring = { version = "1.1.0" } 112 | windows-sys = { version = "0.59.0", features = ["Win32_Foundation", "Win32_Security_Cryptography"] } 113 | 114 | [dev-dependencies] 115 | flate2 = "1.0.35" 116 | indoc = "2.0.5" 117 | simple-file-manifest = "0.11.0" 118 | tar = "0.4.43" 119 | trycmd-indygreg-fork = "0.14.20" 120 | zip = { version = "2.2.1", default-features = false } 121 | 122 | [features] 123 | default = ["notarize"] 124 | notarize = [ 125 | "app-store-connect", 126 | "aws-config", 127 | "aws-sdk-s3", 128 | "aws-smithy-http", 129 | "aws-smithy-types", 130 | ] 131 | smartcard = ["yubikey"] 132 | -------------------------------------------------------------------------------- /apple-codesign/README.md: -------------------------------------------------------------------------------- 1 | # apple-codesign 2 | 3 | `apple-codesign` is a crate implementing functionality related to code signing 4 | on Apple platforms. 5 | 6 | All functionality is implemented in pure Rust and doesn't require any 3rd party 7 | or proprietary software nor do we require running on Apple platforms. 8 | 9 | We believe this crate provides the most comprehensive implementation of Apple 10 | code signing outside the canonical Apple tools. We have support for the following 11 | features: 12 | 13 | * Signing Mach-O binaries (the executable file format on Apple operating systems). 14 | * Signing, notarizing, and stapling directory bundles (e.g. `.app` directories). 15 | * Signing, notarizing, and stapling XAR archives / `.pkg` installers. 16 | * Signing, notarizing, and stapling DMG disk images. 17 | 18 | What this all means is that you can sign, notarize, and release Apple software 19 | from anywhere you can get the Rust crate to compile. Linux, Windows, and macOS 20 | are officially supported by other operating systems (like BSDs) should work as 21 | well. 22 | 23 | See the crate documentation at https://docs.rs/apple-codesign/latest/apple_codesign/ 24 | and the end-user documentation at 25 | https://gregoryszorc.com/docs/apple-codesign/main/ for more. 26 | 27 | # `rcodesign` CLI 28 | 29 | This crate defines an `rcodesign` binary which provides a CLI interface to 30 | some of the crate's capabilities. To install: 31 | 32 | ```bash 33 | # From a Git checkout 34 | $ cargo run --bin rcodesign -- --help 35 | $ cargo install --bin rcodesign 36 | 37 | # Remote install. 38 | $ cargo install --git https://github.com/indygreg/apple-platform-rs --branch main --bin rcodesign apple-codesign 39 | ``` 40 | -------------------------------------------------------------------------------- /apple-codesign/docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= -W -n 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /apple-codesign/docs/apple_codesign.rst: -------------------------------------------------------------------------------- 1 | .. _apple_codesign: 2 | 3 | ================== 4 | Apple Code Signing 5 | ================== 6 | 7 | The ``apple-codesign`` Rust crate and its corresponding ``rcodesign`` CLI 8 | tool implement code signing for Apple platforms. 9 | 10 | We believe this crate provides the most comprehensive implementation of Apple 11 | code signing outside the canonical Apple tools. We have support for the following 12 | features: 13 | 14 | * Signing Mach-O binaries (the executable file format on Apple operating systems). 15 | * Signing, notarizing, and stapling directory bundles (e.g. ``.app`` directories). 16 | * Signing, notarizing, and stapling XAR archives / ``.pkg`` installers. 17 | * Signing, notarizing, and stapling disk images / ``.dmg`` files. 18 | * Notarizing zip files. 19 | 20 | **What this all means is that you can sign, notarize, and release Apple software 21 | from non-Apple operating systems (like Linux, Windows, and BSDs) without needing 22 | access to proprietary Apple software!** 23 | 24 | Other features include: 25 | 26 | * Built-in support for using :ref:`smart cards ` (e.g. 27 | YubiKeys) for signing and key/certificate management. 28 | * A *remote signing* mode that enables you to delegate just the low-level 29 | cryptographic signature generation to a remote machine. This allows you to 30 | do things like have a CI job initiate signing but use a YubiKey on a remote 31 | machine to create cryptographic signatures. See 32 | :ref:`apple_codesign_remote_signing` for more. 33 | * Certificate Signing Request (CSR) support to enable arbitrary private keys 34 | (including those generated on smart card devices) to be easily exchanged for 35 | Apple-issued code signing certificates. 36 | * Support for dumping and diffing data structures related to Apple code 37 | signatures. 38 | * Awareness of Apple's public PKI infrastructure, including CA certificates 39 | and custom X.509 extensions and OIDs used by Apple. 40 | * Documentation and code that are likely a treasure trove for others wanting 41 | to learn and experiment with Apple code signing. 42 | 43 | Canonical project links: 44 | 45 | * Source code: https://github.com/indygreg/apple-platform-rs/tree/main/apple-codesign 46 | * Documentation https://gregoryszorc.com/docs/apple-codesign/ 47 | * Rust crate: https://crates.io/crates/apple-codesign 48 | * Changelog: https://github.com/indygreg/apple-platform-rs/blob/main/apple-codesign/CHANGELOG.rst 49 | * Bugs and feature requests: https://github.com/indygreg/apple-platform-rs/issues?q=is%3Aopen+is%3Aissue+label%3Aapple-codesign 50 | 51 | While this project is developed inside a larger monorepository, it is designed 52 | to be used as a standalone project. 53 | 54 | .. toctree:: 55 | :maxdepth: 2 56 | 57 | apple_codesign_getting_started 58 | apple_codesign_rcodesign 59 | apple_codesign_certificate_management 60 | apple_codesign_smartcard 61 | apple_codesign_github_actions 62 | apple_codesign_concepts 63 | apple_codesign_quirks 64 | apple_codesign_debugging 65 | apple_codesign_remote_signing 66 | apple_codesign_remote_signing_protocol 67 | apple_codesign_remote_signing_design 68 | apple_codesign_gatekeeper 69 | apple_codesign_custom_assessment_policies 70 | apple_codesign_developer_guide 71 | -------------------------------------------------------------------------------- /apple-codesign/docs/apple_codesign_actions_initiator_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/docs/apple_codesign_actions_initiator_output.png -------------------------------------------------------------------------------- /apple-codesign/docs/apple_codesign_actions_signer_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/docs/apple_codesign_actions_signer_output.png -------------------------------------------------------------------------------- /apple-codesign/docs/apple_codesign_actions_sjs_join.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/docs/apple_codesign_actions_sjs_join.png -------------------------------------------------------------------------------- /apple-codesign/docs/apple_codesign_debugging.rst: -------------------------------------------------------------------------------- 1 | .. _apple_codesign_debugging: 2 | 3 | ================================ 4 | How to Debug and Report Problems 5 | ================================ 6 | 7 | Apple code signing is complex and there will be cases where this tool 8 | behaves differently from Apple's, possibly to the point where Apple rejects 9 | the output of this tool. 10 | 11 | .. important:: 12 | 13 | If Apple software rejects the output of this tool, we consider that a bug. 14 | We encourage end-users to report these bugs to the 15 | `GitHub issue tracker `_. 16 | 17 | Commands to Print Signature Info 18 | ================================ 19 | 20 | The ``rcodesign print-signature-info`` command can be used to dump YAML 21 | describing any signable file entity. Just point it at a Mach-O, bundle, DMG, 22 | or ``.pkg`` installer and it will tell you what it knows about the entity. 23 | 24 | The ``rcodesign diff-signatures`` command will internally execute 25 | ``print-signature-info`` against 2 paths and print the differences between them. 26 | 27 | ``rcodesign diff-signatures`` is exceptionally useful at understanding 28 | differences in behavior between this tool and Apple's. If Apple is rejecting 29 | the output of this tool, comparing the output of the same operation with Apple's 30 | tooling against this tool's is a good way to find the source of the problem. 31 | 32 | Reporting Actionable Bugs 33 | ========================= 34 | 35 | Please include the following in bug reports to improve chances for action: 36 | 37 | * The released version or Git commit that this tool was built from. 38 | * The command line used. 39 | * The full output of the command. 40 | * The output of ``rcodesign diff-signatures`` comparing similar operations 41 | between Apple's tooling and ours. 42 | * A copy of the entity you were attempting to sign. 43 | * Text copy or screenshot of error from Apple tooling indicating what failed. 44 | 45 | It is understandable that some people may not desire to file publish issue 46 | reports or submit a copy of their application to be seen by the world. If 47 | you send a polite email to gregory.szorc@gmail.com with ``apple-codesign`` or 48 | ``rcodesign`` in the subject line along with more private/sensitive details, 49 | support can be given over email. 50 | -------------------------------------------------------------------------------- /apple-codesign/docs/apple_codesign_developer_guide.rst: -------------------------------------------------------------------------------- 1 | .. _apple_codesign_developer_guide: 2 | 3 | =============== 4 | Developer Guide 5 | =============== 6 | 7 | If you are familiar with Rust, hacking on the ``apple-codesign`` crate should 8 | feel like any other Rust crate. But there are a few things to watch out for: 9 | 10 | * The ``smartcard`` crate feature isn't enabled by default because it pulls in 11 | library dependencies on Linux that aren't always present. We recommend testing 12 | with ``--all-features`` to ensure all code in the crate is exercised. 13 | * There is some conditional code when running on macOS. We've tried to isolate 14 | that code to the ``macos`` file/module so changes are more obvious. 15 | * When running tests on macOS, some tests call out to Apple tools (like 16 | ``csreq``). Non-standard system installs or 3rd party tools on PATH may 17 | confuse tests. (We generally consider these bugs in the tests and if you 18 | see a test failure due to a runtime environment issue, please file a bug or 19 | send a patch to fix.) 20 | 21 | Desire for Determinism and Reproducibility 22 | ========================================== 23 | 24 | As much code and behavior should be deterministic and bit-for-bit reproducible as 25 | possible. There are some obvious cases where bits will disagree (such as time-stamp 26 | tokens from remote timestamp servers). But we strive for the same data inputs to 27 | produce the same output as much as possible. Unless it can't be avoided due to the 28 | fundamental nature of an operation (such as a random/remote operation), we consider 29 | non-determinism to be a bug. 30 | 31 | Desire for Compliance with Apple Tooling 32 | ======================================== 33 | 34 | We bias towards Apple's official tooling to define behavior. 35 | 36 | Generally, if our implementation behaves differently from Apple's official 37 | tooling in a meaningful way (definition of *meaningful* is subject to 38 | interpretation), the default behavior should be to treat this as a bug. 39 | If deviation is desirable, the justifications should be documented. Ideally 40 | in this documentation tree or in inline code comments. But commit messages 41 | are also fine. The important thing is we leave a breadcrumb trail of known 42 | deviations and why they exist. 43 | 44 | There are plenty of valid reasons to deviate from behavior of Apple's tooling. 45 | We purposefully let present and future project maintainers interpret *valid 46 | reasons* as they want. 47 | -------------------------------------------------------------------------------- /apple-codesign/docs/apple_codesign_getting_started.rst: -------------------------------------------------------------------------------- 1 | .. _apple_codesign_getting_started: 2 | 3 | =============== 4 | Getting Started 5 | =============== 6 | 7 | Installing 8 | ========== 9 | 10 | Pre-built binaries are published as GitHub Releases. Go to 11 | https://github.com/indygreg/apple-platform-rs/releases and look for the latest 12 | release of ``Apple Codesign``. 13 | 14 | To install the latest release version of the ``rcodesign`` executable using Cargo 15 | (Rust's package manager): 16 | 17 | .. code-block:: bash 18 | 19 | cargo install apple-codesign 20 | 21 | To enable smart card integration (i.e. use a YubiKey for signing): 22 | 23 | .. code-block:: bash 24 | 25 | cargo install --features smartcard apple-codesign 26 | 27 | To compile and run from a Git checkout of its canonical repository (developer mode): 28 | 29 | .. code-block:: bash 30 | 31 | cargo run --bin rcodesign -- --help 32 | 33 | To install from a Git checkout of its canonical repository: 34 | 35 | .. code-block:: bash 36 | 37 | cargo install --bin rcodesign 38 | 39 | To install from the latest commit in the canonical Git repository: 40 | 41 | .. code-block:: bash 42 | 43 | cargo install --git https://github.com/indygreg/apple-platform-rs --branch main rcodesign 44 | 45 | Obtaining a Code Signing Certificate 46 | ==================================== 47 | 48 | Follow the instructions at :ref:`apple_codesign_certificate_management` to obtain 49 | a code signing certificate. This is required if signing software for 50 | distribution to other machines. 51 | 52 | If you just want to play around, you can use 53 | ``rcodesign generate-self-signed-certificate`` to create a self-signed 54 | certificate. 55 | 56 | .. _apple_codesign_app_store_connect_api_key: 57 | 58 | Obtaining an App Store Connect API Key 59 | ====================================== 60 | 61 | To notarize and staple, you'll need an App Store Connect API Key to 62 | authenticate connections to Apple's servers. 63 | 64 | You can generate one at https://appstoreconnect.apple.com/access/api. 65 | 66 | This requires joining the Apple Developer Program, which has an annual 67 | fee. 68 | 69 | See 70 | https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api 71 | for Apple's official documentation on creating these API Keys. 72 | 73 | .. important:: 74 | 75 | For the *Access Role*, ``Developer`` should be sufficient. 76 | 77 | Other roles may or may not work for notarization. 78 | 79 | App Store Connect API Keys have 3 components: 80 | 81 | * An *Issuer ID* (likely a UUID). 82 | * A *Key ID* (an alphanumeric string like ``DEADBEEF42``). 83 | * A PEM encoded ECDSA private key (a file beginning with 84 | ``-----BEGIN PRIVATE KEY-----`` that you can download at most 85 | once when you create an API Key). 86 | 87 | All 3 of these components are required to talk to the App Store Connect 88 | API server. To make management of these keys simpler, we provide the 89 | ``encode-app-store-connect-api-key`` command to write out a JSON document 90 | holding all the key info. 91 | 92 | .. important:: 93 | 94 | We highly recommend using our JSON keys created with 95 | ``encode-app-store-connect-api-key`` as it is simpler to manage a single 96 | entity instead of 3. 97 | 98 | You can perform an encode of your key as follows: 99 | 100 | .. code-block:: bash 101 | 102 | rcodesign encode-app-store-connect-api-key -o ~/.appstoreconnect/key.json \ 103 | /path/to/downloaded/private_key 104 | 105 | e.g. 106 | 107 | .. code-block:: bash 108 | 109 | rcodesign encode-app-store-connect-api-key -o ~/.appstoreconnect/key.json \ 110 | 11dda589-8632-49a8-a432-03b5e17fe1d2 DEADBEEF42 ~/Downloads/AuthKey_DEADBEAF42.p8 111 | 112 | Next Steps 113 | ========== 114 | 115 | Once you have a code signing certificate and/or App Store Connect API Key, 116 | read :ref:`apple_codesign_rcodesign` to learn how to sign and/or notarize 117 | software. 118 | -------------------------------------------------------------------------------- /apple-codesign/docs/apple_codesign_rcodesign.rst: -------------------------------------------------------------------------------- 1 | .. _apple_codesign_rcodesign: 2 | 3 | =================== 4 | Using ``rcodesign`` 5 | =================== 6 | 7 | The ``rcodesign`` executable provided by this project provides a command 8 | mechanism to interact with Apple code signing. 9 | 10 | .. toctree:: 11 | :maxdepth: 2 12 | 13 | apple_codesign_rcodesign_signing 14 | apple_codesign_rcodesign_notarizing 15 | apple_codesign_rcodesign_config_files 16 | apple_codesign_settings_scope 17 | -------------------------------------------------------------------------------- /apple-codesign/docs/apple_codesign_rcodesign_signing.rst: -------------------------------------------------------------------------------- 1 | .. _apple_codesign_rcodesign_signing: 2 | 3 | =============================== 4 | Signing with ``rcodesign sign`` 5 | =============================== 6 | 7 | The ``rcodesign sign`` command is used to sign a filesystem path. 8 | 9 | If you simply ``rcodesign sign ``, it will attempt to create an ad-hoc 10 | signature (read: no code signing certificate), rewriting the file/directory 11 | in place. Arguments like ``--p12-file``, ``pem-file``, and ``--smartcard-slot`` 12 | can be used to sign with a code signing certificate/key. 13 | 14 | Nested Signing By Default 15 | ========================= 16 | 17 | One of the areas where ``rcodesign sign`` varies from Apple's ``codesign`` is 18 | that we recursively sign entities by default. e.g. if you sign a bundle, we'll 19 | recursively sign nested bundles/frameworks and Mach-O binaries inside that bundle 20 | unless told otherwise. 21 | 22 | Unlike Apple's ``codesign``, ``rcodesign`` has a signing settings mechanism 23 | that allows you to scope settings to particular paths. This gives you low-level 24 | control over how every binary, bundle, and even individual Macho-O within a 25 | universal Macho-O binary are signed. Whereas ``codesign`` requires N invocations 26 | with N different settings configurations, ``rcodesign`` can perform the same 27 | operation in a single invocation. 28 | 29 | Simple Examples 30 | =============== 31 | 32 | To sign a Mach-O executable:: 33 | 34 | rcodesign sign \ 35 | --p12-file developer-id.p12 --p12-password-file ~/.certificate-password \ 36 | --code-signature-flags runtime \ 37 | path/to/executable 38 | 39 | To sign an ``.app`` bundle (and all Mach-O binaries inside):: 40 | 41 | rcodesign sign \ 42 | --p12-file developer-id.p12 --p12-password-file ~/.certificate-password \ 43 | path/to/My.app 44 | 45 | To sign a DMG image:: 46 | 47 | rcodesign sign \ 48 | --p12-file developer-id.p12 --p12-password-file ~/.certificate-password \ 49 | path/to/app.dmg 50 | 51 | To sign a ``.pkg`` installer:: 52 | 53 | rcodesign sign \ 54 | --p12-file developer-id-installer.p12 --p12-password-file ~/.certificate-password \ 55 | path/to/installer.pkg -------------------------------------------------------------------------------- /apple-codesign/docs/apple_codesign_settings_scope.rst: -------------------------------------------------------------------------------- 1 | .. _apple_codesign_settings_scope: 2 | 3 | =============== 4 | Settings Scopes 5 | =============== 6 | 7 | Various signing settings and configuration settings can be *scoped* to a 8 | specific path or pattern. This is accomplished using a mini language/syntax, 9 | which is described by this document. 10 | 11 | A *scoping string* is syntax that denotes a path or entity to apply 12 | a setting to. 13 | 14 | The following *scoping string* syntax is defined: 15 | 16 | ```` 17 | e.g. ``path/to.file``. Applies to content at a given path. 18 | 19 | This is probably the most common scoping syntax. 20 | 21 | The string is a bundle-relative path to a signable entity (a Mach-O 22 | binary, a nested bundle, etc). e.g. ``Contents/MacOS/extra-bin``. 23 | 24 | If the path belongs to a nested bundle, settings with this scope will 25 | apply to all signable entities in the bundle. 26 | 27 | ``main`` 28 | Applies to the main entity being signed and to nested/children entities. 29 | 30 | ``@`` 31 | e.g. ``@0`` or ``@1``. Applies to Mach-O binaries within a universal/fat 32 | binary at the specified index. ``0`` means the first Mach-O in a universal 33 | binary. 34 | 35 | ``@[cpu_type=]`` 36 | e.g. ``@[cpu_type=7]``. Applies to a Mach-O within a universal binary targeting 37 | a numbered CPU architecture, using the numeric constants as defined by Mach-O. 38 | 39 | ``@[cpu_type=]`` 40 | e.g. ``@[cpu_type=x86_64]``. Applies to a Mach-O within a universal binary 41 | targeting a CPU architecture identified by a string. See below for the set of 42 | recognized architecture names. 43 | 44 | ``@`` ``@[cpu_type=]`` 45 | These syntax are an extension of the ```` and various ``@*`` syntax 46 | above. They allow you to target a specified Mach-O binary within a universal 47 | Mach-O at a given path. 48 | 49 | Like the ```` syntax, if the path matches a bundle, the setting applies 50 | to all Mach-O binaries in that bundle. 51 | 52 | Architecture Names 53 | ------------------ 54 | 55 | * ``arm`` 56 | * ``arm64`` 57 | * ``arm64_32`` 58 | * ``x86_64`` 59 | -------------------------------------------------------------------------------- /apple-codesign/docs/conf.py: -------------------------------------------------------------------------------- 1 | # This Source Code Form is subject to the terms of the Mozilla Public 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this 3 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 4 | 5 | import os 6 | import pathlib 7 | import re 8 | 9 | HERE = pathlib.Path(os.path.dirname(__file__)) 10 | ROOT = pathlib.Path(os.path.dirname(HERE)) 11 | 12 | release = "unknown" 13 | 14 | with (ROOT / "Cargo.toml").open("r") as fh: 15 | for line in fh: 16 | m = re.match('^version = "([^"]+)"', line) 17 | if m: 18 | release = m.group(1) 19 | break 20 | 21 | 22 | project = "Apple Codesign" 23 | copyright = "2022, Gregory Szorc" 24 | author = "Gregory Szorc" 25 | extensions = ["sphinx.ext.intersphinx"] 26 | templates_path = ["_templates"] 27 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] 28 | html_theme = "alabaster" 29 | master_doc = "index" 30 | intersphinx_mapping = { 31 | "python": ("https://docs.python.org/3", None), 32 | "setuptools": ("https://setuptools.pypa.io/en/latest", None), 33 | } 34 | tags.add("apple_codesign") 35 | -------------------------------------------------------------------------------- /apple-codesign/docs/index.rst: -------------------------------------------------------------------------------- 1 | ================== 2 | Apple Code Signing 3 | ================== 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | apple_codesign 9 | -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleAAI2CA.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleAAI2CA.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleAAICA.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleAAICA.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleAAICAG3.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleAAICAG3.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleApplicationIntegrationCA5G1.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleApplicationIntegrationCA5G1.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleApplicationIntegrationCA7G1.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleApplicationIntegrationCA7G1.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleComputerRootCertificate.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleComputerRootCertificate.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleISTCA2G1.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleISTCA2G1.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleISTCA8G1.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleISTCA8G1.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleIncRootCertificate.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleIncRootCertificate.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleRootCA-G2.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleRootCA-G2.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleRootCA-G3.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleRootCA-G3.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleSoftwareUpdateCertificationAuthority.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleSoftwareUpdateCertificationAuthority.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleTimestampCA.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleTimestampCA.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleWWDRCA.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleWWDRCA.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleWWDRCAG2.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleWWDRCAG2.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleWWDRCAG3.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleWWDRCAG3.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleWWDRCAG4.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleWWDRCAG4.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleWWDRCAG5.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleWWDRCAG5.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleWWDRCAG6.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleWWDRCAG6.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleWWDRCAG7.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleWWDRCAG7.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/AppleWWDRCAG8.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/AppleWWDRCAG8.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/DevAuthCA.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/DevAuthCA.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/DeveloperIDCA.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/DeveloperIDCA.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-certs/DeveloperIDG2CA.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-certs/DeveloperIDG2CA.cer -------------------------------------------------------------------------------- /apple-codesign/src/apple-codesign-testuser.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/apple-codesign-testuser.p12 -------------------------------------------------------------------------------- /apple-codesign/src/entitlements.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. 4 | 5 | /*! Code entitlements handling. */ 6 | 7 | use {crate::code_directory::ExecutableSegmentFlags, plist::Value}; 8 | 9 | /// Convert an entitlements plist to [ExecutableSegmentFlags]. 10 | /// 11 | /// Some entitlements plist values imply features in executable segment flags. 12 | /// This function resolves those implied features. 13 | pub fn plist_to_executable_segment_flags(value: &Value) -> ExecutableSegmentFlags { 14 | let mut flags = ExecutableSegmentFlags::empty(); 15 | 16 | if let Value::Dictionary(d) = value { 17 | if matches!(d.get("get-task-allow"), Some(Value::Boolean(true))) { 18 | flags |= ExecutableSegmentFlags::ALLOW_UNSIGNED; 19 | } 20 | if matches!(d.get("run-unsigned-code"), Some(Value::Boolean(true))) { 21 | flags |= ExecutableSegmentFlags::ALLOW_UNSIGNED; 22 | } 23 | if matches!( 24 | d.get("com.apple.private.cs.debugger"), 25 | Some(Value::Boolean(true)) 26 | ) { 27 | flags |= ExecutableSegmentFlags::DEBUGGER; 28 | } 29 | if matches!(d.get("dynamic-codesigning"), Some(Value::Boolean(true))) { 30 | flags |= ExecutableSegmentFlags::JIT; 31 | } 32 | if matches!( 33 | d.get("com.apple.private.skip-library-validation"), 34 | Some(Value::Boolean(true)) 35 | ) { 36 | flags |= ExecutableSegmentFlags::SKIP_LIBRARY_VALIDATION; 37 | } 38 | if matches!( 39 | d.get("com.apple.private.amfi.can-load-cdhash"), 40 | Some(Value::Boolean(true)) 41 | ) { 42 | flags |= ExecutableSegmentFlags::CAN_LOAD_CD_HASH; 43 | } 44 | if matches!( 45 | d.get("com.apple.private.amfi.can-execute-cdhash"), 46 | Some(Value::Boolean(true)) 47 | ) { 48 | flags |= ExecutableSegmentFlags::CAN_EXEC_CD_HASH; 49 | } 50 | } 51 | 52 | flags 53 | } 54 | -------------------------------------------------------------------------------- /apple-codesign/src/main.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. 4 | 5 | use apple_codesign::AppleCodesignError; 6 | 7 | fn main() { 8 | let exit_code = match apple_codesign::cli::main_impl() { 9 | Ok(()) => 0, 10 | Err(AppleCodesignError::Figment(err)) => { 11 | eprintln!("configuration file error"); 12 | 13 | err.metadata.as_ref().map(|metadata| { 14 | metadata.source.as_ref().map(|source| { 15 | source.file_path().map(|path| { 16 | eprintln!(" source path: {}", path.display()); 17 | }) 18 | }) 19 | }); 20 | if let Some(profile) = err.profile.as_ref() { eprintln!(" in profile: {}", profile) } 21 | eprintln!(" problem key: {}", err.path.join(", ")); 22 | eprintln!(" problem: {:?}", err.kind); 23 | 24 | 1 25 | } 26 | Err(err) => { 27 | eprintln!("Error: {err}"); 28 | 1 29 | } 30 | }; 31 | 32 | std::process::exit(exit_code) 33 | } 34 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/apple-signed-3rd-party-mac.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/apple-signed-3rd-party-mac.cer -------------------------------------------------------------------------------- /apple-codesign/src/testdata/apple-signed-apple-development.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/apple-signed-apple-development.cer -------------------------------------------------------------------------------- /apple-codesign/src/testdata/apple-signed-apple-distribution.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/apple-signed-apple-distribution.cer -------------------------------------------------------------------------------- /apple-codesign/src/testdata/apple-signed-developer-id-application.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/apple-signed-developer-id-application.cer -------------------------------------------------------------------------------- /apple-codesign/src/testdata/apple-signed-developer-id-application.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFpjCCBI6gAwIBAgIIfTmR3fnRGfowDQYJKoZIhvcNAQELBQAweTEtMCsGA1UE 3 | AwwkRGV2ZWxvcGVyIElEIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSYwJAYDVQQL 4 | DB1BcHBsZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUg 5 | SW5jLjELMAkGA1UEBhMCVVMwHhcNMjEwNDIyMDEwODMyWhcNMjYwNDIzMDEwODMx 6 | WjCBlTEaMBgGCgmSJomT8ixkAQEMCk1LMjJNWlA5ODcxPTA7BgNVBAMMNERldmVs 7 | b3BlciBJRCBBcHBsaWNhdGlvbjogR3JlZ29yeSBTem9yYyAoTUsyMk1aUDk4Nykx 8 | EzARBgNVBAsMCk1LMjJNWlA5ODcxFjAUBgNVBAoMDUdyZWdvcnkgU3pvcmMxCzAJ 9 | BgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs52TZuX8 10 | /9SVXNBr6Vz5CZOmis3lCpRsSP6pKPnIfK46DlOSoob6u/wALiPKOZJOYKnnbHuJ 11 | 1pjvFEHif/eJkdfovu82bwAMJnFrbCGBHmOsqfuURfc5cfaIcpred9P0mFUVpu19 12 | 4n74ZR2sjxJIFIMxJXgh7dSE4dKKokf/o5Orlb3d84i1/yY/ePSdnFIMotxrv0lv 13 | uZjdlIZE6ugoElueSyH1ZwF03UqQznJ1uuw1DSRyC0YD2l7paO+CKKpHAvsTSAZc 14 | j4X6qwx+aVgxiYcfl1z6nVDVv1m6+ChAOGyo06KpGPxFeON/Dp704UJyfyrRF7xD 15 | If/Cu+2ftMlLswIDAQABo4ICEzCCAg8wDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAW 16 | gBRXF+2iz9x8mKEQ4Py+hy0s8uMXVDBABggrBgEFBQcBAQQ0MDIwMAYIKwYBBQUH 17 | MAGGJGh0dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3NwMDMtZGV2aWQwNjCCAR0GA1Ud 18 | IASCARQwggEQMIIBDAYJKoZIhvdjZAUBMIH+MIHDBggrBgEFBQcCAjCBtgyBs1Jl 19 | bGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMg 20 | YWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1z 21 | IGFuZCBjb25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBj 22 | ZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMDYGCCsGAQUFBwIBFipo 23 | dHRwOi8vd3d3LmFwcGxlLmNvbS9jZXJ0aWZpY2F0ZWF1dGhvcml0eS8wFgYDVR0l 24 | AQH/BAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFJWxErKAkOUMhUHKIfurpWswr6OM 25 | MA4GA1UdDwEB/wQEAwIHgDAfBgoqhkiG92NkBgEhBBEMDzIwMjEwNDIyMDAwMDAw 26 | WjATBgoqhkiG92NkBgENAQH/BAIFADANBgkqhkiG9w0BAQsFAAOCAQEAGpHZefiX 27 | l5n79MZM8GFVs5oGJOdspORMFa9SxWa59LaBAWpkUbVtgic25CQtaIZddb7vgMpq 28 | uCqQIFiYz3MfdaPgKMqM1MGNVOw14Z4nM1z9CgLctBS7ie2ScKf9nJnbLCm2qCeS 29 | 5A13mUagb7lwdzI3Z5G6JP3+ea46Kg0bY9c4TCAZr8v/vpBWktnBimuQ9Rz3PPTT 30 | HPCYuazSBKos0g3gNLgzGdQyZLDvyfyqJ3SvIAvGBYC1SxoGUB8RBeZuYLRQOylA 31 | 72DfBd+bt1wASaSNTosSAauo3Sd3cvIwAtlTtWAT3ISZ36ygnbgwfaarz8Q04MDc 32 | 4Y74EVg2IvFyLA== 33 | -----END CERTIFICATE----- 34 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/apple-signed-developer-id-installer.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/apple-signed-developer-id-installer.cer -------------------------------------------------------------------------------- /apple-codesign/src/testdata/ed25519.pk8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/ed25519.pk8 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/rsa-2048.pk8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/rsa-2048.pk8 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/secp256r1.pk8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/secp256r1.pk8 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-ed25519-apple-development.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/self-signed-ed25519-apple-development.p12 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-ed25519-apple-development.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MFECAQEwBQYDK2VwBCIEIGuXFvz4GG/f9X29/6FpMjDQ9RDghIoEP03sLYZ8lVsI 3 | gSEAflskRT0YQlTWM3izqmpkSzvrb3sTtRm8O2nhm0rTqao= 4 | -----END PRIVATE KEY----- 5 | -----BEGIN CERTIFICATE----- 6 | MIICQTCCAfGgAwIBAgIBATAHBgMrZXAFADCBlDEUMBIGCgmSJomT8ixkAQEMBHRl 7 | c3QxPDA6BgNVBAMMM0FwcGxlIERldmVsb3BtZW50OiBFRDI1NTE5IEFwcGxlIERl 8 | dmVsb3BtZW50ICh0ZXN0KTENMAsGA1UECwwEdGVzdDEiMCAGA1UECgwZRUQyNTUx 9 | OSBBcHBsZSBEZXZlbG9wbWVudDELMAkGA1UEBhMCVVMwHhcNMjMxMTA1MDM1NzE2 10 | WhcNMjMxMTA2MDM1NzE2WjCBlDEUMBIGCgmSJomT8ixkAQEMBHRlc3QxPDA6BgNV 11 | BAMMM0FwcGxlIERldmVsb3BtZW50OiBFRDI1NTE5IEFwcGxlIERldmVsb3BtZW50 12 | ICh0ZXN0KTENMAsGA1UECwwEdGVzdDEiMCAGA1UECgwZRUQyNTUxOSBBcHBsZSBE 13 | ZXZlbG9wbWVudDELMAkGA1UEBhMCVVMwLDAHBgMrZW4FAAMhAH5bJEU9GEJU1jN4 14 | s6pqZEs76297E7UZvDtp4ZtK06mqo2IwYDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB 15 | /wQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDATBgoqhkiG92NkBgECAQH/ 16 | BAIFADATBgoqhkiG92NkBgEMAQH/BAIFADAHBgMrZXAFAANBAOF5ePNwa4MrpHHP 17 | bGD5B2xJNw24F+skkT7LRQyN6eNWkBvDBFzpk81p5Fj0OL4fcqNj8amfIQ0Tfn48 18 | E0uu1g4= 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-ed25519-apple-distribution.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/self-signed-ed25519-apple-distribution.p12 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-ed25519-apple-distribution.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MFECAQEwBQYDK2VwBCIEIAz5g02pu9pb7fV8NrPFAwIn3MVKrpfR/vXtYLFcpQPU 3 | gSEA9bMDV9wcZ9Q8+RCBUU5sx4i/qIlI1kCSYDiR1FVzV5w= 4 | -----END PRIVATE KEY----- 5 | -----BEGIN CERTIFICATE----- 6 | MIICRzCCAfegAwIBAgIBATAHBgMrZXAFADCBlzEUMBIGCgmSJomT8ixkAQEMBHRl 7 | c3QxPjA8BgNVBAMMNUFwcGxlIERpc3RyaWJ1dGlvbjogRUQyNTUxOSBBcHBsZSBE 8 | aXN0cmlidXRpb24gKHRlc3QpMQ0wCwYDVQQLDAR0ZXN0MSMwIQYDVQQKDBpFRDI1 9 | NTE5IEFwcGxlIERpc3RyaWJ1dGlvbjELMAkGA1UEBhMCVVMwHhcNMjMxMTA1MDM1 10 | NjQ5WhcNMjMxMTA2MDM1NjQ5WjCBlzEUMBIGCgmSJomT8ixkAQEMBHRlc3QxPjA8 11 | BgNVBAMMNUFwcGxlIERpc3RyaWJ1dGlvbjogRUQyNTUxOSBBcHBsZSBEaXN0cmli 12 | dXRpb24gKHRlc3QpMQ0wCwYDVQQLDAR0ZXN0MSMwIQYDVQQKDBpFRDI1NTE5IEFw 13 | cGxlIERpc3RyaWJ1dGlvbjELMAkGA1UEBhMCVVMwLDAHBgMrZW4FAAMhAPWzA1fc 14 | HGfUPPkQgVFObMeIv6iJSNZAkmA4kdRVc1eco2IwYDAMBgNVHRMBAf8EAjAAMBYG 15 | A1UdJQEB/wQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDATBgoqhkiG92Nk 16 | BgEHAQH/BAIFADATBgoqhkiG92NkBgEEAQH/BAIFADAHBgMrZXAFAANBAMB8826I 17 | 1NnbGubUz6vpEFVN0hNXIJ2e6c4tDIll+2McKJWfq5JFIa7xMeAFWqa/zZu1Hioo 18 | qFmgQ0yuVqLhEg8= 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-ed25519-developer-id-application.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/self-signed-ed25519-developer-id-application.p12 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-ed25519-developer-id-application.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MFECAQEwBQYDK2VwBCIEIKXbW6yNNNbWyegF2dAlZRS6lHhn/W9fGHbbD2ER0VkH 3 | gSEA4jK8Um/Ky41zVRrhyqCzaPrdMJyKIQnqiw8RWu02/ro= 4 | -----END PRIVATE KEY----- 5 | -----BEGIN CERTIFICATE----- 6 | MIICVjCCAgagAwIBAgIBATAHBgMrZXAFADCBqTEUMBIGCgmSJomT8ixkAQEMBHRl 7 | c3QxSjBIBgNVBAMMQURldmVsb3BlciBJRCBBcHBsaWNhdGlvbjogRUQyNTUxOSBE 8 | ZXZlbG9wZXIgSUQgQXBwbGljYXRpb24gKHRlc3QpMQ0wCwYDVQQLDAR0ZXN0MSkw 9 | JwYDVQQKDCBFRDI1NTE5IERldmVsb3BlciBJRCBBcHBsaWNhdGlvbjELMAkGA1UE 10 | BhMCVVMwHhcNMjMxMTA1MDM1NzQ5WhcNMjMxMTA2MDM1NzQ5WjCBqTEUMBIGCgmS 11 | JomT8ixkAQEMBHRlc3QxSjBIBgNVBAMMQURldmVsb3BlciBJRCBBcHBsaWNhdGlv 12 | bjogRUQyNTUxOSBEZXZlbG9wZXIgSUQgQXBwbGljYXRpb24gKHRlc3QpMQ0wCwYD 13 | VQQLDAR0ZXN0MSkwJwYDVQQKDCBFRDI1NTE5IERldmVsb3BlciBJRCBBcHBsaWNh 14 | dGlvbjELMAkGA1UEBhMCVVMwLDAHBgMrZW4FAAMhAOIyvFJvysuNc1Ua4cqgs2j6 15 | 3TCciiEJ6osPEVrtNv66o00wSzAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoG 16 | CCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDATBgoqhkiG92NkBgENAQH/BAIFADAH 17 | BgMrZXAFAANBAGjwYupT1F7pZhJT8+1+A00ptDYN1nVItw6xxDAT6u4wa1uLBRQY 18 | lSW2tpbFHr5e4IFv9jogGE1ky+xTpT2+5AE= 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-ed25519-developer-id-installer.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/self-signed-ed25519-developer-id-installer.p12 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-ed25519-developer-id-installer.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MFECAQEwBQYDK2VwBCIEIN0VFMWe0x0NUaWxDozef9o+C/Uuf6X+6/9XXgCjyWod 3 | gSEA+sV9wFdfmSM2PF9Ko5A5tlXxELEGBUewpBtXoyx27KU= 4 | -----END PRIVATE KEY----- 5 | -----BEGIN CERTIFICATE----- 6 | MIICSzCCAfugAwIBAgIBATAHBgMrZXAFADCBozEUMBIGCgmSJomT8ixkAQEMBHRl 7 | c3QxRjBEBgNVBAMMPURldmVsb3BlciBJRCBJbnN0YWxsZXI6IEVEMjU1MTkgRGV2 8 | ZWxvcGVyIElEIEluc3RhbGxlciAodGVzdCkxDTALBgNVBAsMBHRlc3QxJzAlBgNV 9 | BAoMHkVEMjU1MTkgRGV2ZWxvcGVyIElEIEluc3RhbGxlcjELMAkGA1UEBhMCVVMw 10 | HhcNMjMxMTA1MDM1ODExWhcNMjMxMTA2MDM1ODExWjCBozEUMBIGCgmSJomT8ixk 11 | AQEMBHRlc3QxRjBEBgNVBAMMPURldmVsb3BlciBJRCBJbnN0YWxsZXI6IEVEMjU1 12 | MTkgRGV2ZWxvcGVyIElEIEluc3RhbGxlciAodGVzdCkxDTALBgNVBAsMBHRlc3Qx 13 | JzAlBgNVBAoMHkVEMjU1MTkgRGV2ZWxvcGVyIElEIEluc3RhbGxlcjELMAkGA1UE 14 | BhMCVVMwLDAHBgMrZW4FAAMhAPrFfcBXX5kjNjxfSqOQObZV8RCxBgVHsKQbV6Ms 15 | duylo04wTDAMBgNVHRMBAf8EAjAAMBcGA1UdJQEB/wQNMAsGCSqGSIb3Y2QEDTAO 16 | BgNVHQ8BAf8EBAMCB4AwEwYKKoZIhvdjZAYBDgEB/wQCBQAwBwYDK2VwBQADQQCt 17 | WU2uTeONtMraXTtThH8m7O6JU1E31jlYNTkQxgQat3vdWGtA2JbwaK60Ffaxwl6m 18 | /wBdUuTfHsHX+Uuz8HkG 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-ed25519-mac-installer-distribution.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/self-signed-ed25519-mac-installer-distribution.p12 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-ed25519-mac-installer-distribution.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MFECAQEwBQYDK2VwBCIEIBSRObN04oDxfLivENEIKVhb+9+OON6JDcBKwRBvAPl5 3 | gSEApOGf2wgy5BKE/nkY1JeXRCFuEW+/6FP0/ElHkzdlIik= 4 | -----END PRIVATE KEY----- 5 | -----BEGIN CERTIFICATE----- 6 | MIICcTCCAiGgAwIBAgIBATAHBgMrZXAFADCBtjEUMBIGCgmSJomT8ixkAQEMBHRl 7 | c3QxVTBTBgNVBAMMTDNyZCBQYXJ0eSBNYWMgRGV2ZWxvcGVyIEluc3RhbGxlcjog 8 | RUQyNTUxOSBNYWMgSW5zdGFsbGVyIERpc3RyaWJ1dGlvbiAodGVzdCkxDTALBgNV 9 | BAsMBHRlc3QxKzApBgNVBAoMIkVEMjU1MTkgTWFjIEluc3RhbGxlciBEaXN0cmli 10 | dXRpb24xCzAJBgNVBAYTAlVTMB4XDTIzMTEwNTAzNTYyMVoXDTIzMTEwNjAzNTYy 11 | MVowgbYxFDASBgoJkiaJk/IsZAEBDAR0ZXN0MVUwUwYDVQQDDEwzcmQgUGFydHkg 12 | TWFjIERldmVsb3BlciBJbnN0YWxsZXI6IEVEMjU1MTkgTWFjIEluc3RhbGxlciBE 13 | aXN0cmlidXRpb24gKHRlc3QpMQ0wCwYDVQQLDAR0ZXN0MSswKQYDVQQKDCJFRDI1 14 | NTE5IE1hYyBJbnN0YWxsZXIgRGlzdHJpYnV0aW9uMQswCQYDVQQGEwJVUzAsMAcG 15 | AytlbgUAAyEApOGf2wgy5BKE/nkY1JeXRCFuEW+/6FP0/ElHkzdlIimjTjBMMAwG 16 | A1UdEwEB/wQCMAAwFwYDVR0lAQH/BA0wCwYJKoZIhvdjZAQJMA4GA1UdDwEB/wQE 17 | AwIHgDATBgoqhkiG92NkBgEIAQH/BAIFADAHBgMrZXAFAANBAAgwBfaT1GXZmQGl 18 | 2LI9Qpi+rR3Cpsc9EW6KOxLLkiYp28H/GKNZYBCBKS0r/IsfOh7ja5acoEDVEHd1 19 | Pa+GEw4= 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-rsa-apple-development.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/self-signed-rsa-apple-development.p12 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-rsa-apple-development.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDmyeKhXDIfutBE 3 | LhC+u5gkxjGf2qev18InvaSoHhUrlyiFWjdeNCSfhfQScgemWLwJG0R7tJnx8IhO 4 | 7MmBh2MCAPJMTQjlV2JMM6QCGrVShYGpK5ArTUNsMDPMJ/ZyQvPv8XHtYvMW/A8T 5 | jrkn6NBWiuzxH8UZSHYIUJA34TgtgZmMEve1kT3RS/nCaIC8wnDEa4cgI/g73Rui 6 | OVs01oc8pf9wPf+85fVhtVNhpaO9Ab/toZ8gsaa8iarf+2Q9Po+vIylgnhGlh3Mv 7 | hUBRAt5qLNdsL5XJXiLdeveum48jjSxgq60FlbP6nJa1Lpq5XvevRZYRLeb6WGKu 8 | vHqiT+H7AgMBAAECggEASmRHFiZGze2E1oVWxnRnvWrZciKkLM1Ke07o9XwE7PEj 9 | kaCb+lSqfXVLUGrLRnaR3gmZEJsNiGw1M+OlrIf8hRfTAn9OX8bEG7YFptv/GKOK 10 | QQKWzS5xjj0XZTZ4fSpRwUU9qPxdSUpkfbRiwJeOGGddqvfHq7esvE9jvW9ukVP5 11 | cr+PNgmlVd6IrxECNln2M5nta7QnXHpPh5P1At/dO6fENpz/GRKn+ExCEnlhAnOf 12 | pQ9xzqKdlKnP+AErThCUz/Zn15ZLuB0Mv5YTrPQohJW9SmuT9lvmIZu0CNcgJCF4 13 | mxLpNTXP24LDPVQNmt4ZbHFIdQmOnwSI3m60RZeOoQKBgQDt5qgqaT+qgWKt/uOk 14 | gBVNqXBGPf8Lrk5X67J7nOYybO+BRqlvHM4BKecVSfoZzweRFQ3kjANDozSkLA1g 15 | OKleAsIiYidYVEx8dIfG+B+xXca9QO5kNsHp407f4YXC2y5GklahggpGmRd/qZ9D 16 | XV0M9y4o8QajMq8zxoF5CEG4CwKBgQD4WLU+0+BM/sruy/Ho7sPv6SMcRCaCwI4+ 17 | SphRElwcTBh1h5FSGyJTpoc2Y3DLmdgUr7NoZKnHjn/nxFYYrUWBW2O1NRdyHfj4 18 | DkT+SPpge1bSj0sNp5nUTdPBLDAehtuJvH/2+Mb52lUOUZ/oZ6HvofFW68DkpNrn 19 | +phPGFGD0QKBgQCHzniJXXO+vgW7FhqVuZhvsR4quxFxdZu7jQ1ii3rNpmpC/jeS 20 | +nqPJ4CHIqfnO8wyAjbgFR136x8N6Sfpme71f9WbEzUqs1TGZy9rYhGVitb9CqgM 21 | BUZFYkGQhIl7ZuvP1ZImuLls+8/yTL5iElYgJKrxLEaBu1lQ0SzwDsqVaQKBgGEi 22 | SRmew086JONLj32czbQrSplGqo1fhQMmJ/clqDNFLBfkA1nK1R1EuAP01uw7awGE 23 | SzackK9FtA9Rgp86PkI/HXuFnXr78CINarzOjGdqNmY6t49Kq2cXXahjgRqfgoSX 24 | 3rEZUrHszHHCSTocNoFEpOFralHDjP9Iy4O8Lj3RAoGAA4u4CSb36THpWZpVKILU 25 | /i8EutBcbZq5LfhvnUKgAmstQHgTq+rqnMfdVp7o1OoxtO+7HPC/NpuxozLB2wC/ 26 | H19AGPZ+ujKNi6SR55RzqWxwSW+sP67nwD07HorLDSuExZt6EjhCZaG3F0EXLBAV 27 | kwgQ9PiQb2otSRlPkpUVNeY= 28 | -----END PRIVATE KEY----- 29 | -----BEGIN CERTIFICATE----- 30 | MIID9zCCAt+gAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjDEUMBIGCgmSJomT8ixk 31 | AQEMBHRlc3QxODA2BgNVBAMML0FwcGxlIERldmVsb3BtZW50OiBSU0EgQXBwbGUg 32 | RGV2ZWxvcG1lbnQgKHRlc3QpMQ0wCwYDVQQLDAR0ZXN0MR4wHAYDVQQKDBVSU0Eg 33 | QXBwbGUgRGV2ZWxvcG1lbnQxCzAJBgNVBAYTAlVTMB4XDTIzMTEwNzEwNDkyOFoX 34 | DTM3MDcxNjEwNDkyOFowgYwxFDASBgoJkiaJk/IsZAEBDAR0ZXN0MTgwNgYDVQQD 35 | DC9BcHBsZSBEZXZlbG9wbWVudDogUlNBIEFwcGxlIERldmVsb3BtZW50ICh0ZXN0 36 | KTENMAsGA1UECwwEdGVzdDEeMBwGA1UECgwVUlNBIEFwcGxlIERldmVsb3BtZW50 37 | MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAObJ 38 | 4qFcMh+60EQuEL67mCTGMZ/ap6/Xwie9pKgeFSuXKIVaN140JJ+F9BJyB6ZYvAkb 39 | RHu0mfHwiE7syYGHYwIA8kxNCOVXYkwzpAIatVKFgakrkCtNQ2wwM8wn9nJC8+/x 40 | ce1i8xb8DxOOuSfo0FaK7PEfxRlIdghQkDfhOC2BmYwS97WRPdFL+cJogLzCcMRr 41 | hyAj+DvdG6I5WzTWhzyl/3A9/7zl9WG1U2Glo70Bv+2hnyCxpryJqt/7ZD0+j68j 42 | KWCeEaWHcy+FQFEC3mos12wvlcleIt16966bjyONLGCrrQWVs/qclrUumrle969F 43 | lhEt5vpYYq68eqJP4fsCAwEAAaNiMGAwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8E 44 | DDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8EBAMCB4AwEwYKKoZIhvdjZAYBAgEB/wQC 45 | BQAwEwYKKoZIhvdjZAYBDAEB/wQCBQAwDQYJKoZIhvcNAQELBQADggEBAJlWMwPG 46 | RsYXKLl1jxbFWebhvi6uCITIU1g0BiuB8hyJqUyJwP+yW5O4hlNXSdgelEQPbSV0 47 | OOB8xwGn5pqoveynHD0vaGNX+ELGKiewRcZxtIfYn9PmlFiq4Z1pJ057LVT39zbi 48 | UZZzgYXKsFzNcbTYoYBhDh93HP7uAZgEdpLsh/06TbrB20/4IF3ddEXWGEsR48pw 49 | GNaklfpLRLwTJf3WgFC0Xd2t86mp6gV1pbbXqdY28FLzs9eXKb9HXvycldtBVPFN 50 | KuWYyw3r1CTg8L/lnxFmjx6A5SQSrj9yK6sCZDmt3Pmge4HNF97HJK+lESjgkgOC 51 | A8E39gLLFUOXwFo= 52 | -----END CERTIFICATE----- 53 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-rsa-apple-distribution.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/self-signed-rsa-apple-distribution.p12 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-rsa-apple-distribution.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCotqbn6o7PRv+0 3 | 89js9h+ZWgVvsHyAJsOmIxwhKgnnxFTOS/Zv3kgIrLSPy+pyyf5oImlEsVNAnOS3 4 | YeA5QAp9RKUuHQNRANK6bil+rskFBUgxU6VD2X1lVFwel5UNS6/iOVz5/BPf0HVl 5 | BhE/pr7CZ2cUNnwRDl5W7Nu5zZ/wyUHph+68FJiiAj9hOzbdgARG6uvJx+fDYZbx 6 | 9dgLtkfdNGdains8R5VXEEC3GtLloksFzg73Z3IGKdlJ6Jo0niAu/V1RtSdjYY/V 7 | XFxKjiNf0jHjbo6tdumuvJohPUZO/wc6CenNqEf0uhWCiKwJwKNGkaEzuNdahMSo 8 | pdkFBhxHAgMBAAECggEAJBzUpRej8eI0obsAV9hm8yA9waZ5P8UMY+doAgFJlX6E 9 | 2JOR8GgX6yNskssHKALsncWf2sBKHa53lnkw0ZBPrnifErvLFe+jK5yg7SjkhlqX 10 | FVfeLCPFn4brIPE5SltFDptQt4Gpj2LDfhhKYOGEO4B+o+j1rYDx2JFihubosVVJ 11 | +lGk95zCY/iWqbMP5pmbsB+mnfCnZNLGfs2T8q1dDdLqwGQNkkGVdDrN0t7a6p3z 12 | psa7H3bNK4JCO9bwXxI9lxGHmQpp3tZxk52I8VAMUsV8u2j6m0E3BJsBJe/p6FOY 13 | u3Vfafavg9met9Q1GP97ueuLfEfrpmZlC4npyp5EQQKBgQDPpr8jTvNVN5pauw9i 14 | WiVzUkZpxIbudZ7LIHQqx23gmoCYyInVjkCP1swhCPcvP84nC+U2HUjcdniJxw8A 15 | UYFKeMX3mkJwXccdin1+kTzqip58nBm5qw6D/07tYnG+Ah8cwc8JrtfEnp1uHFNq 16 | pRjM7bRK2wUq6HzqQCOpmLZMaQKBgQDP/vonTnCTCrm/YQL+5NmcrTDUsmppZmTv 17 | RBw75d+7E2ajg8o6jR8K8VVi8+ltmmzhroiHkQO1tfQSJ80wE/kN5T4Qe3shIvE7 18 | byqNvYhzZdlGKTm2o3EwN+VI3k9wynmOEqcmgF98pbsVTluP18LVOgAO4r/wN5iL 19 | Bn4laa7NLwKBgQCOi7w4g9EdFc97K2BzNsjwsnEt2EB8X/gDHyM/3ql5/vX6a+fa 20 | 1w1Q8LYuk1YEdHuTaGIP1OiYlydGBYUxxcHImsHjqFylgGrYx6JAiXlU1JXZmts6 21 | DsgnKtNGuEa2lgQ/nHgBAKqUCgKufPlygyVUQHV80X9ppjFiKWeR3AiAyQKBgE3d 22 | MByC2tXREBQ65voxBd4HX95gJEHs2SBRKRirR4QrESNpdM1Sgyp/ie2PTfV/9/7M 23 | bcQCX5co1IPvbnrvHy86gG9/KmsPP6t2REHnkCtTF3GSgU6EBR1971HGF4sr4TF0 24 | fiqFqDlreYvSV6iTpxZXrinkbOIqjeqNta+fzpZ1AoGBAKBwZucL1L5rBDLKrb5S 25 | SlmXHjnQdj9zMDInyt98Rx9ioLRN4gS5SsN285aYajInFXp5rQmWSRgjE5kDrOyr 26 | HTbO4tdFhRnuvB25KIXfSDRG5MUTFF8WfFmvO8RQUjQEid6YOPZItUT+30q40iD1 27 | fIxpn1DnmltxBswkDdlr7JI1 28 | -----END PRIVATE KEY----- 29 | -----BEGIN CERTIFICATE----- 30 | MIID/TCCAuWgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjzEUMBIGCgmSJomT8ixk 31 | AQEMBHRlc3QxOjA4BgNVBAMMMUFwcGxlIERpc3RyaWJ1dGlvbjogUlNBIEFwcGxl 32 | IERpc3RyaWJ1dGlvbiAodGVzdCkxDTALBgNVBAsMBHRlc3QxHzAdBgNVBAoMFlJT 33 | QSBBcHBsZSBEaXN0cmlidXRpb24xCzAJBgNVBAYTAlVTMB4XDTIzMTEwNzEwNDgz 34 | N1oXDTM3MDcxNjEwNDgzN1owgY8xFDASBgoJkiaJk/IsZAEBDAR0ZXN0MTowOAYD 35 | VQQDDDFBcHBsZSBEaXN0cmlidXRpb246IFJTQSBBcHBsZSBEaXN0cmlidXRpb24g 36 | KHRlc3QpMQ0wCwYDVQQLDAR0ZXN0MR8wHQYDVQQKDBZSU0EgQXBwbGUgRGlzdHJp 37 | YnV0aW9uMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC 38 | ggEBAKi2pufqjs9G/7Tz2Oz2H5laBW+wfIAmw6YjHCEqCefEVM5L9m/eSAistI/L 39 | 6nLJ/mgiaUSxU0Cc5Ldh4DlACn1EpS4dA1EA0rpuKX6uyQUFSDFTpUPZfWVUXB6X 40 | lQ1Lr+I5XPn8E9/QdWUGET+mvsJnZxQ2fBEOXlbs27nNn/DJQemH7rwUmKICP2E7 41 | Nt2ABEbq68nH58NhlvH12Au2R900Z1qKezxHlVcQQLca0uWiSwXODvdncgYp2Uno 42 | mjSeIC79XVG1J2Nhj9VcXEqOI1/SMeNujq126a68miE9Rk7/BzoJ6c2oR/S6FYKI 43 | rAnAo0aRoTO411qExKil2QUGHEcCAwEAAaNiMGAwDAYDVR0TAQH/BAIwADAWBgNV 44 | HSUBAf8EDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8EBAMCB4AwEwYKKoZIhvdjZAYB 45 | BwEB/wQCBQAwEwYKKoZIhvdjZAYBBAEB/wQCBQAwDQYJKoZIhvcNAQELBQADggEB 46 | AFRh1ZGg2rmbxsAN34LzSjimIkB1DXaY1qGekQps99ydb/Lb+V7pZYMo/D722IID 47 | nbXBklumjVg+f5DupML2vOiz+zWKTBCAT9u9caTbmdvSl49+7TEqbNoj6OwgaWBi 48 | DX+cwDHEtKz/z5EMnt9kG1/WBq6jMpKs2fRg8AwIrZJVU04IM3fAW1kBHKZ83qzE 49 | kPYci/YpNc15sG/cWY+tqwG9QU49dFprt75AhQHJPfZEDeYe4UN/sKCEF8LWgRP1 50 | YPdfrR1OkSBy2SHUmx14nkOrDLyBbcHuFofytdE52hRPzEBmxS4HB90gLz1z4UqT 51 | Jl4MAwduSrE9qqk6JuvqV1o= 52 | -----END CERTIFICATE----- 53 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-rsa-developer-id-application.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/self-signed-rsa-developer-id-application.p12 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-rsa-developer-id-application.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCkdCzwAgHcNbpH 3 | awCPZISFqL6vPHstX1F9FjjGiOqQZ60xtXMsj1vpfxhpBZwxO/Q3RDn1ogvCluE5 4 | accwRI4uYJa80i5Dre+3znMFjkC2dJhaiG8NdsGZ2sVvlrfBMVHgayQSxNer0eIl 5 | A/NmnACLbYrfVfp4umd08QfZZLzSCIQi01JYgGXDLK9qqgU09Y/t8Wm+LdXgKCjG 6 | f30WlABULQR2WelMUk9S3PQHItZANYqNSOBCA3WOn532Eqq04bWcXPyLrvGgYrYH 7 | Gh6GdpAQIL+pL2ECZWegHvHdoWyFuuDbvvhV/VebaHIiIw5g1KF/X4Y9RvjYdaWM 8 | SjMNFNQfAgMBAAECggEAW16gyQiUeADx6lQtD35NkuVabIox9deLsu/xw3y2tlyk 9 | AYZK42sTKfwPV+piCYjB+yLRAQRzfD3QDNIUdWDhjirkFSzBv6CYG4t8pI2Qrs7B 10 | ByveZ6CfmBfQslsO5Su9ze45MKRlH3WRK/ex+EScmNrX2ZYvf3wxluuD7Ojnb9mf 11 | ND7Di6Sn5LTOsuuyTQP/PN1I23xg8QLf2YvDyS2zWx+gwdJlDPcRV3uIBlpoylyB 12 | sF+CpDgL0I8GpclLS31JyHoUlZ+e7wQ5aj1ZYX8wQl6f41dXHu5m5gExBU1u/fpE 13 | 54MFo+QlB7uy+qutgVlax8UWRExQ4dkIhdq5M3VUYQKBgQDEEwJuX6ahqyCbqsXU 14 | sxA2QobaDJ12+NJQ+dHXo4acgpPBm6e6j7hiUyIZDcD3yi2WJPTsk+wGHke+eo9n 15 | ZOkI6goZr5El1iPeTE5rnOIYdgpzgVpOQ2b26AnKXsgKeZwnmf8ugtHIwVZy3yBn 16 | pX4MYLFQC+5XgCeolwmy78k2tQKBgQDWtyjjOVWX0cONm1CtiRRByZaPocdKiHqm 17 | PpsMQk4uPUmI0Cfwlxzux+aBTloHX7+1GO3uFea6Czj4yX9DDcRF88tMtyI8SjzC 18 | MtTly1gaj7e7wqcTUheueTMq/kiT4n1dMvULYuRmv/enwXWAs+v/N+9/f6ZEuNYH 19 | UKCoguJwAwKBgQCuqKxSu5vIiZLbd+0QAo4fd3V+iRw/nXhjr5Xwe/duNZb/MPPh 20 | aSL7W0iVfr31PMEM7VDL6RynepO4Jp7VoHtBeJGUveMTDEUZQWndzHtPBN9ccs6J 21 | xtrSeHI4NeQGCLxEPpakzN2o8iha3U2VZkL5LazlPCuNAFjTge+e2KCpvQKBgFdt 22 | OtPSm5x2x/ZX4HDYmQv0hj6zs88QZUhdw4opUWYYhGGVyD15eklr0dqiyZupDAk0 23 | PmUsO8dTHH6IpS3rZBjLnOL+yozb+YNlaTSsKJKgJELqjlcanRPou8HsyiaVGVCi 24 | mA5r1O5VigSfjDW8jQJdh0JV+qCO1m8iEFis+oB7AoGAXYeCuNJXMOpL/Lm+29tD 25 | n0jbbnM9eVnomjzc67zCxwAQ6BsyuxAPoZ++4e+2jTDX0kDYa2AF8h00o8x0b+dR 26 | VavZLjYNM8lZ6uTATsZH/fTjMhw5mWGltaIJnrwldz7nzmwpXkzvNqqs1k2qb64S 27 | UhDxvyDeOLaOchP3itAAV9s= 28 | -----END PRIVATE KEY----- 29 | -----BEGIN CERTIFICATE----- 30 | MIIEDDCCAvSgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBoTEUMBIGCgmSJomT8ixk 31 | AQEMBHRlc3QxRjBEBgNVBAMMPURldmVsb3BlciBJRCBBcHBsaWNhdGlvbjogUlNB 32 | IERldmVsb3BlciBJRCBBcHBsaWNhdGlvbiAodGVzdCkxDTALBgNVBAsMBHRlc3Qx 33 | JTAjBgNVBAoMHFJTQSBEZXZlbG9wZXIgSUQgQXBwbGljYXRpb24xCzAJBgNVBAYT 34 | AlVTMB4XDTIzMTEwNzEwNTAzM1oXDTM3MDcxNjEwNTAzM1owgaExFDASBgoJkiaJ 35 | k/IsZAEBDAR0ZXN0MUYwRAYDVQQDDD1EZXZlbG9wZXIgSUQgQXBwbGljYXRpb246 36 | IFJTQSBEZXZlbG9wZXIgSUQgQXBwbGljYXRpb24gKHRlc3QpMQ0wCwYDVQQLDAR0 37 | ZXN0MSUwIwYDVQQKDBxSU0EgRGV2ZWxvcGVyIElEIEFwcGxpY2F0aW9uMQswCQYD 38 | VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKR0LPACAdw1 39 | ukdrAI9khIWovq88ey1fUX0WOMaI6pBnrTG1cyyPW+l/GGkFnDE79DdEOfWiC8KW 40 | 4TlpxzBEji5glrzSLkOt77fOcwWOQLZ0mFqIbw12wZnaxW+Wt8ExUeBrJBLE16vR 41 | 4iUD82acAIttit9V+ni6Z3TxB9lkvNIIhCLTUliAZcMsr2qqBTT1j+3xab4t1eAo 42 | KMZ/fRaUAFQtBHZZ6UxST1Lc9Aci1kA1io1I4EIDdY6fnfYSqrThtZxc/Iuu8aBi 43 | tgcaHoZ2kBAgv6kvYQJlZ6Ae8d2hbIW64Nu++FX9V5tociIjDmDUoX9fhj1G+Nh1 44 | pYxKMw0U1B8CAwEAAaNNMEswDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggr 45 | BgEFBQcDAzAOBgNVHQ8BAf8EBAMCB4AwEwYKKoZIhvdjZAYBDQEB/wQCBQAwDQYJ 46 | KoZIhvcNAQELBQADggEBAH4q6KQrqpdColHYFzw/v0CJ2j5ENwOuObw3xg+Q9ZJJ 47 | H2DskOsuZZeeMPpuasLwSk0Z5lWnzf7FRKNzmgb8PjTW+egPvGaulOEZ+p7vwYJH 48 | uN8KJhRpGK1IU0QrpjmM9b7+zXumxfAYW9BYane2f11FzoAXM/4rBzIXa0EzDlyZ 49 | 3vna93Q6qyRuvh6h9PLbrbqxsd8yeyj0TaXQ/s21NymUB4kTtXcBaBi2kg1UTS9b 50 | 7v7L+TgsfZ0Z1TCKYEfIbdwTTRguFbJxOnQ5shkV1Z6mMV7/AfEAwLbk6q14wQMY 51 | irQ7cH2zS2Ho8YDX+QI9pnRtGQJ7xivGxx/zJdQoZsw= 52 | -----END CERTIFICATE----- 53 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-rsa-developer-id-application2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCxB3u9PkOjy9K7 3 | vaqeAQ7OUmBEtx01NjzUn4LEe5BTL0/bh02KxG+edlaVOmdeMF8nff89yrP6k3L+ 4 | lA7p19uzACxjEYowytUyeLf1RCF9z+6rEeIAqW7+PEYH+yeiOrdSzd5DIaf/PGYk 5 | KxhHyp9OuAS8CDimfvXBRV7PmpKMj+ostOy0Tlj6po1+Nci+SepZRNP/YdFTi0Yd 6 | q9B/FztslFhvX/Ffc8rhmP8GQ8lPJqJOBcLss+aKAz9slFCzVahqmqXu8rz1b3E/ 7 | 5JHv5RFFBxgvwuXWaiO1mLTn62tIWTiG5rmR0xqJ4VucXk9DvOEAt1CxOBVupXOd 8 | 5IDt+qZ7AgMBAAECggEAH8IU6704yzCsjGuZKSFNc6wJgypKfhpNzWMURYVZPeMV 9 | 828RdRyKXaYjIEBK/PW2jFIpMP+lTAWZspwDFOZZjoIwdFFYNiqdFqHbdo+TZouf 10 | 6Gab4byDoe5ULehbktnvu1YdUnO+PKasOD7W60IpVCjlCIp9Bzltgw+b06iKM9bt 11 | KIPvBXDRgIp6eSBzJFxzj3zmdnSQn1OSF4V4oQt6gbR3NCJIcNyLXL1gEqtKg/AS 12 | swbpOVrPpXWd2x3gND8zvHD90vEiIesDNoSXKlclvLpQ30tkhkFh78xSe5sW7XEL 13 | hIKOExm+VCHoXTdjZnuCkXBkUIkek8T0KNs7A3LgeQKBgQDQXIDvGwzDhR+bdG5C 14 | azKI7SSqvIVpSngfGDCL8OLkYcoOwSClPOwZbY+UCXLppjrkoCD6QwJQ6CyCJwCK 15 | n9hAAWazOQPaerS3zbq2ig+HCQg12zZZ9/oXe7C/sRsq02phxV2+Km+v4uIyalQ9 16 | qGsywA1PN4/mFJ3H0w0QZXV3bwKBgQDZgRhegfulaWvK6x93EJ+UjLYv2d1oBBsn 17 | /87Vif/q14Ms0RNSmUPy1c8WuF8ZYOD4d7S+jcc/92JZWwJK+8pm6pHazdIIPCAP 18 | GCcp9fkS6gOu4twdC6oz34mJ3lqdmHKHz+0hhC2JqV1uwvPS5k/DcKfKR2+ifxQE 19 | xCBocLObtQKBgGWLH17n3OGQiCXXqUB/Q6KNh9gZhh8ZJs9ol4grvje1HKbyIfnF 20 | Zf7CcT2hGTqbQ4pWK5wref56F+7aGR515grTY/ymJaWdNWN6RKtfP0/8695rVeKk 21 | wmIdarcRFf9aBzdc22GpBsM+HCSbwzBFWvDhvdrEZkGn/Hj89xntiEDLAoGAb1sR 22 | r+kafkBv6I7iKCJBoVs9N1hya3uWr67fJSKm/IPj68ELBIHlcOEYSkiQn7yi0XLv 23 | /ZM2zMAKATeAAAXTRUeY7w3rFz45J6E1A92j7JQU2KfbC5/aPv6WOxi1CfRvxqqk 24 | fEFg0xb79+Yl0PcLJUN7FCvosqgfBqWm9fGlcvUCgYAYvALoZPz2z6zzqURDKPWk 25 | lkrW8nQVFg0eeTJNBiU1ipXS28oEGQISdjlYCHD1Ds3W8JHav/i6QnCaAXb5PtHd 26 | DlylI7U+tSZaC83+oPu/BaKVUO9n9e0mqj2oCD7W2gTBazac3d9F1ncfSkEhpDSB 27 | i6+0+GL62SGnzAF52ajf0g== 28 | -----END PRIVATE KEY----- 29 | -----BEGIN CERTIFICATE----- 30 | MIID4DCCAsigAwIBAgIBATANBgkqhkiG9w0BAQsFADCBizEYMBYGCgmSJomT8ixk 31 | AQEMCGRlYWRiZWVmMTkwNwYDVQQDDDBEZXZlbG9wZXIgSUQgQXBwbGljYXRpb246 32 | IEpvaG4gU2lnbmVyIChkZWFkYmVlZikxETAPBgNVBAsMCGRlYWRiZWVmMRQwEgYD 33 | VQQKDAtKb2huIFNpZ25lcjELMAkGA1UEBhMCWFgwHhcNMjQwMTE3MDI0ODE2WhcN 34 | MzcwOTI1MDI0ODE2WjCBizEYMBYGCgmSJomT8ixkAQEMCGRlYWRiZWVmMTkwNwYD 35 | VQQDDDBEZXZlbG9wZXIgSUQgQXBwbGljYXRpb246IEpvaG4gU2lnbmVyIChkZWFk 36 | YmVlZikxETAPBgNVBAsMCGRlYWRiZWVmMRQwEgYDVQQKDAtKb2huIFNpZ25lcjEL 37 | MAkGA1UEBhMCWFgwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCxB3u9 38 | PkOjy9K7vaqeAQ7OUmBEtx01NjzUn4LEe5BTL0/bh02KxG+edlaVOmdeMF8nff89 39 | yrP6k3L+lA7p19uzACxjEYowytUyeLf1RCF9z+6rEeIAqW7+PEYH+yeiOrdSzd5D 40 | Iaf/PGYkKxhHyp9OuAS8CDimfvXBRV7PmpKMj+ostOy0Tlj6po1+Nci+SepZRNP/ 41 | YdFTi0Ydq9B/FztslFhvX/Ffc8rhmP8GQ8lPJqJOBcLss+aKAz9slFCzVahqmqXu 42 | 8rz1b3E/5JHv5RFFBxgvwuXWaiO1mLTn62tIWTiG5rmR0xqJ4VucXk9DvOEAt1Cx 43 | OBVupXOd5IDt+qZ7AgMBAAGjTTBLMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAww 44 | CgYIKwYBBQUHAwMwDgYDVR0PAQH/BAQDAgeAMBMGCiqGSIb3Y2QGAQ0BAf8EAgUA 45 | MA0GCSqGSIb3DQEBCwUAA4IBAQCGzLhwja5AWKrla/VNjhXdKFiendu1VnGBwFQr 46 | WtMVSlXirqjG32WaayFJAjtp3MfXgLD6Yu2isB6I06LimuET4e2jR9nHcxtgZZ0B 47 | iowzgoNi+OA9sUSuZyrgzHwO7+tRmMroaMSURrzwCsffFIiiL8thgvZFZvtCRKm8 48 | 7pHzhvIGmjc5BYY8TB3BoWPZiqZAXY1cpw66gPVi2pQ6zitUtv1C3gzwLxQMDtnn 49 | SWm4XWWeihFcL6KgHxPqgnJ9YsRGjDbJ5LcrYk+uinXxSgzhv2Jlq+KD0VxvM6xr 50 | foxvH3jp8ISnTYjajhPQ8zekYE5iZN+GPtF0RjmtQ6RMlweR 51 | -----END CERTIFICATE----- 52 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-rsa-developer-id-installer.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/self-signed-rsa-developer-id-installer.p12 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-rsa-developer-id-installer.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDIwOT4PWVnRWDa 3 | B+ruSEvsTkamlVi6OcuuQ3c8E3YR/4A9cKzliE9o8XGK6h1uCP2MB8nj6vIVmm7B 4 | 1nHPSSdU3IlNO2s1Xmh1nJN9Q5LSXkCvh5yjMwsgxhyxcXKeeAALmDlmzVwZjAdZ 5 | N2wQmTCtMUu45AWG5T3Yw/W4n49Xs/q8bw2BucWOtRcCsc7+evFwYfMpHeZIRGxH 6 | HCDiRG0mkJ2VdX0Y1xRCYno+MvukeknAo/zF4Wle1YM99OgwBpRR33XwQE7B3SYN 7 | XVjiF+h+F3zPuVHMsGnH0Hu5s4SIGwbYl7oD3WX08khlKpmvRw+n5FyoiK+rRtND 8 | KkTMqDeFAgMBAAECggEBAJTGHum41kVKLRRnebtM6Lce60zYsQCRhFiItvxWj9GW 9 | v7rIndkcw3zKMZL5HQZGs1/rBbtaij1oTVxpR76OQA+rwDT0K+dJJ7DBcKwMP+qW 10 | 3uk2XuazFTQcnXcC1CaMV7w/+4or9m0YUPnVEMjcPi6bsbo7gb0Odl8GGjvQQ7KB 11 | 5tQQN7wWkPdM1g7KatiYkfWjNXa9RkwUdiZzZg9IMtF/YA9b3ol2wNVNAV6T5Fst 12 | OM862gcpe5TlInWFxYkRfF59GhPV84VAetc2u2ke5Lg3nZg86vGmoJ6ZkINsyVUz 13 | xDNJ/uiWdEC5VDA05Dit8Hb0Q9wEF2hulnEWlyXL6gECgYEA3ISCJzmO8oFigvb3 14 | Q2GaNyqvj735mVDK3U58Biu9YnBYqKyBa8mp8ZUYEQwbuwG3QyCt0CI2xbLFC6wE 15 | 5N7Scu4+dX8AhF1txABi7TCdr15OHYu9nFpyRG+KVCf7bCE3IAY3kWgRLLyoZapy 16 | CUo7b9gNagarPXMhhTqIig54SFUCgYEA6Q5EzJQ/Ki6FJrpifZjlZQ+RhfxaVUQ/ 17 | ZcINYROklx8JLzwLkOw5GVYkNslRjg+BAy+QwSSuYLfo4AFisWQ59owEjoAXkOag 18 | t/1zw/N1LKWwNaWWkushFJOidtw+X9LQCITL7XnTEkLirOpSlEl005wzk0ooEJ6U 19 | 4u30i6khInECgYAsJ/Bz8EeacaQLO26ptGqP72E2NEE9nPryM5wMFEgY5Qwrwlcs 20 | ATahZExsZXNMD/zlWS7UxXUYQ0LHootcVO3pC6HAH004NAkdvUIR4rFAg2665ddy 21 | 7n2BDKCzV0o2DbSfGf+YgzElNyW1Ldsl1xJtw+Jzv6AcbuhgaCcdFeap/QKBgQCQ 22 | TJdom/moInmrCwhkf8C5HDScYy2DUeh3Fvm1u7XTJBJJvsHij4CjIWT2zxvB+/OD 23 | h3X3QMD/fZ+g4vq6nzYMY5GGseTlgQbOJQ4Cq8FHTaeW79oVSaSH2wli0ueD6UGJ 24 | pL+nYCDCU8uKCOPskLbXNwXwEqBP+gBxqagauTOc4QKBgBH4DM5sC7LKOK0PjwuC 25 | BIE0PhY96IJS3k+J8+wupfcE+xzrCPcD4rdNRzByYFrihVnpRJSjc/FlLlg2z9J1 26 | vD9NYQaFtkaHuWV+m2EHaKqmS1ymsoZU+2N4eC/34ZnuSDhE/WPJLaU/YfL17Rsi 27 | axmxLymyrVblIh0KrU2AuJ/1 28 | -----END PRIVATE KEY----- 29 | -----BEGIN CERTIFICATE----- 30 | MIIEATCCAumgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBmzEUMBIGCgmSJomT8ixk 31 | AQEMBHRlc3QxQjBABgNVBAMMOURldmVsb3BlciBJRCBJbnN0YWxsZXI6IFJTQSBE 32 | ZXZlbG9wZXIgSUQgSW5zdGFsbGVyICh0ZXN0KTENMAsGA1UECwwEdGVzdDEjMCEG 33 | A1UECgwaUlNBIERldmVsb3BlciBJRCBJbnN0YWxsZXIxCzAJBgNVBAYTAlVTMB4X 34 | DTIzMTEwNzEwNTEwN1oXDTM3MDcxNjEwNTEwN1owgZsxFDASBgoJkiaJk/IsZAEB 35 | DAR0ZXN0MUIwQAYDVQQDDDlEZXZlbG9wZXIgSUQgSW5zdGFsbGVyOiBSU0EgRGV2 36 | ZWxvcGVyIElEIEluc3RhbGxlciAodGVzdCkxDTALBgNVBAsMBHRlc3QxIzAhBgNV 37 | BAoMGlJTQSBEZXZlbG9wZXIgSUQgSW5zdGFsbGVyMQswCQYDVQQGEwJVUzCCASIw 38 | DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMjA5Pg9ZWdFYNoH6u5IS+xORqaV 39 | WLo5y65DdzwTdhH/gD1wrOWIT2jxcYrqHW4I/YwHyePq8hWabsHWcc9JJ1TciU07 40 | azVeaHWck31DktJeQK+HnKMzCyDGHLFxcp54AAuYOWbNXBmMB1k3bBCZMK0xS7jk 41 | BYblPdjD9bifj1ez+rxvDYG5xY61FwKxzv568XBh8ykd5khEbEccIOJEbSaQnZV1 42 | fRjXFEJiej4y+6R6ScCj/MXhaV7Vgz306DAGlFHfdfBATsHdJg1dWOIX6H4XfM+5 43 | UcywacfQe7mzhIgbBtiXugPdZfTySGUqma9HD6fkXKiIr6tG00MqRMyoN4UCAwEA 44 | AaNOMEwwDAYDVR0TAQH/BAIwADAXBgNVHSUBAf8EDTALBgkqhkiG92NkBA0wDgYD 45 | VR0PAQH/BAQDAgeAMBMGCiqGSIb3Y2QGAQ4BAf8EAgUAMA0GCSqGSIb3DQEBCwUA 46 | A4IBAQAQYlyBvfIXIrfTzOWv+Bp4DzbCmtOpTmPtDh9Kv0bE4lJIroyFjm+cf9vQ 47 | 3MYDclbe75lqRwJEN5EQM2Fakb1FJC7IFEkgO7S4QGpld6congNLGmba/+2teJJ7 48 | yH0IMpYyC2gV35PJt52r4V6RRHv4yQ2tAdj7UPOiqXuzqUc6TCsLIcOmXzd3kYux 49 | jtAK3C+EWNB2zMUrstJ1Y1iGp4cny8jXLb4PCEEqVZBt1NCnGqCm5MfW2WLSj2DO 50 | 0UyJtqolyd4mTJmtK3MzWZK/KOE6q7Xum4phraVeCJqiWRYOE+art2gLqWDu5rif 51 | AjgIK7uOqJrmYiVjDS40vlaCptGa 52 | -----END CERTIFICATE----- 53 | -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-rsa-mac-installer-distribution.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-codesign/src/testdata/self-signed-rsa-mac-installer-distribution.p12 -------------------------------------------------------------------------------- /apple-codesign/src/testdata/self-signed-rsa-mac-installer-distribution.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDA87L0C/PY6A74 3 | jFhmY4QtXInTWhBiGsNoUO9fXcs1/hAUKxZxf5AbsqZVAAo5LqkjaEt510MtnhW+ 4 | NtMYY+K6A9PRmEYXrcIP75JesyPWJDGi49qQrd3wUrYULpmAzt0RzsMmfsGu0L36 5 | FrK0W4DALlnF9lz9jN6zdRMp7ArdgK0NzG/1lIsbkyVqyckR9CXQaloID5VbQYJe 6 | NYpF3bdppNrs9CbuSRakInv3t0XjHKL3l6X1bvcTIPguUsrsMADGQJ6Uh409+EwK 7 | XzYEkZBfMu2bEC3QbcYEgLAA6jHsHC9ooo+3Z+uwSb4v13xLLC9B5FrE+iOuZfHD 8 | 9bC87W8RAgMBAAECggEBAKOZPV8dD0kXITJuVLmjoTuQ3a9dCs0ToiE9lmhGr3j9 9 | DIb9LY9YOEizxcIGQaTQQkqqMGyDLwtroUXhWESy1FchzaRFtxB2nDdEytcOjtEP 10 | aSKSjQvkz2vnxUgBZtfHDbv+kop+KRxfEuUL/8NaXiUUZ7uospmsqlqAZppB78hz 11 | y9w/dN+s8i1XnYZkCcqdI2ifWIGQNS0HiW/mFP0iwGZMw70ORkos+p8LNDkimU5/ 12 | 4JapgeSneZmTllB1pferElUym+o4SRTW9aFLzWNE/odfw61CviE+2+XlnI7JttGq 13 | q1p1e4nIxbcm2dbqq4EG11cWxdkR73DfhKSDT2gP/V0CgYEA23mD2YE3tzq3Pbze 14 | cMjoTpgZ+OA2xU93I9Z3qT2YMQW+NIhIkh+DHMMs1U7auym3/iG0LmrFIR3BZ58j 15 | imffTXT5JbPHQB5gY/9pf6C/GE69aWnsXxT6QYqKaF+9tjx9Ki7e/U558Ud9pDQh 16 | hibFrFHu3y9wDwfKP/AuY18poEcCgYEA4RA2NaoWFRu3DJh8Fp43laTx3FSHBTJO 17 | iMB5o9FCjjjUMtSvnr0KIQ6X3TJCJfs6IAClaXrtu7r1quI/+BL6HGYC3QuT0G7Z 18 | KcLfDUT1Lx6BLTTDgSsAdwZjH7eERuReodZOxPUMCXAbJjmp/+kYzXrQng82bGlS 19 | Hh7WOY3iOecCgYBJnxl7fL0T2b5eF10GuF40/xC3S38T8PQmMWsyelbzGtoTBSRS 20 | 3/87Rr1jUHBPGE+AEA5BA8/cq/6Uo+1oIC/n67Un0IamG4p6ANOC3Ik9viwLkFya 21 | CI9qLO8A1BzvZJsX62Eh15FQPosG6fXU6mykwVc/xsnwQMy3Zfopm2J7QQKBgQCP 22 | 9m/GmfqwG99WJj/Rs/j4Nt8iwcrwTwKfRQdJ+3QoRz+tGBESZ/ePt6b6rchURUQj 23 | 7mXgd+qT1/6HBVxH0dO80J/qRxqRDCbLKMTG1yJCtq+IfCTGffw5JpPHWPs64Z+K 24 | w+v03o6JhvVG2UHd2XutDG9fe3mjlSca7zy26gQYZwKBgQCksh2zE2sGzxArOfYN 25 | LJd5BV74jtqhRhB11vvvhYOm8cvNoLimOBYiePF9ZO6ZcjCyyoNR4DURbTLwT6Rv 26 | AOYb00OmLtsU2v2P+0schBDWELpt9vvt7QOif3h1rdp31icgA2f5mNCn85NrwjpZ 27 | Tb1OwwrD2C1bj5j3a/e4//Dnkg== 28 | -----END PRIVATE KEY----- 29 | -----BEGIN CERTIFICATE----- 30 | MIIEJzCCAw+gAwIBAgIBATANBgkqhkiG9w0BAQsFADCBrjEUMBIGCgmSJomT8ixk 31 | AQEMBHRlc3QxUTBPBgNVBAMMSDNyZCBQYXJ0eSBNYWMgRGV2ZWxvcGVyIEluc3Rh 32 | bGxlcjogUlNBIE1hYyBJbnN0YWxsZXIgRGlzdHJpYnV0aW9uICh0ZXN0KTENMAsG 33 | A1UECwwEdGVzdDEnMCUGA1UECgweUlNBIE1hYyBJbnN0YWxsZXIgRGlzdHJpYnV0 34 | aW9uMQswCQYDVQQGEwJVUzAeFw0yMzExMDcxMDUxNTZaFw0zNzA3MTYxMDUxNTZa 35 | MIGuMRQwEgYKCZImiZPyLGQBAQwEdGVzdDFRME8GA1UEAwxIM3JkIFBhcnR5IE1h 36 | YyBEZXZlbG9wZXIgSW5zdGFsbGVyOiBSU0EgTWFjIEluc3RhbGxlciBEaXN0cmli 37 | dXRpb24gKHRlc3QpMQ0wCwYDVQQLDAR0ZXN0MScwJQYDVQQKDB5SU0EgTWFjIElu 38 | c3RhbGxlciBEaXN0cmlidXRpb24xCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0B 39 | AQEFAAOCAQ8AMIIBCgKCAQEAwPOy9Avz2OgO+IxYZmOELVyJ01oQYhrDaFDvX13L 40 | Nf4QFCsWcX+QG7KmVQAKOS6pI2hLeddDLZ4VvjbTGGPiugPT0ZhGF63CD++SXrMj 41 | 1iQxouPakK3d8FK2FC6ZgM7dEc7DJn7BrtC9+haytFuAwC5ZxfZc/Yzes3UTKewK 42 | 3YCtDcxv9ZSLG5MlasnJEfQl0GpaCA+VW0GCXjWKRd23aaTa7PQm7kkWpCJ797dF 43 | 4xyi95el9W73EyD4LlLK7DAAxkCelIeNPfhMCl82BJGQXzLtmxAt0G3GBICwAOox 44 | 7BwvaKKPt2frsEm+L9d8SywvQeRaxPojrmXxw/WwvO1vEQIDAQABo04wTDAMBgNV 45 | HRMBAf8EAjAAMBcGA1UdJQEB/wQNMAsGCSqGSIb3Y2QECTAOBgNVHQ8BAf8EBAMC 46 | B4AwEwYKKoZIhvdjZAYBCAEB/wQCBQAwDQYJKoZIhvcNAQELBQADggEBAK6eDJi5 47 | ig1RyQrsMhy/K9OPsDL2//01iwJBUClkx/ajJZPlZFvipbrs1gA4+rIK01lx9qnL 48 | pGugeTSRMMcBCrat+E/4675AFZftq/H5/plsJJ98XrGOXOTfXg40aF9rbv1tV8K0 49 | u37xaOGAAj7bZYPvazfTZ7XBKx0Fwr9JsskR6zM083BXRUhKONMSS3h60m6PRyRS 50 | rSPgzxC2Zmso7h763PwFVZbKpz6cQ8l4AdWGDuXvzHl/7e94kiU9mEta0szQyJBU 51 | bAxvajf/y1XUQDu9YQUDy67NCsc7jga6RvJBkwWLrLZpmD10tnOY0qUPmPY3Abk8 52 | gUISATBAl9H0xuY= 53 | -----END CERTIFICATE----- 54 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/compute-code-hashes.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help compute-code-hashes 3 | Compute code hashes for a binary 4 | 5 | Usage: rcodesign[EXE] compute-code-hashes [OPTIONS] 6 | 7 | Arguments: 8 | 9 | Path to Mach-O binary to examine 10 | 11 | Options: 12 | -C, --config-file 13 | Explicit configuration file to load. 14 | 15 | If provided, the default configuration files are not loaded, even if they exist. 16 | 17 | Can be specified multiple times. Files are loaded/merged in the order given. 18 | 19 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 20 | 21 | --hash 22 | Hashing algorithm to use 23 | 24 | [default: sha256] 25 | [possible values: none, sha1, sha256, sha256-truncated, sha384, sha512] 26 | 27 | -P, --profile 28 | Configuration profile to load. 29 | 30 | If not specified, the implicit "default" profile is loaded. 31 | 32 | --page-size 33 | Chunk size to digest over 34 | 35 | [default: 4096] 36 | 37 | --universal-index 38 | Index of Mach-O binary to operate on within a universal/fat binary 39 | 40 | [default: 0] 41 | 42 | -v, --verbose... 43 | Increase logging verbosity. Can be specified multiple times 44 | 45 | -h, --help 46 | Print help (see a summary with '-h') 47 | 48 | ``` 49 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/diff-signatures.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help diff-signatures 3 | Print a diff between the signature content of two paths 4 | 5 | Usage: rcodesign[EXE] diff-signatures [OPTIONS] 6 | 7 | Arguments: 8 | 9 | The first path to compare 10 | 11 | 12 | The second path to compare 13 | 14 | Options: 15 | -C, --config-file 16 | Explicit configuration file to load. 17 | 18 | If provided, the default configuration files are not loaded, even if they exist. 19 | 20 | Can be specified multiple times. Files are loaded/merged in the order given. 21 | 22 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 23 | 24 | -P, --profile 25 | Configuration profile to load. 26 | 27 | If not specified, the implicit "default" profile is loaded. 28 | 29 | -v, --verbose... 30 | Increase logging verbosity. Can be specified multiple times 31 | 32 | -h, --help 33 | Print help (see a summary with '-h') 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/encode-app-store-connect-api-key.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help encode-app-store-connect-api-key 3 | Encode App Store Connect API Key metadata to JSON 4 | 5 | App Store Connect API Keys 6 | (https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api) 7 | are defined by 3 components: 8 | 9 | * The Issuer ID (likely a UUID) 10 | * A Key ID (an alphanumeric value like `DEADBEEF42`) 11 | * A PEM encoded ECDSA private key (typically a file beginning with 12 | `-----BEGIN PRIVATE KEY-----`). 13 | 14 | This command is used to encode all API Key components into a single JSON 15 | object so you only have to refer to a single entity when performing 16 | operations (like notarization) using these API Keys. 17 | 18 | The API Key components are specified as positional arguments. 19 | 20 | By default, the JSON encoded unified representation is printed to stdout. 21 | You can write to a file instead by passing `--output-path `. 22 | 23 | # Security Considerations 24 | 25 | The App Store Connect API Key contains a private key and its value should be 26 | treated as sensitive: if an unwanted party obtains your private key, they 27 | effectively have access to your App Store Connect account. 28 | 29 | When this command writes JSON files, an attempt is made to limit access 30 | to the file. However, file access restrictions may not be as secure as you 31 | want. Security conscious individuals should audit the permissions of the 32 | file and adjust accordingly. 33 | 34 | Usage: rcodesign[EXE] encode-app-store-connect-api-key [OPTIONS] 35 | 36 | Arguments: 37 | 38 | The issuer of the API Token. Likely a UUID 39 | 40 | 41 | The Key ID. A short alphanumeric string like DEADBEEF42 42 | 43 | 44 | Path to a file containing the private key downloaded from Apple 45 | 46 | Options: 47 | -C, --config-file 48 | Explicit configuration file to load. 49 | 50 | If provided, the default configuration files are not loaded, even if they exist. 51 | 52 | Can be specified multiple times. Files are loaded/merged in the order given. 53 | 54 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 55 | 56 | -o, --output-path 57 | Path to a JSON file to create the output to 58 | 59 | -P, --profile 60 | Configuration profile to load. 61 | 62 | If not specified, the implicit "default" profile is loaded. 63 | 64 | -v, --verbose... 65 | Increase logging verbosity. Can be specified multiple times 66 | 67 | -h, --help 68 | Print help (see a summary with '-h') 69 | 70 | ``` 71 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/generate-csr.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign generate-certificate-signing-request --help 3 | Generates a certificate signing request that can be sent to Apple and exchanged for a signing certificate 4 | 5 | Usage: rcodesign[EXE] generate-certificate-signing-request [OPTIONS] 6 | 7 | Options: 8 | -C, --config-file 9 | Explicit configuration file to load. 10 | 11 | If provided, the default configuration files are not loaded, even if they exist. 12 | 13 | Can be specified multiple times. Files are loaded/merged in the order given. 14 | 15 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 16 | 17 | --csr-pem-file 18 | Path to file to write PEM encoded CSR to 19 | 20 | -P, --profile 21 | Configuration profile to load. 22 | 23 | If not specified, the implicit "default" profile is loaded. 24 | 25 | --smartcard-slot 26 | Smartcard slot number of signing certificate to use (9c is common) 27 | 28 | --smartcard-pin 29 | Smartcard PIN used to unlock certificate 30 | 31 | If not provided, you will be prompted for a PIN as necessary. 32 | 33 | -v, --verbose... 34 | Increase logging verbosity. Can be specified multiple times 35 | 36 | --smartcard-pin-env 37 | Environment variable holding the smartcard PIN 38 | 39 | --keychain-domain 40 | (macOS only) Keychain domain to operate on 41 | 42 | [possible values: user, system, common, dynamic] 43 | 44 | --keychain-fingerprint 45 | (macOS only) SHA-256 fingerprint of certificate in Keychain to use 46 | 47 | --windows-store-name 48 | (Windows only) Windows Store to operate on 49 | 50 | [possible values: user, machine, service] 51 | 52 | --windows-store-sha1-fingerprint 53 | (Windows only) SHA-1 fingerprint of certificate in Windows Store to use 54 | 55 | --pem-file 56 | Path to file containing PEM encoded certificate/key data 57 | 58 | --p12-file 59 | Path to a .p12/PFX file containing a certificate key pair 60 | 61 | --p12-password 62 | The password to use to open the --p12-file file 63 | 64 | --p12-password-file 65 | Path to file containing password for opening --p12-file file 66 | 67 | --remote-signing-url 68 | URL of a remote code signing server 69 | 70 | --remote-public-key 71 | Base64 encoded public key data describing the signer 72 | 73 | --remote-public-key-pem-file 74 | PEM encoded public key data describing the signer 75 | 76 | --remote-shared-secret 77 | Shared secret used for remote signing 78 | 79 | --remote-shared-secret-env 80 | Environment variable holding the shared secret used for remote signing 81 | 82 | --certificate-der-file 83 | Path to file containing DER encoded certificate data 84 | 85 | -h, --help 86 | Print help (see a summary with '-h') 87 | 88 | ``` 89 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/generate-self-signed-cert.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign generate-self-signed-certificate --help 3 | Generate a self-signed certificate for code signing 4 | 5 | This command will generate a new key pair using the algorithm of choice then create an X.509 certificate wrapper for it that is signed with the just-generated private key. The created X.509 certificate has extensions that mark it as appropriate for code signing. 6 | 7 | Certificates generated with this command can be useful for local testing. However, because it is a self-signed certificate and isn't signed by a trusted certificate authority, Apple operating systems may refuse to load binaries signed with it. 8 | 9 | By default the command prints 2 PEM encoded blocks. One block is for the X.509 public certificate. The other is for the PKCS#8 private key (which can include the public key). 10 | 11 | The `--pem-filename` argument can be specified to write the generated certificate pair to a pair of files. The destination files will have `.crt` and `.key` appended to the value provided. 12 | 13 | When the certificate is written to a file, it isn't printed to stdout. 14 | 15 | Usage: rcodesign[EXE] generate-self-signed-certificate [OPTIONS] --person-name 16 | 17 | Options: 18 | --algorithm 19 | Which key type to use 20 | 21 | [default: rsa] 22 | [possible values: ecdsa, ed25519, rsa] 23 | 24 | -C, --config-file 25 | Explicit configuration file to load. 26 | 27 | If provided, the default configuration files are not loaded, even if they exist. 28 | 29 | Can be specified multiple times. Files are loaded/merged in the order given. 30 | 31 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 32 | 33 | --profile 34 | [default: apple-development] 35 | [possible values: mac-installer-distribution, apple-distribution, apple-development, developer-id-application, developer-id-installer] 36 | 37 | --team-id 38 | Team ID (this is a short string attached to your Apple Developer account) 39 | 40 | [default: unset] 41 | 42 | -v, --verbose... 43 | Increase logging verbosity. Can be specified multiple times 44 | 45 | --person-name 46 | The name of the person this certificate is for 47 | 48 | --country-name 49 | Country Name (C) value for certificate identifier 50 | 51 | [default: XX] 52 | 53 | --validity-days 54 | How many days the certificate should be valid for 55 | 56 | [default: 365] 57 | 58 | --pem-filename 59 | Base name of files to write PEM encoded certificate to 60 | 61 | --pem-unified-file 62 | Filename to write PEM encoded private key and public certificate to 63 | 64 | --p12-file 65 | Filename to write a PKCS#12 / p12 / PFX encoded certificate to 66 | 67 | --p12-password 68 | Password to use to encrypt --p12-path. 69 | 70 | If not provided you will be prompted for a password. 71 | 72 | -h, --help 73 | Print help (see a summary with '-h') 74 | 75 | ``` 76 | 77 | ``` 78 | $ rcodesign generate-self-signed-certificate --profile apple-development --person-name 'Johnny Apple' 79 | -----BEGIN CERTIFICATE----- 80 | [..] 81 | [..] 82 | [..] 83 | [..] 84 | [..] 85 | [..] 86 | [..] 87 | [..] 88 | [..] 89 | [..] 90 | [..] 91 | [..] 92 | [..] 93 | [..] 94 | [..] 95 | [..] 96 | [..] 97 | [..] 98 | [..] 99 | [..] 100 | [..] 101 | -----END CERTIFICATE----- 102 | -----BEGIN PRIVATE KEY----- 103 | [..] 104 | [..] 105 | [..] 106 | [..] 107 | [..] 108 | [..] 109 | [..] 110 | [..] 111 | [..] 112 | [..] 113 | [..] 114 | [..] 115 | [..] 116 | [..] 117 | [..] 118 | [..] 119 | [..] 120 | [..] 121 | [..] 122 | [..] 123 | [..] 124 | [..] 125 | [..] 126 | [..] 127 | [..] 128 | [..] 129 | -----END PRIVATE KEY----- 130 | 131 | ``` 132 | 133 | Try a PKCS#12 file 134 | 135 | ``` 136 | $ rcodesign generate-self-signed-certificate --profile apple-development --person-name 'Johnny Apple' --p12-file test.p12 --p12-password password 137 | writing PKCS#12 certificate to test.p12 138 | 139 | ``` 140 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/keychain-export-certificate-chain.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help keychain-export-certificate-chain 3 | Export Apple CA certificates from the macOS Keychain 4 | 5 | Usage: rcodesign[EXE] keychain-export-certificate-chain [OPTIONS] --user-id 6 | 7 | Options: 8 | -C, --config-file 9 | Explicit configuration file to load. 10 | 11 | If provided, the default configuration files are not loaded, even if they exist. 12 | 13 | Can be specified multiple times. Files are loaded/merged in the order given. 14 | 15 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 16 | 17 | --domain 18 | Keychain domain to operate on 19 | 20 | [default: user] 21 | [possible values: user, system, common, dynamic] 22 | 23 | -P, --profile 24 | Configuration profile to load. 25 | 26 | If not specified, the implicit "default" profile is loaded. 27 | 28 | --password 29 | Password to unlock the Keychain 30 | 31 | --password-file 32 | File containing password to use to unlock the Keychain 33 | 34 | -v, --verbose... 35 | Increase logging verbosity. Can be specified multiple times 36 | 37 | --no-print-self 38 | Print only the issuing certificate chain, not the subject certificate 39 | 40 | --user-id 41 | User ID value of code signing certificate to find and whose CA chain to export 42 | 43 | -h, --help 44 | Print help (see a summary with '-h') 45 | 46 | ``` 47 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/keychain-print-certificates.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help keychain-print-certificates 3 | Print information about certificates in the macOS keychain 4 | 5 | Usage: rcodesign[EXE] keychain-print-certificates [OPTIONS] 6 | 7 | Options: 8 | -C, --config-file 9 | Explicit configuration file to load. 10 | 11 | If provided, the default configuration files are not loaded, even if they exist. 12 | 13 | Can be specified multiple times. Files are loaded/merged in the order given. 14 | 15 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 16 | 17 | --domain 18 | Keychain domain to operate on 19 | 20 | [default: user] 21 | [possible values: user, system, common, dynamic] 22 | 23 | -P, --profile 24 | Configuration profile to load. 25 | 26 | If not specified, the implicit "default" profile is loaded. 27 | 28 | -v, --verbose... 29 | Increase logging verbosity. Can be specified multiple times 30 | 31 | -h, --help 32 | Print help (see a summary with '-h') 33 | 34 | ``` 35 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/macho-universal-create.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help macho-universal-create 3 | Create a universal ("fat") Mach-O binary. 4 | 5 | This is similar to the `lipo -create` command. Use it to stitch multiple single architecture Mach-O binaries into a single multi-arch binary. 6 | 7 | Usage: rcodesign[EXE] macho-universal-create [OPTIONS] --output [INPUT]... 8 | 9 | Arguments: 10 | [INPUT]... 11 | Input Mach-O binaries to combine 12 | 13 | Options: 14 | -C, --config-file 15 | Explicit configuration file to load. 16 | 17 | If provided, the default configuration files are not loaded, even if they exist. 18 | 19 | Can be specified multiple times. Files are loaded/merged in the order given. 20 | 21 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 22 | 23 | -o, --output 24 | Output file to write 25 | 26 | -P, --profile 27 | Configuration profile to load. 28 | 29 | If not specified, the implicit "default" profile is loaded. 30 | 31 | -v, --verbose... 32 | Increase logging verbosity. Can be specified multiple times 33 | 34 | -h, --help 35 | Print help (see a summary with '-h') 36 | 37 | $ rcodesign debug-create-macho --architecture aarch64 exe.aarch64 38 | assuming default minimum version 11.0.0 39 | writing Mach-O to exe.aarch64 40 | 41 | $ rcodesign debug-create-macho --architecture x86-64 exe.x86-64 42 | assuming default minimum version 11.0.0 43 | writing Mach-O to exe.x86-64 44 | 45 | $ rcodesign macho-universal-create -o exe exe.aarch64 exe.x86-64 46 | adding exe.aarch64 47 | adding exe.x86-64 48 | writing exe 49 | 50 | ``` 51 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/notary-log.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help notary-log 3 | Fetch the notarization log for a previous submission 4 | 5 | Usage: rcodesign[EXE] notary-log [OPTIONS] 6 | 7 | Arguments: 8 | 9 | The ID of the previous submission to wait on 10 | 11 | Options: 12 | --api-key-file 13 | Path to a JSON file containing the API Key 14 | 15 | -C, --config-file 16 | Explicit configuration file to load. 17 | 18 | If provided, the default configuration files are not loaded, even if they exist. 19 | 20 | Can be specified multiple times. Files are loaded/merged in the order given. 21 | 22 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 23 | 24 | --api-issuer 25 | App Store Connect Issuer ID (likely a UUID) 26 | 27 | -P, --profile 28 | Configuration profile to load. 29 | 30 | If not specified, the implicit "default" profile is loaded. 31 | 32 | --api-key 33 | App Store Connect API Key ID 34 | 35 | -v, --verbose... 36 | Increase logging verbosity. Can be specified multiple times 37 | 38 | -h, --help 39 | Print help (see a summary with '-h') 40 | 41 | ``` 42 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/notary-submit.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help notary-submit 3 | Upload an asset to Apple for notarization and possibly staple it 4 | 5 | This command is used to submit an asset to Apple for notarization. Given a path to an asset with a code signature, this command will connect to Apple's Notary API and upload the asset. It will then optionally wait on the submission to finish processing (which typically takes a few dozen seconds). If the asset validates Apple's requirements, Apple will issue a *notarization ticket* as proof that they approved of it. This ticket is then added to the asset in a process called *stapling*, which this command can do automatically if the `--staple` argument is passed. 6 | 7 | # App Store Connect API Key 8 | 9 | In order to communicate with Apple's servers, you need an App Store Connect API Key. This requires an Apple Developer account. You can generate an API Key at https://appstoreconnect.apple.com/access/api. 10 | 11 | The recommended mechanism to define the API Key is via `--api-key-path`, which takes the path to a file containing JSON produced by the `encode-app-store-connect-api-key` command. See that command's help for more details. 12 | 13 | If you don't wish to use `--api-key-path`, you can define the key components via the `--api-issuer` and `--api-key` arguments. You will need a file named `AuthKey_.p8` in one of the following locations: `$(pwd)/private_keys/`, `~/private_keys/`, '~/.private_keys/`, and `~/.appstoreconnect/private_keys/` (searched in that order). The name of the file is derived from the value of `--api-key`. 14 | 15 | In all cases, App Store Connect API Keys can be managed at https://appstoreconnect.apple.com/access/api. 16 | 17 | # Modes of Operation 18 | 19 | By default, the `notarize` command will initiate an upload to Apple and exit once the upload is complete. 20 | 21 | Once an upload is performed, Apple will asynchronously process the uploaded content. This can take seconds to minutes. 22 | 23 | To poll Apple's servers and wait on the server-side processing to finish, specify `--wait`. This will query the state of the processing every few seconds until it is finished, the max wait time is reached, or an error occurs. 24 | 25 | To automatically staple an asset after server-side processing has finished, specify `--staple`. This implies `--wait`. 26 | 27 | Usage: rcodesign[EXE] notary-submit [OPTIONS] 28 | 29 | Arguments: 30 | 31 | Path to asset to upload 32 | 33 | Options: 34 | -C, --config-file 35 | Explicit configuration file to load. 36 | 37 | If provided, the default configuration files are not loaded, even if they exist. 38 | 39 | Can be specified multiple times. Files are loaded/merged in the order given. 40 | 41 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 42 | 43 | --wait 44 | Whether to wait for upload processing to complete 45 | 46 | --max-wait-seconds 47 | Maximum time in seconds to wait for the upload result 48 | 49 | [default: 600] 50 | 51 | -P, --profile 52 | Configuration profile to load. 53 | 54 | If not specified, the implicit "default" profile is loaded. 55 | 56 | --staple 57 | Staple the notarization ticket after successful upload (implies --wait) 58 | 59 | -v, --verbose... 60 | Increase logging verbosity. Can be specified multiple times 61 | 62 | --api-key-file 63 | Path to a JSON file containing the API Key 64 | 65 | --api-issuer 66 | App Store Connect Issuer ID (likely a UUID) 67 | 68 | --api-key 69 | App Store Connect API Key ID 70 | 71 | -h, --help 72 | Print help (see a summary with '-h') 73 | 74 | ``` 75 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/notary-wait.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help notary-wait 3 | Wait for completion of a previous submission 4 | 5 | Usage: rcodesign[EXE] notary-wait [OPTIONS] 6 | 7 | Arguments: 8 | 9 | The ID of the previous submission to wait on 10 | 11 | Options: 12 | -C, --config-file 13 | Explicit configuration file to load. 14 | 15 | If provided, the default configuration files are not loaded, even if they exist. 16 | 17 | Can be specified multiple times. Files are loaded/merged in the order given. 18 | 19 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 20 | 21 | --max-wait-seconds 22 | Maximum time in seconds to wait for the upload result 23 | 24 | [default: 600] 25 | 26 | --api-key-file 27 | Path to a JSON file containing the API Key 28 | 29 | -P, --profile 30 | Configuration profile to load. 31 | 32 | If not specified, the implicit "default" profile is loaded. 33 | 34 | --api-issuer 35 | App Store Connect Issuer ID (likely a UUID) 36 | 37 | -v, --verbose... 38 | Increase logging verbosity. Can be specified multiple times 39 | 40 | --api-key 41 | App Store Connect API Key ID 42 | 43 | -h, --help 44 | Print help (see a summary with '-h') 45 | 46 | ``` 47 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/parse-code-signing-requirement.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help parse-code-signing-requirement 3 | Parse binary Code Signing Requirement data into a human readable string 4 | 5 | This command can be used to parse binary code signing requirement data and print it in various formats. 6 | 7 | The source input format is the binary code requirement serialization. This is the format generated by Apple's `csreq` tool via `csreq -b`. The binary data begins with header magic `0xfade0c00`. 8 | 9 | The default output format is the Code Signing Requirement Language. But the output format can be changed via the --format argument. 10 | 11 | Our Code Signing Requirement Language output may differ from Apple's. For example, `and` and `or` expressions always have their sub-expressions surrounded by parentheses (e.g. `(a) and (b)` instead of `a and b`) and strings are always quoted. The differences, however, should not matter to the parser or result in a different binary serialization. 12 | 13 | Usage: rcodesign[EXE] parse-code-signing-requirement [OPTIONS] 14 | 15 | Arguments: 16 | 17 | Path to file to parse 18 | 19 | Options: 20 | -C, --config-file 21 | Explicit configuration file to load. 22 | 23 | If provided, the default configuration files are not loaded, even if they exist. 24 | 25 | Can be specified multiple times. Files are loaded/merged in the order given. 26 | 27 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 28 | 29 | --format 30 | Output format 31 | 32 | [default: csrl] 33 | [possible values: csrl, expression-tree] 34 | 35 | -P, --profile 36 | Configuration profile to load. 37 | 38 | If not specified, the implicit "default" profile is loaded. 39 | 40 | -v, --verbose... 41 | Increase logging verbosity. Can be specified multiple times 42 | 43 | -h, --help 44 | Print help (see a summary with '-h') 45 | 46 | ``` 47 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/print-signature-info.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help print-signature-info 3 | Print signature information for a filesystem path 4 | 5 | Usage: rcodesign[EXE] print-signature-info [OPTIONS] 6 | 7 | Arguments: 8 | 9 | Filesystem path to entity whose info to print 10 | 11 | Options: 12 | -C, --config-file 13 | Explicit configuration file to load. 14 | 15 | If provided, the default configuration files are not loaded, even if they exist. 16 | 17 | Can be specified multiple times. Files are loaded/merged in the order given. 18 | 19 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 20 | 21 | -P, --profile 22 | Configuration profile to load. 23 | 24 | If not specified, the implicit "default" profile is loaded. 25 | 26 | -v, --verbose... 27 | Increase logging verbosity. Can be specified multiple times 28 | 29 | -h, --help 30 | Print help (see a summary with '-h') 31 | 32 | ``` 33 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/remote-sign.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help remote-sign 3 | Create signatures initiated from a remote signing operation 4 | 5 | Usage: rcodesign[EXE] remote-sign [OPTIONS] <--editor|--sjs-file |SESSION_JOIN_STRING> 6 | 7 | Arguments: 8 | [SESSION_JOIN_STRING] 9 | Session join string (provided by the signing initiator) 10 | 11 | Options: 12 | -C, --config-file 13 | Explicit configuration file to load. 14 | 15 | If provided, the default configuration files are not loaded, even if they exist. 16 | 17 | Can be specified multiple times. Files are loaded/merged in the order given. 18 | 19 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 20 | 21 | --editor 22 | Open an editor to input the session join string 23 | 24 | -P, --profile 25 | Configuration profile to load. 26 | 27 | If not specified, the implicit "default" profile is loaded. 28 | 29 | --sjs-file 30 | Path to file containing session join string 31 | 32 | --smartcard-slot 33 | Smartcard slot number of signing certificate to use (9c is common) 34 | 35 | -v, --verbose... 36 | Increase logging verbosity. Can be specified multiple times 37 | 38 | --smartcard-pin 39 | Smartcard PIN used to unlock certificate 40 | 41 | If not provided, you will be prompted for a PIN as necessary. 42 | 43 | --smartcard-pin-env 44 | Environment variable holding the smartcard PIN 45 | 46 | --keychain-domain 47 | (macOS only) Keychain domain to operate on 48 | 49 | [possible values: user, system, common, dynamic] 50 | 51 | --keychain-fingerprint 52 | (macOS only) SHA-256 fingerprint of certificate in Keychain to use 53 | 54 | --windows-store-name 55 | (Windows only) Windows Store to operate on 56 | 57 | [possible values: user, machine, service] 58 | 59 | --windows-store-sha1-fingerprint 60 | (Windows only) SHA-1 fingerprint of certificate in Windows Store to use 61 | 62 | --pem-file 63 | Path to file containing PEM encoded certificate/key data 64 | 65 | --p12-file 66 | Path to a .p12/PFX file containing a certificate key pair 67 | 68 | --p12-password 69 | The password to use to open the --p12-file file 70 | 71 | --p12-password-file 72 | Path to file containing password for opening --p12-file file 73 | 74 | --remote-signing-url 75 | URL of a remote code signing server 76 | 77 | --remote-public-key 78 | Base64 encoded public key data describing the signer 79 | 80 | --remote-public-key-pem-file 81 | PEM encoded public key data describing the signer 82 | 83 | --remote-shared-secret 84 | Shared secret used for remote signing 85 | 86 | --remote-shared-secret-env 87 | Environment variable holding the shared secret used for remote signing 88 | 89 | --certificate-der-file 90 | Path to file containing DER encoded certificate data 91 | 92 | -h, --help 93 | Print help (see a summary with '-h') 94 | 95 | ``` 96 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/sign-bundle-symlink-overwrite.trycmd: -------------------------------------------------------------------------------- 1 | Sign a bundle with symlinks and verify symlink overwrites work 2 | 3 | ``` 4 | $ rcodesign debug-create-macho MyApp.app/Contents/MacOS/MyApp 5 | assuming default minimum version 11.0.0 6 | writing Mach-O to MyApp.app/Contents/MacOS/MyApp 7 | 8 | $ rcodesign debug-create-info-plist --bundle-name MyApp MyApp.app/Contents/Info.plist 9 | writing MyApp.app/Contents/Info.plist 10 | 11 | $ mkdir -p MyApp.app/Contents/Resources 12 | $ touch MyApp.app/Contents/Resources/file-00.txt 13 | $ touch MyApp.app/Contents/Resources/file-01.txt 14 | $ ln -s file-00.txt MyApp.app/Contents/Resources/file.txt 15 | 16 | $ rcodesign sign MyApp.app MyApp.app.signed 17 | signing MyApp.app to MyApp.app.signed 18 | signing bundle at MyApp.app 19 | signing bundle at MyApp.app into MyApp.app.signed 20 | signing main executable Contents/MacOS/MyApp 21 | 22 | $ ln -sf file-01.txt MyApp.app/Contents/Resources/file.txt 23 | 24 | $ rcodesign sign MyApp.app MyApp.app.signed 25 | signing MyApp.app to MyApp.app.signed 26 | signing bundle at MyApp.app 27 | signing bundle at MyApp.app into MyApp.app.signed 28 | signing main executable Contents/MacOS/MyApp 29 | 30 | $ rcodesign debug-file-tree MyApp.app.signed 31 | d MyApp.app.signed/ 32 | d MyApp.app.signed/Contents 33 | f 0a5902dc8e47f490d038 MyApp.app.signed/Contents/Info.plist 34 | d MyApp.app.signed/Contents/MacOS 35 | f 92cc3ed9973cf49d2574 MyApp.app.signed/Contents/MacOS/MyApp 36 | d MyApp.app.signed/Contents/Resources 37 | f e3b0c44298fc1c149afb MyApp.app.signed/Contents/Resources/file-00.txt 38 | f e3b0c44298fc1c149afb MyApp.app.signed/Contents/Resources/file-01.txt 39 | l MyApp.app.signed/Contents/Resources/file.txt -> file-01.txt 40 | d MyApp.app.signed/Contents/_CodeSignature 41 | f bafb4e22a57de8763dc1 MyApp.app.signed/Contents/_CodeSignature/CodeResources 42 | 43 | ``` 44 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/sign-code-requirements.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign debug-create-macho exe 3 | assuming default minimum version 11.0.0 4 | writing Mach-O to exe 5 | 6 | $ rcodesign debug-create-code-requirements --code-requirement developer-id-signed reqs 7 | writing code requirements to reqs 8 | 9 | $ rcodesign sign --code-requirements-path reqs exe exe.signed 10 | setting designated code requirements for main signing target: ((anchor apple generic) and (certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */)) and ((certificate leaf[field.1.2.840.113635.100.6.1.14] /* exists */) or (certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */)) 11 | signing exe to exe.signed 12 | signing exe as a Mach-O binary 13 | setting binary identifier to exe 14 | parsing Mach-O 15 | writing Mach-O to exe.signed 16 | 17 | $ rcodesign print-signature-info exe.signed 18 | - path: exe.signed 19 | file_size: 22544 20 | file_sha256: c08fddbfc311ebf3358bc6dca698de84f1eb89ba4dcc6a5aa7a0e214f766909d 21 | entity: 22 | mach_o: 23 | macho_linkedit_start_offset: 16384 / 0x4000 24 | macho_signature_start_offset: 16400 / 0x4010 25 | macho_signature_end_offset: 16892 / 0x41fc 26 | macho_linkedit_end_offset: 22544 / 0x5810 27 | macho_end_offset: 22544 / 0x5810 28 | linkedit_signature_start_offset: 16 / 0x10 29 | linkedit_signature_end_offset: 508 / 0x1fc 30 | linkedit_bytes_after_signature: 5652 / 0x1614 31 | signature: 32 | superblob_length: 492 / 0x1ec 33 | blob_count: 3 34 | blobs: 35 | - slot: CodeDirectory (0) 36 | magic: fade0c02 37 | length: 316 38 | sha1: 73543dc5f7d53cca5d485adfa9a36aeeb162f5ad 39 | sha256: 0282989f9df116683ae8f98e3b71d389d7a9eaa9b1864904e94cb7bc4a19cb02 40 | - slot: RequirementSet (2) 41 | magic: fade0c01 42 | length: 132 43 | sha1: 2ac6f23e29171f6d5b6a87822e8f5411753e0ec7 44 | sha256: 362f0cbb74f1847e4b2c7e3159a9d55e63d112fd1bf085e379d1bdfaf2813472 45 | - slot: CMS Signature (65536) 46 | magic: fade0b01 47 | length: 8 48 | sha1: 2a7254313aa41796079bb0e9d0f044345f69f98b 49 | sha256: e6c83bc98a10348492c7d4d2378a54572ef29e1a5692ccd02b5e29f4b762d6a0 50 | code_directory: 51 | version: '0x20400' 52 | flags: CodeSignatureFlags(ADHOC) 53 | identifier: exe 54 | digest_type: sha256 55 | platform: 0 56 | signed_entity_size: 16400 57 | executable_segment_flags: ExecutableSegmentFlags(MAIN_BINARY) 58 | code_digests_count: 5 59 | slot_digests: 60 | - 'Info (1): 0000000000000000000000000000000000000000000000000000000000000000' 61 | - 'RequirementSet (2): 362f0cbb74f1847e4b2c7e3159a9d55e63d112fd1bf085e379d1bdfaf2813472' 62 | code_requirements: 63 | - 'designated(3): 0: ((anchor apple generic) and (certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */)) and ((certificate leaf[field.1.2.840.113635.100.6.1.14] /* exists */) or (certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */));' 64 | cms: null 65 | 66 | ``` 67 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/sign-macho-info-plist.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign debug-create-macho exe 3 | assuming default minimum version 11.0.0 4 | writing Mach-O to exe 5 | 6 | $ rcodesign debug-create-info-plist --bundle-name MyApp Info.plist 7 | writing Info.plist 8 | 9 | $ rcodesign sign --info-plist-path Info.plist exe exe.signed 10 | signing exe to exe.signed 11 | signing exe as a Mach-O binary 12 | setting binary identifier to exe 13 | parsing Mach-O 14 | writing Mach-O to exe.signed 15 | 16 | $ rcodesign print-signature-info exe.signed 17 | - path: exe.signed 18 | file_size: 22544 19 | file_sha256: a060c6c3b1bd72a2d0a8aca5e21d5a91ed7ecbcfdc7d0201a87ef53ed1a74077 20 | entity: 21 | mach_o: 22 | macho_linkedit_start_offset: 16384 / 0x4000 23 | macho_signature_start_offset: 16400 / 0x4010 24 | macho_signature_end_offset: 16772 / 0x4184 25 | macho_linkedit_end_offset: 22544 / 0x5810 26 | macho_end_offset: 22544 / 0x5810 27 | linkedit_signature_start_offset: 16 / 0x10 28 | linkedit_signature_end_offset: 388 / 0x184 29 | linkedit_bytes_after_signature: 5772 / 0x168c 30 | signature: 31 | superblob_length: 372 / 0x174 32 | blob_count: 3 33 | blobs: 34 | - slot: CodeDirectory (0) 35 | magic: fade0c02 36 | length: 316 37 | sha1: 7f41a89c7645b669df41150feae14a688103d27f 38 | sha256: af781f6cf2fe6b3460d436deaf800f0481ae67eaae1681a419fc7e9657da69a4 39 | - slot: RequirementSet (2) 40 | magic: fade0c01 41 | length: 12 42 | sha1: 3a75f6db058529148e14dd7ea1b4729cc09ec973 43 | sha256: 987920904eab650e75788c054aa0b0524e6a80bfc71aa32df8d237a61743f986 44 | - slot: CMS Signature (65536) 45 | magic: fade0b01 46 | length: 8 47 | sha1: 2a7254313aa41796079bb0e9d0f044345f69f98b 48 | sha256: e6c83bc98a10348492c7d4d2378a54572ef29e1a5692ccd02b5e29f4b762d6a0 49 | code_directory: 50 | version: '0x20400' 51 | flags: CodeSignatureFlags(ADHOC) 52 | identifier: exe 53 | digest_type: sha256 54 | platform: 0 55 | signed_entity_size: 16400 56 | executable_segment_flags: ExecutableSegmentFlags(MAIN_BINARY) 57 | code_digests_count: 5 58 | slot_digests: 59 | - 'Info (1): 0a5902dc8e47f490d03889d3593d17bddbf79e6c1f79494e20dd28f9459effa5' 60 | - 'RequirementSet (2): 987920904eab650e75788c054aa0b0524e6a80bfc71aa32df8d237a61743f986' 61 | cms: null 62 | 63 | $ hashsum --sha256 --text Info.plist 64 | 0a5902dc8e47f490d03889d3593d17bddbf79e6c1f79494e20dd28f9459effa5 Info.plist 65 | 66 | ``` 67 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/smartcard-generate-key.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help smartcard-generate-key 3 | Generate a new private key on a smartcard 4 | 5 | Usage: rcodesign[EXE] smartcard-generate-key [OPTIONS] --smartcard-slot 6 | 7 | Options: 8 | -C, --config-file 9 | Explicit configuration file to load. 10 | 11 | If provided, the default configuration files are not loaded, even if they exist. 12 | 13 | Can be specified multiple times. Files are loaded/merged in the order given. 14 | 15 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 16 | 17 | --smartcard-slot 18 | Smartcard slot number to store key in (9c is common) 19 | 20 | -P, --profile 21 | Configuration profile to load. 22 | 23 | If not specified, the implicit "default" profile is loaded. 24 | 25 | --touch-policy 26 | Smartcard touch policy to protect key access 27 | 28 | [default: default] 29 | [possible values: default, always, never, cached] 30 | 31 | --pin-policy 32 | Smartcard pin prompt policy to protect key access 33 | 34 | [default: default] 35 | [possible values: default, never, once, always] 36 | 37 | -v, --verbose... 38 | Increase logging verbosity. Can be specified multiple times 39 | 40 | -h, --help 41 | Print help (see a summary with '-h') 42 | 43 | ``` 44 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/smartcard-import.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help smartcard-import 3 | Import a code signing certificate and key into a smartcard 4 | 5 | Usage: rcodesign[EXE] smartcard-import [OPTIONS] 6 | 7 | Options: 8 | -C, --config-file 9 | Explicit configuration file to load. 10 | 11 | If provided, the default configuration files are not loaded, even if they exist. 12 | 13 | Can be specified multiple times. Files are loaded/merged in the order given. 14 | 15 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 16 | 17 | --existing-key 18 | Re-use the existing private key in the smartcard slot 19 | 20 | --dry-run 21 | Don't actually perform the import 22 | 23 | -P, --profile 24 | Configuration profile to load. 25 | 26 | If not specified, the implicit "default" profile is loaded. 27 | 28 | --smartcard-slot 29 | Smartcard slot number of signing certificate to use (9c is common) 30 | 31 | -v, --verbose... 32 | Increase logging verbosity. Can be specified multiple times 33 | 34 | --smartcard-pin 35 | Smartcard PIN used to unlock certificate 36 | 37 | If not provided, you will be prompted for a PIN as necessary. 38 | 39 | --smartcard-pin-env 40 | Environment variable holding the smartcard PIN 41 | 42 | --keychain-domain 43 | (macOS only) Keychain domain to operate on 44 | 45 | [possible values: user, system, common, dynamic] 46 | 47 | --keychain-fingerprint 48 | (macOS only) SHA-256 fingerprint of certificate in Keychain to use 49 | 50 | --windows-store-name 51 | (Windows only) Windows Store to operate on 52 | 53 | [possible values: user, machine, service] 54 | 55 | --windows-store-sha1-fingerprint 56 | (Windows only) SHA-1 fingerprint of certificate in Windows Store to use 57 | 58 | --pem-file 59 | Path to file containing PEM encoded certificate/key data 60 | 61 | --p12-file 62 | Path to a .p12/PFX file containing a certificate key pair 63 | 64 | --p12-password 65 | The password to use to open the --p12-file file 66 | 67 | --p12-password-file 68 | Path to file containing password for opening --p12-file file 69 | 70 | --remote-signing-url 71 | URL of a remote code signing server 72 | 73 | --remote-public-key 74 | Base64 encoded public key data describing the signer 75 | 76 | --remote-public-key-pem-file 77 | PEM encoded public key data describing the signer 78 | 79 | --remote-shared-secret 80 | Shared secret used for remote signing 81 | 82 | --remote-shared-secret-env 83 | Environment variable holding the shared secret used for remote signing 84 | 85 | --certificate-der-file 86 | Path to file containing DER encoded certificate data 87 | 88 | --touch-policy 89 | Smartcard touch policy to protect key access 90 | 91 | [default: default] 92 | [possible values: default, always, never, cached] 93 | 94 | --pin-policy 95 | Smartcard pin prompt policy to protect key access 96 | 97 | [default: default] 98 | [possible values: default, never, once, always] 99 | 100 | -h, --help 101 | Print help (see a summary with '-h') 102 | 103 | ``` 104 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/smartcard-scan.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help smartcard-scan 3 | Show information about available smartcard (SC) devices 4 | 5 | Usage: rcodesign[EXE] smartcard-scan [OPTIONS] 6 | 7 | Options: 8 | -C, --config-file 9 | Explicit configuration file to load. 10 | 11 | If provided, the default configuration files are not loaded, even if they exist. 12 | 13 | Can be specified multiple times. Files are loaded/merged in the order given. 14 | 15 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 16 | 17 | -P, --profile 18 | Configuration profile to load. 19 | 20 | If not specified, the implicit "default" profile is loaded. 21 | 22 | -v, --verbose... 23 | Increase logging verbosity. Can be specified multiple times 24 | 25 | -h, --help 26 | Print help (see a summary with '-h') 27 | 28 | ``` 29 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/staple.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help staple 3 | Staples a notarization ticket to an entity 4 | 5 | Usage: rcodesign[EXE] staple [OPTIONS] 6 | 7 | Arguments: 8 | 9 | Path to entity to attempt to staple 10 | 11 | Options: 12 | -C, --config-file 13 | Explicit configuration file to load. 14 | 15 | If provided, the default configuration files are not loaded, even if they exist. 16 | 17 | Can be specified multiple times. Files are loaded/merged in the order given. 18 | 19 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 20 | 21 | -P, --profile 22 | Configuration profile to load. 23 | 24 | If not specified, the implicit "default" profile is loaded. 25 | 26 | -v, --verbose... 27 | Increase logging verbosity. Can be specified multiple times 28 | 29 | -h, --help 30 | Print help (see a summary with '-h') 31 | 32 | ``` 33 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/verify.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help verify 3 | Verifies code signature data 4 | 5 | Usage: rcodesign[EXE] verify [OPTIONS] 6 | 7 | Arguments: 8 | 9 | Path of Mach-O binary to examine 10 | 11 | Options: 12 | -C, --config-file 13 | Explicit configuration file to load. 14 | 15 | If provided, the default configuration files are not loaded, even if they exist. 16 | 17 | Can be specified multiple times. Files are loaded/merged in the order given. 18 | 19 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 20 | 21 | -P, --profile 22 | Configuration profile to load. 23 | 24 | If not specified, the implicit "default" profile is loaded. 25 | 26 | -v, --verbose... 27 | Increase logging verbosity. Can be specified multiple times 28 | 29 | -h, --help 30 | Print help (see a summary with '-h') 31 | 32 | ``` 33 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/windows-store-export-certificate-chain.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help windows-store-export-certificate-chain 3 | Export CA certificates from the Windows Store 4 | 5 | Usage: rcodesign[EXE] windows-store-export-certificate-chain [OPTIONS] --thumbprint 6 | 7 | Options: 8 | -C, --config-file 9 | Explicit configuration file to load. 10 | 11 | If provided, the default configuration files are not loaded, even if they exist. 12 | 13 | Can be specified multiple times. Files are loaded/merged in the order given. 14 | 15 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 16 | 17 | --windows-store-name 18 | Windows Store to operate on 19 | 20 | [default: user] 21 | [possible values: user, machine, service] 22 | 23 | --no-print-self 24 | Print only the issuing certificate chain, not the subject certificate 25 | 26 | -P, --profile 27 | Configuration profile to load. 28 | 29 | If not specified, the implicit "default" profile is loaded. 30 | 31 | --thumbprint 32 | SHA-1 thumbprint of code signing certificate to find and whose CA chain to export 33 | 34 | -v, --verbose... 35 | Increase logging verbosity. Can be specified multiple times 36 | 37 | -h, --help 38 | Print help (see a summary with '-h') 39 | 40 | ``` 41 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/windows-store-print-certificates.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign help windows-store-print-certificates 3 | Print information about certificates in the Windows Store 4 | 5 | Usage: rcodesign[EXE] windows-store-print-certificates [OPTIONS] 6 | 7 | Options: 8 | -C, --config-file 9 | Explicit configuration file to load. 10 | 11 | If provided, the default configuration files are not loaded, even if they exist. 12 | 13 | Can be specified multiple times. Files are loaded/merged in the order given. 14 | 15 | The special value `/dev/null` can be used to specify an empty/null config file. It can be used to short-circuit loading of default config files. 16 | 17 | --windows-store-name 18 | Windows Store name to operate on 19 | 20 | [default: user] 21 | [possible values: user, machine, service] 22 | 23 | -P, --profile 24 | Configuration profile to load. 25 | 26 | If not specified, the implicit "default" profile is loaded. 27 | 28 | -v, --verbose... 29 | Increase logging verbosity. Can be specified multiple times 30 | 31 | -h, --help 32 | Print help (see a summary with '-h') 33 | 34 | ``` 35 | -------------------------------------------------------------------------------- /apple-codesign/tests/cmd/x509-oids.trycmd: -------------------------------------------------------------------------------- 1 | ``` 2 | $ rcodesign x509-oids 3 | # Extended Key Usage (EKU) Extension OIDs 4 | 5 | 1.3.6.1.5.5.7.3.3 CodeSigning 6 | 1.2.840.113635.100.4.8 SafariDeveloper 7 | 1.2.840.113635.100.4.9 ThirdPartyMacDeveloperInstaller 8 | 1.2.840.113635.100.4.13 DeveloperIdInstaller 9 | 10 | # Code Signing Certificate Extension OIDs 11 | 12 | 1.2.840.113635.100.6.1.1 AppleSigning 13 | 1.2.840.113635.100.6.1.2 IPhoneDeveloper 14 | 1.2.840.113635.100.6.1.3 IPhoneOsApplicationSigning 15 | 1.2.840.113635.100.6.1.4 AppleDeveloperCertificateSubmission 16 | 1.2.840.113635.100.6.1.5 SafariDeveloper 17 | 1.2.840.113635.100.6.1.6 IPhoneOsVpnSigning 18 | 1.2.840.113635.100.6.1.7 AppleMacAppSigningDevelopment 19 | 1.2.840.113635.100.6.1.8 AppleMacAppSigningSubmission 20 | 1.2.840.113635.100.6.1.9 AppleMacAppStoreCodeSigning 21 | 1.2.840.113635.100.6.1.10 AppleMacAppStoreInstallerSigning 22 | 1.2.840.113635.100.6.1.12 MacDeveloper 23 | 1.2.840.113635.100.6.1.13 DeveloperIdApplication 24 | 1.2.840.113635.100.6.1.33 DeveloperIdDate 25 | 1.2.840.113635.100.6.1.14 DeveloperIdInstaller 26 | 1.2.840.113635.100.6.1.16 ApplePayPassbookSigning 27 | 1.2.840.113635.100.6.1.17 WebsitePushNotificationSigning 28 | 1.2.840.113635.100.6.1.18 DeveloperIdKernel 29 | 1.2.840.113635.100.6.1.25.1 TestFlight 30 | 31 | # Certificate Authority Certificate Extension OIDs 32 | 33 | 1.2.840.113635.100.6.2.1 AppleWorldwideDeveloperRelations 34 | 1.2.840.113635.100.6.2.3 AppleApplicationIntegration 35 | 1.2.840.113635.100.6.2.6 DeveloperId 36 | 1.2.840.113635.100.6.2.9 AppleTimestamp 37 | 1.2.840.113635.100.6.2.11 DeveloperAuthentication 38 | 1.2.840.113635.100.6.2.14 AppleApplicationIntegrationG3 39 | 1.2.840.113635.100.6.2.15 AppleWorldwideDeveloperRelationsG2 40 | 1.2.840.113635.100.6.2.19 AppleSoftwareUpdateCertification 41 | 1.2.840.113635.100.6.2.31 AppleApplicationIntegrationG1 42 | 43 | ``` 44 | -------------------------------------------------------------------------------- /apple-dmg/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # apple-dmg Crate Changelog 2 | 3 | 4 | 5 | ## Unreleased 6 | 7 | Released on ReleaseDate. 8 | 9 | ## 0.5.0 10 | 11 | Released on 2024-11-03. 12 | 13 | * gpt 3.1 -> 4.0. 14 | 15 | ## 0.4.0 16 | 17 | Released on 2023-11-15. 18 | 19 | ## 0.3.1 20 | 21 | Released on 2023-11-09. 22 | 23 | ## 0.3.0 24 | 25 | Released on 2023-11-06. 26 | 27 | * Minimum supported Rust version is now 1.70. 28 | 29 | ## 0.2.0 30 | 31 | Released on 2022-12-21. 32 | -------------------------------------------------------------------------------- /apple-dmg/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "apple-dmg" 3 | version = "0.5.0" 4 | edition = "2021" 5 | rust-version = "1.81" 6 | description = "Library for reading and writing dmg images." 7 | repository = "https://github.com/indygreg/apple-platform-rs" 8 | license = "Apache-2.0 OR MIT" 9 | 10 | [dependencies] 11 | anyhow = "1.0.93" 12 | byteorder = "1.5.0" 13 | crc32fast = "1.4.2" 14 | fatfs = "0.3.6" 15 | flate2 = "1.0.35" 16 | fscommon = "0.1.1" 17 | getrandom = "0.2.15" 18 | gpt = "4.0.0" 19 | md5 = "0.7.0" 20 | plist = "1.7.0" 21 | serde = { version = "1.0.215", features = ["derive"] } 22 | serde_bytes = "0.11.15" 23 | -------------------------------------------------------------------------------- /apple-dmg/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright 2022 Gregory Szorc 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to use, 6 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 7 | Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | 20 | -------------------------------------------------------------------------------- /apple-dmg/assets/example.dmg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/indygreg/apple-platform-rs/2312b1e5bd77322c019613e0ca624e222c6c6e08/apple-dmg/assets/example.dmg -------------------------------------------------------------------------------- /apple-dmg/src/xml.rs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 or the MIT license 3 | // , at your 4 | // option. This file may not be copied, modified, or distributed 5 | // except according to those terms. 6 | use { 7 | crate::blkx::BlkxTable, 8 | anyhow::Result, 9 | serde::{Deserialize, Serialize}, 10 | }; 11 | 12 | #[derive(Clone, Debug, Default, Deserialize, Serialize)] 13 | #[serde(deny_unknown_fields)] 14 | pub struct Plist { 15 | #[serde(rename = "resource-fork")] 16 | pub resource_fork: ResourceFork, 17 | } 18 | 19 | impl Plist { 20 | pub fn partitions(&self) -> &[Partition] { 21 | &self.resource_fork.blkx 22 | } 23 | 24 | pub fn add_partition(&mut self, partition: Partition) { 25 | self.resource_fork.blkx.push(partition); 26 | } 27 | } 28 | 29 | #[derive(Clone, Debug, Default, Deserialize, Serialize)] 30 | #[serde(deny_unknown_fields)] 31 | pub struct ResourceFork { 32 | pub blkx: Vec, 33 | #[serde(default)] 34 | pub plst: Vec, 35 | } 36 | 37 | #[derive(Clone, Debug, Deserialize, Serialize)] 38 | #[serde(deny_unknown_fields)] 39 | pub struct Partition { 40 | #[serde(rename = "Attributes")] 41 | pub attributes: String, 42 | #[serde(rename = "CFName")] 43 | #[serde(default)] 44 | pub cfname: String, 45 | #[serde(rename = "Data")] 46 | #[serde(with = "serde_bytes")] 47 | pub data: Vec, 48 | #[serde(rename = "ID")] 49 | pub id: String, 50 | #[serde(rename = "Name")] 51 | pub name: String, 52 | } 53 | 54 | impl Partition { 55 | pub fn new(id: i32, name: String, table: BlkxTable) -> Self { 56 | let mut data = vec![]; 57 | table.write_to(&mut data).unwrap(); 58 | Self { 59 | attributes: "0x0050".to_string(), 60 | cfname: name.clone(), 61 | data, 62 | id: id.to_string(), 63 | name, 64 | } 65 | } 66 | 67 | pub fn table(&self) -> Result { 68 | BlkxTable::read_from(&mut &self.data[..]) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /apple-flat-package/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # apple-flat package Crate Changelog 2 | 3 | 4 | 5 | ## Unreleased 6 | 7 | Released on ReleaseDate. 8 | 9 | ## 0.20.0 10 | 11 | Released on 2024-11-29. 12 | 13 | ## 0.19.0 14 | 15 | Released on 2024-11-03. 16 | 17 | ## 0.18.0 18 | 19 | Released on 2024-01-17. 20 | 21 | ## 0.17.0 22 | 23 | * scroll 0.11 -> 0.12. 24 | 25 | Released on 2023-11-17. 26 | 27 | ## 0.16.0 28 | 29 | Released on 2023-11-15. 30 | 31 | * Types implementing `Serialize` and `Deserialize` all now derive `Eq` and 32 | `PartialEq`. 33 | * The `PackageInfo` struct changed its storage of the `scripts` field 34 | so it can now properly decode `` in XML files. (#9) 35 | * `PkgReader::resolve_component()` is now public. 36 | * The documentation for `PkgReader` has been clarified. (#14) 37 | 38 | ## 0.15.0 39 | 40 | Released on 2023-11-09. 41 | 42 | ## 0.14.1 43 | 44 | Released on 2023-11-09. 45 | 46 | ## 0.14.0 47 | 48 | Released on 2023-11-06. 49 | 50 | * Minimum supported Rust version is now 1.70. 51 | 52 | ## 0.13.0 53 | 54 | Released on 2022-12-21. 55 | 56 | * Cargo.toml now defines patch version for all dependencies. 57 | 58 | ## 0.12.0 59 | 60 | Released on 2022-12-18. 61 | 62 | ## 0.11.0 63 | 64 | Released on 2022-10-02. 65 | -------------------------------------------------------------------------------- /apple-flat-package/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "apple-flat-package" 3 | version = "0.20.0" 4 | authors = ["Gregory Szorc "] 5 | edition = "2021" 6 | rust-version = "1.81" 7 | license = "MPL-2.0" 8 | description = "Apple flat package (.pkg) format handling" 9 | keywords = ["apple", "flat-package", "pkgbuild", "pkg", "productbuild"] 10 | homepage = "https://github.com/indygreg/apple-platform-rs" 11 | repository = "https://github.com/indygreg/apple-platform-rs.git" 12 | readme = "README.md" 13 | 14 | [dependencies] 15 | flate2 = "1.0.35" 16 | scroll = { version = "0.12.0", features = ["derive"] } 17 | serde-xml-rs = "0.6.0" 18 | serde = { version = "1.0.215", features = ["derive"] } 19 | thiserror = "2.0.3" 20 | 21 | [dependencies.apple-xar] 22 | path = "../apple-xar" 23 | version = "0.20.0" 24 | 25 | [dependencies.cpio-archive] 26 | path = "../cpio-archive" 27 | version = "0.10.0" 28 | -------------------------------------------------------------------------------- /apple-flat-package/README.md: -------------------------------------------------------------------------------- 1 | # apple-flat-package 2 | 3 | This crate implements an interface to Apple's *flat package* installer package 4 | file format. This is the XAR-based installer package (`.pkg`) format used since 5 | macOS 10.5. 6 | 7 | The interface is in pure Rust and doesn't require the use of Apple specific 8 | tools or hardware to run. The functionality in this crate could be used to 9 | reimplement Apple installer tools like `pkgbuild` and `productbuild`. 10 | -------------------------------------------------------------------------------- /apple-flat-package/src/component_package.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. 4 | 5 | //! Interface to component packages, installable units within flat packages. 6 | 7 | use { 8 | crate::{package_info::PackageInfo, PkgResult}, 9 | cpio_archive::ChainedCpioReader, 10 | std::io::{Cursor, Read}, 11 | }; 12 | 13 | const GZIP_HEADER: [u8; 3] = [0x1f, 0x8b, 0x08]; 14 | 15 | /// Attempt to decode the compressed content of an archive file. 16 | /// 17 | /// The content can be compressed with various formats. This attempts to 18 | /// sniff them and apply an appropriate decompressor. 19 | fn decode_archive(data: Vec) -> PkgResult> { 20 | if data.len() > 3 && data[0..3] == GZIP_HEADER { 21 | Ok(Box::new(flate2::read::GzDecoder::new(Cursor::new(data))) as Box) 22 | } else { 23 | Ok(Box::new(Cursor::new(data)) as Box) 24 | } 25 | } 26 | 27 | /// Type alias representing a generic reader for a cpio archive. 28 | pub type CpioReader = Box>>; 29 | 30 | fn cpio_reader(data: &[u8]) -> PkgResult { 31 | let decoder = decode_archive(data.to_vec())?; 32 | Ok(cpio_archive::reader(decoder)?) 33 | } 34 | 35 | /// Read-only interface for a single *component package*. 36 | pub struct ComponentPackageReader { 37 | bom: Option>, 38 | package_info: Option, 39 | payload: Option>, 40 | scripts: Option>, 41 | } 42 | 43 | impl ComponentPackageReader { 44 | /// Construct an instance with raw file data backing different files. 45 | pub fn from_file_data( 46 | bom: Option>, 47 | package_info: Option>, 48 | payload: Option>, 49 | scripts: Option>, 50 | ) -> PkgResult { 51 | let package_info = if let Some(data) = package_info { 52 | Some(PackageInfo::from_reader(Cursor::new(data))?) 53 | } else { 54 | None 55 | }; 56 | 57 | Ok(Self { 58 | bom, 59 | package_info, 60 | payload, 61 | scripts, 62 | }) 63 | } 64 | 65 | /// Obtained the contents of the `Bom` file. 66 | pub fn bom(&self) -> Option<&[u8]> { 67 | self.bom.as_ref().map(|x| x.as_ref()) 68 | } 69 | 70 | /// Obtain the parsed `PackageInfo` XML file. 71 | pub fn package_info(&self) -> Option<&PackageInfo> { 72 | self.package_info.as_ref() 73 | } 74 | 75 | /// Obtain a reader for the `Payload` cpio archive. 76 | pub fn payload_reader(&self) -> PkgResult> { 77 | if let Some(payload) = &self.payload { 78 | Ok(Some(cpio_reader(payload)?)) 79 | } else { 80 | Ok(None) 81 | } 82 | } 83 | 84 | /// Obtain a reader for the `Scripts` cpio archive. 85 | pub fn scripts_reader(&self) -> PkgResult> { 86 | if let Some(data) = &self.scripts { 87 | Ok(Some(cpio_reader(data)?)) 88 | } else { 89 | Ok(None) 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /apple-sdk/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # apple-sdk Crate Changelog 2 | 3 | 4 | 5 | ## Unreleased 6 | 7 | Released on ReleaseDate. 8 | 9 | ## 0.6.0 10 | 11 | Released on 2024-11-03. 12 | 13 | * XROS support. `Platform` enumeration added `XrOs` and `XrOsSimulator` 14 | variants. The `aarch64-apple-xros-sim` and `*-apple-xros` triples are 15 | now recognized as XROS. 16 | * The developer directory configured with `xcode-select --switch PATH` can now 17 | be retrieved by using `DeveloperDirectory::from_xcode_select_paths`, and 18 | this is done by default when searching for SDKs. (#154) 19 | * `plist` 1.6 -> 1.7. 20 | 21 | ## 0.5.2 22 | 23 | Released on 2023-12-22. 24 | 25 | * Fixed repository URL in README.md. 26 | 27 | ## 0.5.1 28 | 29 | Released on 2023-11-09. 30 | 31 | ## 0.5.0 32 | 33 | Released on 2023-11-06. 34 | 35 | * Change `PlatformDirectory` and `SdkVersion` `partial_cmp()` to be 36 | implemented in terms of `cmp()`. Should have no visible effects. 37 | 38 | ## 0.4.0 39 | 40 | Released on 2022-12-21. 41 | 42 | * Cargo.toml now defines patch version for all dependencies. 43 | 44 | ## 0.3.0 45 | 46 | Released on 2022-12-18. 47 | 48 | * Project moved from https://github.com/indygreg/toolchain-tools to 49 | https://github.com/indygreg/apple-platform-rs. 50 | 51 | ## 0.2.0 52 | 53 | Released on 2022-07-31. 54 | 55 | * Document that `SdkSearchLocation::SdkRootEnv` bypasses SDK filtering. 56 | * Add `Platform::from_target_triple()`. (#1) 57 | * `AppleSdk::as_sdk_path()` has been renamed to `AppleSdk::sdk_path()`. The 58 | old name proxies to the new function, is marked as deprecated, and will be 59 | removed in a future minor version release. (#2) 60 | 61 | ## 0.1.0 62 | 63 | Released on 2022-05-26. 64 | 65 | Initial version of crate. 66 | -------------------------------------------------------------------------------- /apple-sdk/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "apple-sdk" 3 | version = "0.6.0" 4 | edition = "2021" 5 | license = "MIT OR Apache-2.0" 6 | readme = "README.md" 7 | authors = ["Gregory Szorc "] 8 | description = "Interact with Apple SDKs" 9 | keywords = ["apple"] 10 | homepage = "https://github.com/indygreg/apple-platform-rs" 11 | repository = "https://github.com/indygreg/apple-platform-rs.git" 12 | 13 | [dependencies] 14 | serde_json = { version = "1.0.133", optional = true } 15 | serde = { version = "1.0.215", optional = true, features = ["derive"] } 16 | plist = { version = "1.7.0", optional = true } 17 | 18 | [features] 19 | default = ["parse"] 20 | parse = ["plist", "serde_json", "serde"] 21 | -------------------------------------------------------------------------------- /apple-sdk/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright 2022 Gregory Szorc 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to use, 6 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 7 | Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | 20 | -------------------------------------------------------------------------------- /apple-sdk/README.md: -------------------------------------------------------------------------------- 1 | # apple-sdk 2 | 3 | `apple-sdk` provides facilities for interacting with Apple SDKs. 4 | 5 | The canonical home of this project is 6 | https://github.com/indygreg/apple-platform-rs. 7 | -------------------------------------------------------------------------------- /apple-sdk/src/simple_sdk.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Gregory Szorc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use { 10 | crate::{AppleSdk, Error, Platform, SdkPath, SdkVersion}, 11 | std::path::{Path, PathBuf}, 12 | }; 13 | 14 | #[cfg(feature = "parse")] 15 | use crate::parsed_sdk::ParsedSdk; 16 | 17 | /// A directory purported to hold an Apple SDK. 18 | #[derive(Clone, Debug)] 19 | pub struct SimpleSdk { 20 | /// Root directory of the SDK. 21 | path: PathBuf, 22 | 23 | /// Whether the root directory is a symlink to another path. 24 | is_symlink: bool, 25 | 26 | sdk_path: SdkPath, 27 | } 28 | 29 | impl AsRef for SimpleSdk { 30 | fn as_ref(&self) -> &Path { 31 | &self.path 32 | } 33 | } 34 | 35 | impl AppleSdk for SimpleSdk { 36 | fn from_directory(path: &Path) -> Result { 37 | let sdk = SdkPath::from_path(path)?; 38 | 39 | // Need to call symlink_metadata so symlinks aren't followed. 40 | let metadata = std::fs::symlink_metadata(path)?; 41 | 42 | let is_symlink = metadata.file_type().is_symlink(); 43 | 44 | let json_path = path.join("SDKSettings.json"); 45 | let plist_path = path.join("SDKSettings.plist"); 46 | 47 | if json_path.exists() || plist_path.exists() { 48 | Ok(Self { 49 | path: path.to_path_buf(), 50 | is_symlink, 51 | sdk_path: sdk, 52 | }) 53 | } else { 54 | Err(Error::PathNotSdk(path.to_path_buf())) 55 | } 56 | } 57 | 58 | fn is_symlink(&self) -> bool { 59 | self.is_symlink 60 | } 61 | 62 | fn platform(&self) -> &Platform { 63 | &self.sdk_path.platform 64 | } 65 | 66 | fn version(&self) -> Option<&SdkVersion> { 67 | self.sdk_path.version.as_ref() 68 | } 69 | 70 | fn supports_deployment_target( 71 | &self, 72 | _target_name: &str, 73 | _target_version: &SdkVersion, 74 | ) -> Result { 75 | Err(Error::FunctionalityNotSupported( 76 | "evaluating deployment target support on UnparsedSdk instances", 77 | )) 78 | } 79 | } 80 | 81 | impl SimpleSdk { 82 | #[cfg(feature = "parse")] 83 | /// Attempt to convert into an [AppleSdk] by parsing an `SDKSettings.*` file. 84 | pub fn try_parse(self) -> Result { 85 | self.try_into() 86 | } 87 | } 88 | 89 | #[cfg(test)] 90 | mod test { 91 | use { 92 | super::*, 93 | crate::{DeveloperDirectory, COMMAND_LINE_TOOLS_DEFAULT_PATH}, 94 | }; 95 | 96 | #[test] 97 | fn find_default_sdks() -> Result<(), Error> { 98 | if let Ok(developer_dir) = DeveloperDirectory::find_default_required() { 99 | assert!(!developer_dir.sdks::()?.is_empty()); 100 | } 101 | 102 | Ok(()) 103 | } 104 | 105 | #[test] 106 | fn find_command_line_tools_sdks() -> Result<(), Error> { 107 | let sdk_path = PathBuf::from(COMMAND_LINE_TOOLS_DEFAULT_PATH).join("SDKs"); 108 | 109 | let res = SimpleSdk::find_command_line_tools_sdks()?; 110 | 111 | if sdk_path.exists() { 112 | assert!(res.is_some()); 113 | assert!(!res.unwrap().is_empty()); 114 | } else { 115 | assert!(res.is_none()); 116 | } 117 | 118 | Ok(()) 119 | } 120 | 121 | #[test] 122 | fn find_all_sdks() -> Result<(), Error> { 123 | for dir in DeveloperDirectory::find_system_xcodes()? { 124 | for sdk in dir.sdks::()? { 125 | assert!(!matches!(sdk.platform(), Platform::Unknown(_))); 126 | } 127 | } 128 | 129 | Ok(()) 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /apple-sdk/src/testfiles/macosx10.10-settings.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CanonicalName 6 | macosx10.10 7 | CustomProperties 8 | 9 | KERNEL_EXTENSION_HEADER_SEARCH_PATHS 10 | $(KERNEL_FRAMEWORK)/PrivateHeaders $(KERNEL_FRAMEWORK_HEADERS) 11 | 12 | DefaultProperties 13 | 14 | MACOSX_DEPLOYMENT_TARGET 15 | 10.10 16 | PLATFORM_NAME 17 | macosx 18 | DEFAULT_KEXT_INSTALL_PATH 19 | $(LIBRARY_KEXT_INSTALL_PATH) 20 | 21 | DisplayName 22 | OS X 10.10 23 | MaximumDeploymentTarget 24 | 10.10 25 | MinimalDisplayName 26 | 10.10 27 | MinimumSupportedToolsVersion 28 | 3.2 29 | SupportedBuildToolComponents 30 | 31 | com.apple.compilers.gcc.headers.4_2 32 | 33 | Version 34 | 10.10 35 | isBaseSDK 36 | YES 37 | 38 | 39 | -------------------------------------------------------------------------------- /apple-sdk/src/testfiles/macosx10.9-settings.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | macosx10.9 7 | CanonicalName 8 | macosx10.9 9 | CustomProperties 10 | 11 | KERNEL_EXTENSION_HEADER_SEARCH_PATHS 12 | $(KERNEL_FRAMEWORK)/PrivateHeaders $(KERNEL_FRAMEWORK_HEADERS) 13 | 14 | DefaultProperties 15 | 16 | MACOSX_DEPLOYMENT_TARGET 17 | 10.9 18 | PLATFORM_NAME 19 | macosx 20 | DEFAULT_KEXT_INSTALL_PATH 21 | $(LIBRARY_KEXT_INSTALL_PATH) 22 | 23 | DisplayName 24 | OS X 10.9 25 | MaximumDeploymentTarget 26 | 10.9 27 | MinimalDisplayName 28 | 10.9 29 | MinimumSupportedToolsVersion 30 | 3.2 31 | SupportedBuildToolComponents 32 | 33 | com.apple.compilers.gcc.headers.4_2 34 | 35 | Version 36 | 10.9 37 | isBaseSDK 38 | YES 39 | 40 | 41 | -------------------------------------------------------------------------------- /apple-xar/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # apple-xar Crate Changelog 2 | 3 | 4 | 5 | ## Unreleased 6 | 7 | Released on ReleaseDate. 8 | 9 | ## 0.20.0 10 | 11 | Released on 2024-11-29. 12 | 13 | ## 0.19.0 14 | 15 | Released on 2024-11-03. 16 | 17 | * Added `id` field to `Ea` struct. (#155) 18 | * `base64` 0.21 -> 0.22. 19 | * `cryptographic-message-syntax` 0.26 -> 0.27. 20 | * `reqwest` 0.11 -> 0.12. 21 | * `x509-certificate` 0.23 -> 0.24. 22 | 23 | ## 0.18.0 24 | 25 | Released on 2024-01-17. 26 | 27 | * scroll 0.11 -> 0.12. 28 | 29 | ## 0.17.0 30 | 31 | Released on 2023-11-17. 32 | 33 | ## 0.16.0 34 | 35 | Released on 2023-11-15. 36 | 37 | * Added the `signing` feature which controls whether Cryptographic 38 | Message Syntax based signing support is available. The feature - 39 | enabled by default - can be disabled to disable the `bcder`, 40 | `cryptographic-message-syntax`, `rand`, `reqwest`, and `signature` 41 | crates to significantly slim down the dependency tree. (#15) 42 | 43 | ## 0.15.0 44 | 45 | Released on 2023-11-09. 46 | 47 | * cryptographic-message-syntax 0.25 -> 0.26. 48 | * x509-certificate 0.22 -> 0.23. 49 | 50 | ## 0.14.0 51 | 52 | Released on 2023-11-06. 53 | 54 | * Minimum supported Rust version is now 1.70. 55 | * cryptographic-message-syntax 0.20 -> 0.25. 56 | * signature 1.6 -> 2.0. 57 | * x509-certificate 0.17 -> 0.22. 58 | 59 | ## 0.13.0 60 | 61 | Released on 2022-12-21. 62 | 63 | * Cargo.toml now defines patch version for all dependencies. 64 | 65 | ## 0.12.0 66 | 67 | Released on 2022-12-18. 68 | 69 | * `FileChecksum` now deserializes UPPERCASE string variants without 70 | error. (#51) 71 | 72 | ## 0.11.0 73 | 74 | Released on 2022-10-02. 75 | -------------------------------------------------------------------------------- /apple-xar/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "apple-xar" 3 | version = "0.20.0" 4 | authors = ["Gregory Szorc "] 5 | edition = "2021" 6 | rust-version = "1.81" 7 | license = "MPL-2.0" 8 | description = "XAR archive reading and writing" 9 | keywords = ["apple", "xar"] 10 | homepage = "https://github.com/indygreg/apple-platform-rs" 11 | repository = "https://github.com/indygreg/apple-platform-rs.git" 12 | readme = "README.md" 13 | 14 | [dependencies] 15 | base64 = "0.22.1" 16 | bcder = { version = "0.7.4", optional = true } 17 | bzip2 = "0.4.4" 18 | chrono = { version = "0.4.38", features = ["serde"] } 19 | cryptographic-message-syntax = { version = "0.27.0", optional = true } 20 | digest = "0.10.7" 21 | log = "0.4.22" 22 | md-5 = "0.10.6" 23 | flate2 = "1.0.35" 24 | rand = { version = "0.8.5", optional = true } 25 | reqwest = { version = "0.12.9", default-features = false, optional = true } 26 | scroll = { version = "0.12.0", features = ["derive"] } 27 | serde-xml-rs = "0.6.0" 28 | serde = { version = "1.0.215", features = ["derive"] } 29 | sha1 = "0.10.6" 30 | sha2 = "0.10.8" 31 | signature = { version = "2.2.0", features = ["std"], optional = true } 32 | thiserror = "2.0.3" 33 | url = "2.5.4" 34 | xml-rs = "0.8.23" 35 | x509-certificate = "0.24.0" 36 | xz2 = { version = "0.1.7", features = ["static"] } 37 | 38 | [features] 39 | default = ["signing"] 40 | # Enable support for extracting the cryptographic signature in XAR archives. 41 | signing = [ 42 | "dep:bcder", 43 | "dep:cryptographic-message-syntax", 44 | "dep:rand", 45 | "dep:reqwest", 46 | "dep:signature", 47 | ] 48 | -------------------------------------------------------------------------------- /apple-xar/README.md: -------------------------------------------------------------------------------- 1 | # apple-xar 2 | 3 | This crate implements the Apple-flavored XAR archive format, enabling reading 4 | and writing of XAR archives. 5 | 6 | XAR archives are commonly encountered as the archive format for *flat packages* 7 | (`.pkg` installers). 8 | -------------------------------------------------------------------------------- /apple-xar/src/format.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. 4 | 5 | use { 6 | scroll::{IOread, IOwrite, Pread, SizeWith}, 7 | std::fmt::{Display, Formatter}, 8 | }; 9 | 10 | /// A XAR archive header. 11 | /// 12 | /// The header effectively defines a table of contents, which 13 | /// holds information about the content of the archive. 14 | #[derive(Clone, Copy, Debug, IOread, IOwrite, Pread, SizeWith)] 15 | pub struct XarHeader { 16 | /// File magic. `xar!`. 17 | pub magic: u32, 18 | 19 | /// Size of this header + magic. 20 | pub size: u16, 21 | 22 | /// Format version number. 23 | pub version: u16, 24 | 25 | /// Size in bytes of zlib compressed table of contents. 26 | pub toc_length_compressed: u64, 27 | 28 | /// Size in bytes of uncompressed table of contents. 29 | pub toc_length_uncompressed: u64, 30 | 31 | /// Checksum algorithm used. 32 | pub checksum_algorithm_id: u32, 33 | } 34 | 35 | /// Checksum format used in file. 36 | pub enum XarChecksum { 37 | None, 38 | Sha1, 39 | Md5, 40 | Sha256, 41 | Sha512, 42 | Other(u32), 43 | } 44 | 45 | impl From for XarChecksum { 46 | fn from(i: u32) -> Self { 47 | match i { 48 | 0 => Self::None, 49 | 1 => Self::Sha1, 50 | 2 => Self::Md5, 51 | 3 => Self::Sha256, 52 | 4 => Self::Sha512, 53 | _ => Self::Other(i), 54 | } 55 | } 56 | } 57 | 58 | impl From for u32 { 59 | fn from(checksum: XarChecksum) -> u32 { 60 | match checksum { 61 | XarChecksum::None => 0, 62 | XarChecksum::Sha1 => 1, 63 | XarChecksum::Md5 => 2, 64 | XarChecksum::Sha256 => 3, 65 | XarChecksum::Sha512 => 4, 66 | XarChecksum::Other(v) => v, 67 | } 68 | } 69 | } 70 | 71 | impl Display for XarChecksum { 72 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 73 | match self { 74 | XarChecksum::None => f.write_str("none"), 75 | XarChecksum::Sha1 => f.write_str("SHA-1"), 76 | XarChecksum::Md5 => f.write_str("MD5"), 77 | XarChecksum::Sha256 => f.write_str("SHA-256"), 78 | XarChecksum::Sha512 => f.write_str("SHA-512"), 79 | XarChecksum::Other(v) => f.write_fmt(format_args!("unknown ({v})")), 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /apple-xar/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. 4 | 5 | /*! XAR file format */ 6 | 7 | pub mod format; 8 | pub mod reader; 9 | #[cfg(feature = "signing")] 10 | pub mod signing; 11 | pub mod table_of_contents; 12 | 13 | #[derive(Debug, thiserror::Error)] 14 | pub enum Error { 15 | #[error("(de)serialization error: {0}")] 16 | Scroll(#[from] scroll::Error), 17 | 18 | #[error("unable to parse checksum string: {0}")] 19 | BadChecksum(&'static str), 20 | 21 | #[error("I/O error: {0}")] 22 | Io(#[from] std::io::Error), 23 | 24 | #[error("decompression error: {0}")] 25 | Decompress(#[from] flate2::DecompressError), 26 | 27 | #[error("XML error: {0}")] 28 | SerdeXml(#[from] serde_xml_rs::Error), 29 | 30 | #[error("XML write error: {0}")] 31 | XmlWrite(#[from] xml::writer::Error), 32 | 33 | #[error("Invalid file ID")] 34 | InvalidFileId, 35 | 36 | #[error("table of contents is corrupted: {0}")] 37 | TableOfContentsCorrupted(&'static str), 38 | 39 | #[error("File has no data")] 40 | FileNoData, 41 | 42 | #[error("Unimplemented file encoding: {0}")] 43 | UnimplementedFileEncoding(String), 44 | 45 | #[error("Operation not supported: {0}")] 46 | Unsupported(&'static str), 47 | 48 | #[error("x509 certificate error: {0}")] 49 | X509Certificate(#[from] x509_certificate::X509CertificateError), 50 | 51 | #[cfg(feature = "signing")] 52 | #[error("signing error: {0}")] 53 | SignatureCreation(#[from] signature::Error), 54 | 55 | #[cfg(feature = "signing")] 56 | #[error("CMS error: {0}")] 57 | Cms(#[from] cryptographic_message_syntax::CmsError), 58 | 59 | #[cfg(feature = "signing")] 60 | #[error("HTTP error: {0}")] 61 | Reqwest(#[from] reqwest::Error), 62 | } 63 | 64 | pub type XarResult = std::result::Result; 65 | -------------------------------------------------------------------------------- /ci/developer-id-application.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt2CB7Q9oBDpA6Pkd4spG 3 | CWF+LbOnJUGkUPeCn7frIv8CT6HMxaCE8KokTuNo8nVqJW9Ocy/oFHO2SiJ0H2EM 4 | FgaWIVgfiJuZKIMwzDzIEtgV48VE9V+9ARaI5JOFm+buivAtlCdTzpUASscIqVb1 5 | 00Lqyf8oAd679bywsxEyigVTxAFQ+qHFfyk0/D8Z8tg7e+osoXAFoH/E6fdKaUMv 6 | EUwoMvpulvT/+gqAS9qnnYd2ugbHNtjIrD1YK5JF5oi2JePDS37uF4QmuEXGAh3e 7 | DlIRDozAqC0Oeg0zPVuFBFZy1iVy4NS8aYY9NiaKH3EMDVkzz077znw/cJp9+wHZ 8 | WQIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /cpio-archive/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # cpio-archive Crate Changelog 2 | 3 | 4 | 5 | ## Unreleased 6 | 7 | Released on ReleaseDate. 8 | 9 | ## 0.10.0 10 | 11 | Released on 2024-11-03. 12 | 13 | ## 0.9.0 14 | 15 | Released on 2024-01-17. 16 | 17 | ## 0.8.0 18 | 19 | Released on 2023-11-06. 20 | 21 | * Fixed `NewcReader` to correctly handle padding between header and file content. 22 | #68. Fix contributed by Youmu. 23 | 24 | ## 0.7.0 25 | 26 | Released on 2022-12-21. 27 | 28 | * Cargo.toml now defines patch version for all dependencies. 29 | 30 | ## 0.6.0 31 | 32 | Released on 2022-12-18. 33 | -------------------------------------------------------------------------------- /cpio-archive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cpio-archive" 3 | version = "0.10.0" 4 | authors = ["Gregory Szorc "] 5 | edition = "2021" 6 | license = "MPL-2.0" 7 | description = "cpio archive reading and writing" 8 | keywords = ["cpio"] 9 | homepage = "https://github.com/indygreg/apple-platform-rs" 10 | repository = "https://github.com/indygreg/apple-platform-rs.git" 11 | readme = "README.md" 12 | 13 | [dependencies] 14 | chrono = "0.4.38" 15 | is_executable = "1.0.4" 16 | simple-file-manifest = "0.11.0" 17 | thiserror = "2.0.3" 18 | -------------------------------------------------------------------------------- /cpio-archive/README.md: -------------------------------------------------------------------------------- 1 | # cpio-archive 2 | 3 | Pure Rust interface to cpio archive format. See crate documentation for more. 4 | -------------------------------------------------------------------------------- /cpio-archive/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. 4 | 5 | pub mod newc; 6 | pub use newc::{NewcHeader, NewcReader}; 7 | pub mod odc; 8 | pub use odc::{OdcBuilder, OdcHeader, OdcReader}; 9 | 10 | use { 11 | chrono::{DateTime, Utc}, 12 | std::{ 13 | fmt::Debug, 14 | io::{Chain, Cursor, Read}, 15 | path::PathBuf, 16 | }, 17 | }; 18 | 19 | #[derive(Debug, thiserror::Error)] 20 | pub enum Error { 21 | #[error("I/O error: {0}")] 22 | Io(#[from] std::io::Error), 23 | 24 | #[error("bad magic value encountered")] 25 | BadMagic, 26 | 27 | #[error("value in header is not an ASCII string")] 28 | BadHeaderString, 29 | 30 | #[error("string value in header is not in hex: {0}")] 31 | BadHeaderHex(String), 32 | 33 | #[error("filename could not be decoded")] 34 | FilenameDecode, 35 | 36 | #[error("Numeric value too large to be encoded")] 37 | ValueTooLarge, 38 | 39 | #[error("Size mismatch between header length and provided data")] 40 | SizeMismatch, 41 | 42 | #[error("path is not a file: {0}")] 43 | NotAFile(PathBuf), 44 | } 45 | 46 | /// Result type for this crate. 47 | pub type CpioResult = Result; 48 | 49 | /// Common behavior for a header/entry in a cpio archive. 50 | pub trait CpioHeader: Debug { 51 | /// Device number. 52 | fn device(&self) -> u32; 53 | 54 | /// Inode number. 55 | fn inode(&self) -> u32; 56 | 57 | /// File mode. 58 | fn mode(&self) -> u32; 59 | 60 | /// User ID. 61 | fn uid(&self) -> u32; 62 | 63 | /// Group ID. 64 | fn gid(&self) -> u32; 65 | 66 | /// Number of links. 67 | fn nlink(&self) -> u32; 68 | 69 | /// Associated device number. 70 | fn rdev(&self) -> u32; 71 | 72 | /// Modified time as seconds since UNIX epoch. 73 | fn mtime(&self) -> u32; 74 | 75 | /// Modified time as a [DateTime]. 76 | fn modified_time(&self) -> DateTime { 77 | DateTime::from_timestamp(self.mtime() as _, 0) 78 | .expect("out of range timestamp") 79 | .to_utc() 80 | } 81 | 82 | /// File size in bytes. 83 | fn file_size(&self) -> u64; 84 | 85 | /// File name. 86 | fn name(&self) -> &str; 87 | } 88 | 89 | /// Common interface for cpio archive reading. 90 | /// 91 | /// In addition to the members of this trait, instances implement [Iterator] over 92 | /// the members of the archive and [Read] to obtain a reader for the current 93 | /// archive member. 94 | /// 95 | /// Instances behave like a cursor over members of the archive. The cursor is 96 | /// advanced by calling [Self::read_next]. When the cursor is advanced, the 97 | /// [Read] trait will read data for this and only this archive member. The reader 98 | /// will hit EOF at the end of the current archive member. 99 | pub trait CpioReader: Iterator>> + Read 100 | where 101 | T: Read + Sized, 102 | { 103 | /// Construct a new instance from a reader. 104 | fn new(reader: T) -> Self 105 | where 106 | Self: Sized; 107 | 108 | /// Read the next header from the archive. 109 | /// 110 | /// `Some` on another file entry. `None` if at end of file. 111 | /// 112 | /// The special `TRAILER!!!` entry is not emitted. 113 | fn read_next(&mut self) -> CpioResult>>; 114 | 115 | /// Finish reading the current member. 116 | /// 117 | /// This will advance the reader to the next archive member if the 118 | /// current member hasn't been fully consumed. 119 | fn finish(&mut self) -> CpioResult<()>; 120 | } 121 | 122 | pub type ChainedCpioReader = dyn CpioReader>, T>>; 123 | 124 | /// Construct a new cpio archive reader. 125 | /// 126 | /// This will sniff the type of the cpio archive and return an appropriate 127 | /// instance. 128 | pub fn reader(mut reader: T) -> CpioResult>> { 129 | let mut magic = vec![0u8; 6]; 130 | reader.read_exact(&mut magic)?; 131 | 132 | match magic.as_ref() { 133 | crate::newc::MAGIC => Ok(Box::new(NewcReader::new(Cursor::new(magic).chain(reader)))), 134 | crate::odc::MAGIC => Ok(Box::new(OdcReader::new(Cursor::new(magic).chain(reader)))), 135 | _ => Err(Error::BadMagic), 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /release.toml: -------------------------------------------------------------------------------- 1 | allow-branch = ["main"] 2 | push-remote = "origin" 3 | pre-release-commit-message = "workspace: perform releases" 4 | tag-message = "{{crate_name}}: version {{version}}" 5 | tag-name = "{{crate_name}}/{{version}}" 6 | tag = true 7 | enable-features = [] 8 | enable-all-features = false 9 | dependent-version = "fix" 10 | 11 | pre-release-replacements = [ 12 | {file="CHANGELOG.md", search="Unreleased", replace="{{version}}"}, 13 | {file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}"}, 14 | {file="CHANGELOG.md", search="", replace="\n\n## Unreleased\n\nReleased on ReleaseDate.", exactly=1}, 15 | ] 16 | -------------------------------------------------------------------------------- /scripts/secure_download.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This Source Code Form is subject to the terms of the Mozilla Public 3 | # License, v. 2.0. If a copy of the MPL was not distributed with this 4 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 5 | 6 | # Securely download a file by validating its SHA-256 against expectations. 7 | 8 | import argparse 9 | import gzip 10 | import hashlib 11 | import http.client 12 | import pathlib 13 | import urllib.error 14 | import urllib.request 15 | 16 | 17 | def hash_path(p: pathlib.Path): 18 | h = hashlib.sha256() 19 | 20 | with p.open("rb") as fh: 21 | while True: 22 | chunk = fh.read(65536) 23 | if not chunk: 24 | break 25 | 26 | h.update(chunk) 27 | 28 | return h.hexdigest() 29 | 30 | 31 | class IntegrityError(Exception): 32 | """Represents an integrity error when downloading a URL.""" 33 | 34 | 35 | def secure_download_stream(url, sha256): 36 | """Securely download a URL to a stream of chunks. 37 | 38 | If the integrity of the download fails, an exception is raised. 39 | """ 40 | h = hashlib.sha256() 41 | 42 | with urllib.request.urlopen(url) as fh: 43 | if not url.endswith(".gz") and fh.info().get("Content-Encoding") == "gzip": 44 | fh = gzip.GzipFile(fileobj=fh) 45 | 46 | while True: 47 | chunk = fh.read(65536) 48 | if not chunk: 49 | break 50 | 51 | h.update(chunk) 52 | 53 | yield chunk 54 | 55 | digest = h.hexdigest() 56 | 57 | if digest != sha256: 58 | raise IntegrityError( 59 | "integrity mismatch on %s: wanted sha256=%s; got sha256=%s" 60 | % (url, sha256, digest) 61 | ) 62 | 63 | 64 | def download_to_path(url: str, path: pathlib.Path, sha256: str): 65 | # We download to a temporary file and rename at the end so there's 66 | # no chance of the final file being partially written or containing 67 | # bad data. 68 | print("downloading %s to %s" % (url, path)) 69 | 70 | if path.exists(): 71 | good = True 72 | 73 | if good: 74 | if hash_path(path) != sha256: 75 | print("existing file hash is wrong; removing") 76 | good = False 77 | 78 | if good: 79 | print("%s exists and passes integrity checks" % path) 80 | return 81 | 82 | path.unlink() 83 | 84 | tmp = path.with_name("%s.tmp" % path.name) 85 | 86 | path.parent.mkdir(parents=True, exist_ok=True) 87 | 88 | for _ in range(5): 89 | try: 90 | try: 91 | with tmp.open("wb") as fh: 92 | for chunk in secure_download_stream(url, sha256): 93 | fh.write(chunk) 94 | 95 | break 96 | except IntegrityError: 97 | tmp.unlink() 98 | raise 99 | except http.client.HTTPException as e: 100 | print("HTTP exception; retrying: %s" % e) 101 | except urllib.error.URLError as e: 102 | print("urllib error; retrying: %s" % e) 103 | else: 104 | raise Exception("download failed after multiple retries") 105 | 106 | tmp.rename(path) 107 | print("successfully downloaded %s" % url) 108 | 109 | 110 | def main(): 111 | parser = argparse.ArgumentParser() 112 | parser.add_argument("url", help="URL to download") 113 | parser.add_argument("sha256", help="Expected SHA-256 of downloaded file") 114 | parser.add_argument("dest", help="Destination path to write") 115 | 116 | args = parser.parse_args() 117 | 118 | download_to_path(args.url, pathlib.Path(args.dest), sha256=args.sha256) 119 | 120 | 121 | if __name__ == "__main__": 122 | main() 123 | -------------------------------------------------------------------------------- /terraform-modules/remote-code-signing/README.rst: -------------------------------------------------------------------------------- 1 | =============================================== 2 | Terraform Module for Remote Code Signing Server 3 | =============================================== 4 | 5 | This directory defines a Terraform module which provides a websocket server 6 | facilitating the exchange of messages between code signing peers. 7 | 8 | Overview 9 | ======== 10 | 11 | The Terraform module defines AWS resources for deploying a websocket server 12 | leveraging Lambda, API Gateway, and DynamoDB. To support this service it also 13 | needs to provision IAM and CloudWatch resources. It currently also uses ACM 14 | for an Amazon issued certificate to be used for API Gateway. However, this 15 | requirement could possibly be made optional. 16 | 17 | The ``websocket.py`` file is registered as a Lambda function. This Lambda 18 | function handles websocket connect, disconnect, and message events. 19 | 20 | Persistent state for the Lambda function is stored in a single DynamoDB table. 21 | Items in the table have a TTL, ensuring they automatically expire and don't 22 | accumulate space/costs. 23 | 24 | An API Gateway with a single stage is configured to send all websocket activity 25 | to the Lambda. There is no authentication for the API Gateway, so anyone with 26 | network access can speak to it. 27 | 28 | A custom API Gateway domain name is optionally registered and the API Gateway is 29 | bound to it if the ``hostname`` variable is passed to the module. 30 | 31 | Example Usage 32 | ============= 33 | 34 | This is a minimal example. It will not configure a domain name for API 35 | Gateway. 36 | 37 | .. code-block:: terraform 38 | 39 | module "remote_code_signing" { 40 | source = "/path/to/remote-code-signing" 41 | lambda_zip_path = "${path.root}/lambda.zip" 42 | } 43 | 44 | This example configures a hostname and registers Route 53 records for its 45 | DNS resolution. 46 | 47 | .. code-block:: terraform 48 | 49 | locals { 50 | route53_zone_id = "" 51 | hostname = "ws.codesign.gregoryszorc.com" 52 | } 53 | 54 | module "remote_code_signing" { 55 | source = "/path/to/remote-code-signing" 56 | lambda_zip_path = "${path.root}/lambda.zip" 57 | hostname = local.hostname 58 | } 59 | 60 | resource "aws_route53_record" "codesign" { 61 | name = local.hostname 62 | type = "A" 63 | zone_id = local.route53_zone_id 64 | alias { 65 | evaluate_target_health = true 66 | name = module.remote_code_signing.domain_name 67 | zone_id = module.remote_code_signing.domain_zone_id 68 | } 69 | } 70 | 71 | resource "aws_route53_record" "codesign_validation_validation" { 72 | for_each = { 73 | for dvo in module.remote_code_signing.domain_validation_options : dvo.resource_record_name => { 74 | name = dvo.resource_record_name 75 | record = dvo.resource_record_value 76 | type = dvo.resource_record_type 77 | } 78 | } 79 | name = each.value.name 80 | records = [each.value.record] 81 | type = each.value.type 82 | zone_id = local.route53_zone_id 83 | ttl = 60 84 | allow_overwrite = true 85 | } 86 | 87 | Additional Customization 88 | ======================== 89 | 90 | The module has various additional variables to control behavior. e.g. 91 | the names of most resources can be modified from their defaults. Look 92 | for ``variable`` blocks at the top of ``main.tf`` for more. 93 | --------------------------------------------------------------------------------