| 130 | |
| 131 | |
| 132 | class AzureSignTool(SigningTool): |
| 133 | def __init__(self): |
| 134 | super().__init__(os.environ.get("AZURE_SIGNTOOL_PATH", "AzureSignTool")) |
| 135 | |
| 136 | def get_signing_command(self) -> str: |
| 137 | required_env_vars = ( |
| 138 | "AZURE_SIGNTOOL_KEY_VAULT_URL", |
| 139 | "AZURE_SIGNTOOL_KEY_VAULT_CERTIFICATE", |
| 140 | ) |
| 141 | check_required_env_vars(required_env_vars) |
| 142 | timestamp_server = os.environ.get( |
| 143 | "AZURE_SIGNTOOL_TIMESTAMP_SERVER_URL", "http://timestamp.sectigo.com" |
| 144 | ) |
| 145 | timestamp_digest = os.environ.get("AZURE_SIGNTOOL_TIMESTAMP_DIGEST", "sha256") |
| 146 | file_digest = os.environ.get("AZURE_SIGNTOOL_FILE_DIGEST", "sha256") |
| 147 | |
| 148 | command = ( |
| 149 | f"{win_str_esc(self.executable)} sign -v" |
| 150 | ' -kvu "%AZURE_SIGNTOOL_KEY_VAULT_URL%"' |
| 151 | ' -kvc "%AZURE_SIGNTOOL_KEY_VAULT_CERTIFICATE%"' |
| 152 | f' -tr "{timestamp_server}"' |
| 153 | f" -td {timestamp_digest}" |
| 154 | f" -fd {file_digest}" |
| 155 | ) |
| 156 | # There are three ways to sign: |
| 157 | # 1. Access token |
| 158 | # 2. Secret (requires tenant ID) |
| 159 | # 3. Managed identity (requires prior login to Azure) |
| 160 | if "AZURE_SIGNTOOL_KEY_VAULT_ACCESSTOKEN" in os.environ: |
| 161 | logger.info("AzureSignTool: signing binary using access token.") |
| 162 | command += ' -kva "%AZURE_SIGNTOOL_KEY_VAULT_ACCESSTOKEN%"' |
| 163 | elif "AZURE_SIGNTOOL_KEY_VAULT_SECRET" in os.environ: |
| 164 | # Authentication via secret required client and tenant ID |
| 165 | logger.info("AzureSignTool: signing binary using secret.") |
| 166 | required_env_vars = ( |
| 167 | "AZURE_SIGNTOOL_KEY_VAULT_CLIENT_ID", |
| 168 | "AZURE_SIGNTOOL_KEY_VAULT_TENANT_ID", |
| 169 | ) |
| 170 | check_required_env_vars(required_env_vars) |
| 171 | command += ( |
| 172 | ' -kvi "%AZURE_SIGNTOOL_KEY_VAULT_CLIENT_ID%"' |
| 173 | ' -kvt "%AZURE_SIGNTOOL_KEY_VAULT_TENANT_ID%"' |
| 174 | ' -kvs "%AZURE_SIGNTOOL_KEY_VAULT_SECRET%"' |
| 175 | ) |
| 176 | else: |
| 177 | # No token or secret found, assume managed identity |
| 178 | logger.info("AzureSignTool: signing binary using managed identity.") |
| 179 | command += " -kvm" |
| 180 | return command |
| 181 | |
| 182 | def verify_signing_tool(self): |
| 183 | self._verify_tool_is_available() |
| 184 | check_call([self.executable, "--help"], stdout=PIPE, stderr=PIPE) |
| 185 | |
| 186 | def verify_signature(self, installer_file: str | Path): |
| 187 | """Use Powershell to verify signature. |
| 188 | |
| 189 | For available statuses, see the Microsoft documentation: |
no outgoing calls
no test coverage detected