mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/telegramdesktop/tdesktop
synced 2026-09-20 08:03:45 +08:00
Try to fix signing.
This commit is contained in:
15
.github/workflows/canary.yml
vendored
15
.github/workflows/canary.yml
vendored
@@ -657,10 +657,14 @@ jobs:
|
||||
# Report every failing file in one run rather than the first.
|
||||
defaults write com.apple.dt.Xcode IDEBuildingContinueBuildingAfterErrors -bool YES
|
||||
|
||||
# No LTO on the macOS canary: the full-LTO x86_64 link of the
|
||||
# universal app took 4h39m on the Depot runner (arm64: 8 min),
|
||||
# turning a ~40 minute job into 5+ hours. Release builds keep
|
||||
# LTO on the release machine; revisit with ThinLTO or a larger
|
||||
# runner if the canary binaries need to match exactly.
|
||||
./configure.sh \
|
||||
-D CMAKE_CONFIGURATION_TYPES=Release \
|
||||
-D CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=NO \
|
||||
-D DESKTOP_APP_ENABLE_LTO=ON \
|
||||
-D CMAKE_OSX_ARCHITECTURES="x86_64;arm64" \
|
||||
-D TDESKTOP_API_ID=${{ secrets.CANARY_API_ID }} \
|
||||
-D TDESKTOP_API_HASH=${{ secrets.CANARY_API_HASH }} \
|
||||
@@ -956,8 +960,15 @@ jobs:
|
||||
run: |
|
||||
cd out/Release
|
||||
mkdir -p symbols
|
||||
# dump_syms is built into the centos_env image (breakpad), so
|
||||
# it runs there against the same binaries mounted from the
|
||||
# host; the release flow copies the tool out by hand instead.
|
||||
for MODULE in Telegram Updater; do
|
||||
./dump_syms $MODULE > $MODULE.sym
|
||||
docker run --rm \
|
||||
-u $(id -u) \
|
||||
-v $PWD:/out -w /out \
|
||||
$IMAGE_TAG \
|
||||
dump_syms $MODULE > $MODULE.sym
|
||||
DEBUG_ID=$(head -n 1 $MODULE.sym | awk '{ print $4 }')
|
||||
mkdir -p symbols/$MODULE/$DEBUG_ID
|
||||
mv $MODULE.sym symbols/$MODULE/$DEBUG_ID/
|
||||
|
||||
@@ -7,14 +7,15 @@
|
||||
|
||||
# ES256 signing glue for the v2 update packer, shared by build.bat,
|
||||
# build.sh and canary.yml. Standard library only: the actual signing
|
||||
# happens in Azure Key Vault (az keyvault key sign) or, for local
|
||||
# happens in Azure Key Vault (REST sign with an az token) or, for local
|
||||
# testing, in an openssl subprocess.
|
||||
#
|
||||
# The packer emits a signing-input file (-emit-signing-input), this
|
||||
# script signs its SHA-256 and writes the raw r||s (64 bytes) signature
|
||||
# that the packer embeds (-embed-signatures id:sigfile). ES256 keys sign
|
||||
# SHA256(signing_input); Ed25519 keys are signed by the packer itself
|
||||
# in-process (-local-key), never through this script.
|
||||
# in-process (-local-key), never through this script. Azure signing goes
|
||||
# through the Key Vault REST API with a token from the az session.
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
@@ -23,6 +24,8 @@ import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
|
||||
def b64url(data: bytes) -> str:
|
||||
@@ -73,26 +76,59 @@ def der_to_raw_rs(der: bytes) -> bytes:
|
||||
return r + s
|
||||
|
||||
|
||||
def sign_azure(digest: bytes, args) -> bytes:
|
||||
def az_access_token() -> str:
|
||||
# On Windows the CLI is az.cmd, which a plain 'az' argv misses.
|
||||
command = [
|
||||
shutil.which('az') or 'az', 'keyvault', 'key', 'sign',
|
||||
'--vault-name', args.az_vault,
|
||||
'--name', args.az_key,
|
||||
'--algorithm', 'ES256',
|
||||
'--digest', b64url(digest),
|
||||
'--output', 'json',
|
||||
'--only-show-errors',
|
||||
]
|
||||
if args.az_key_version:
|
||||
command += ['--version', args.az_key_version]
|
||||
result = subprocess.run(command, capture_output=True, text=True)
|
||||
result = subprocess.run(
|
||||
[
|
||||
shutil.which('az') or 'az', 'account', 'get-access-token',
|
||||
'--resource', 'https://vault.azure.net',
|
||||
'--query', 'accessToken',
|
||||
'--output', 'tsv',
|
||||
'--only-show-errors',
|
||||
],
|
||||
capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError('az keyvault key sign failed: ' + result.stderr)
|
||||
signature = b64url_decode(json.loads(result.stdout)['signature'])
|
||||
raise RuntimeError('az account get-access-token failed: ' + result.stderr)
|
||||
token = result.stdout.strip()
|
||||
if not token:
|
||||
raise RuntimeError('az account get-access-token returned no token')
|
||||
return token
|
||||
|
||||
|
||||
def key_vault_request(token: str, url: str, body=None) -> dict:
|
||||
data = json.dumps(body).encode() if body is not None else None
|
||||
request = urllib.request.Request(url, data=data, method='POST' if data else 'GET')
|
||||
request.add_header('Authorization', 'Bearer ' + token)
|
||||
request.add_header('Content-Type', 'application/json')
|
||||
try:
|
||||
with urllib.request.urlopen(request, timeout=60) as response:
|
||||
return json.loads(response.read().decode())
|
||||
except urllib.error.HTTPError as error:
|
||||
raise RuntimeError('Key Vault %s failed: HTTP %d %s' % (
|
||||
url, error.code, error.read().decode(errors='replace')))
|
||||
|
||||
|
||||
def sign_azure(digest: bytes, args) -> bytes:
|
||||
# The Key Vault REST API is called directly: "az keyvault key sign"
|
||||
# wants the digest as standard base64 but then serializes the raw
|
||||
# signature bytes through str.decode(), which is not a usable
|
||||
# transport for an ECDSA signature. The token comes from the az
|
||||
# session azure/login (OIDC) or an interactive az login set up.
|
||||
token = az_access_token()
|
||||
base = 'https://%s.vault.azure.net/keys/%s' % (args.az_vault, args.az_key)
|
||||
if args.az_key_version:
|
||||
key_id = base + '/' + args.az_key_version
|
||||
else:
|
||||
key_id = key_vault_request(token, base + '?api-version=7.4')['key']['kid']
|
||||
result = key_vault_request(
|
||||
token,
|
||||
key_id + '/sign?api-version=7.4',
|
||||
{'alg': 'ES256', 'value': b64url(digest)})
|
||||
signature = b64url_decode(result['value'])
|
||||
if len(signature) != 64:
|
||||
raise RuntimeError(
|
||||
'unexpected Key Vault signature size: %d' % len(signature))
|
||||
'unexpected Key Vault signature size: %d (from %r)'
|
||||
% (len(signature), result['value']))
|
||||
return signature
|
||||
|
||||
|
||||
@@ -118,7 +154,7 @@ def main():
|
||||
help='where to write the raw r||s (64 bytes) signature')
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument('--az-vault',
|
||||
help='Azure Key Vault name (signs with az keyvault key sign)')
|
||||
help='Azure Key Vault name (signs through the Key Vault REST API)')
|
||||
group.add_argument('--openssl-key',
|
||||
help='local P-256 private key PEM (testing stub)')
|
||||
parser.add_argument('--az-key',
|
||||
|
||||
Reference in New Issue
Block a user