pub fn create_self_signed_code_signing_certificate(
    algorithm: KeyAlgorithm,
    profile: CertificateProfile,
    team_id: &str,
    person_name: &str,
    country: &str,
    validity_duration: Duration
) -> Result<(CapturedX509Certificate, InMemorySigningKeyPair, Document), AppleCodesignError>
Expand description

Create a new self-signed X.509 certificate suitable for signing code.

The created certificate contains all the extensions needed to convey that it is used for code signing and should resemble certificates.

However, because the certificate isn’t signed by Apple or another trusted certificate authority, binaries signed with the certificate may not pass Apple’s verification requirements and the OS may refuse to proceed. Needless to say, only use certificates generated with this function for testing purposes only.

Examples found in repository?
src/cli.rs (lines 1734-1741)
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
fn command_generate_self_signed_certificate(args: &ArgMatches) -> Result<(), AppleCodesignError> {
    let algorithm = match args
        .get_one::<String>("algorithm")
        .ok_or(AppleCodesignError::CliBadArgument)?
        .as_str()
    {
        "ecdsa" => KeyAlgorithm::Ecdsa(EcdsaCurve::Secp256r1),
        "ed25519" => KeyAlgorithm::Ed25519,
        value => panic!(
            "algorithm values should have been validated by arg parser: {value}"
        ),
    };

    let profile = args
        .get_one::<String>("profile")
        .ok_or(AppleCodesignError::CliBadArgument)?;
    let profile = CertificateProfile::from_str(profile)?;
    let team_id = args
        .get_one::<String>("team_id")
        .ok_or(AppleCodesignError::CliBadArgument)?;
    let person_name = args
        .get_one::<String>("person_name")
        .ok_or(AppleCodesignError::CliBadArgument)?;
    let country_name = args
        .get_one::<String>("country_name")
        .ok_or(AppleCodesignError::CliBadArgument)?;

    let validity_days = args.get_one::<String>("validity_days").unwrap();
    let validity_days =
        i64::from_str(validity_days).map_err(|_| AppleCodesignError::CliBadArgument)?;

    let pem_filename = args.get_one::<String>("pem_filename");

    let validity_duration = chrono::Duration::days(validity_days);

    let (cert, _, raw) = create_self_signed_code_signing_certificate(
        algorithm,
        profile,
        team_id,
        person_name,
        country_name,
        validity_duration,
    )?;

    let cert_pem = cert.encode_pem();
    let key_pem = pem::encode(&pem::Pem {
        tag: "PRIVATE KEY".to_string(),
        contents: raw.as_ref().to_vec(),
    });

    let mut wrote_file = false;

    if let Some(pem_filename) = pem_filename {
        let cert_path = PathBuf::from(format!("{pem_filename}.crt"));
        let key_path = PathBuf::from(format!("{pem_filename}.key"));

        if let Some(parent) = cert_path.parent() {
            std::fs::create_dir_all(parent)?;
        }

        println!("writing public certificate to {}", cert_path.display());
        std::fs::write(&cert_path, cert_pem.as_bytes())?;
        println!("writing private signing key to {}", key_path.display());
        std::fs::write(&key_path, key_pem.as_bytes())?;

        wrote_file = true;
    }

    if !wrote_file {
        print!("{cert_pem}");
        print!("{key_pem}");
    }

    Ok(())
}