Skip to content

Commit 082cb0f

Browse files
committed
linux: port Debian package signing
Port Debian package signing workflow and scripts from GCM Core. This is a "good enough for now" state; we should revisit these scripts and clean them up, when we look to port Windows and macOS signing to this model.
1 parent f2072b6 commit 082cb0f

2 files changed

Lines changed: 236 additions & 0 deletions

File tree

.github/run_esrp_signing.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import json
2+
import os
3+
import glob
4+
import pprint
5+
import subprocess
6+
import sys
7+
8+
esrp_tool = os.path.join("esrp", "tools", "EsrpClient.exe")
9+
10+
aad_id = os.environ['AZURE_AAD_ID'].strip()
11+
workspace = os.environ['GITHUB_WORKSPACE'].strip()
12+
13+
source_root_location = os.path.join(workspace, "tosign")
14+
destination_location = os.path.join(workspace)
15+
16+
scalar_files = glob.glob(os.path.join(source_root_location, "scalar-linux*.deb"))
17+
azrepos_files = glob.glob(os.path.join(source_root_location, "scalar-azrepos-linux*.deb"))
18+
19+
print("Found files:")
20+
pprint.pp(scalar_files)
21+
pprint.pp(azrepos_files)
22+
23+
if len(scalar_files) < 1 or not scalar_files[0].endswith(".deb"):
24+
print("Error: cannot find scalar .deb to sign")
25+
exit(1)
26+
27+
if len(azrepos_files) < 1 or not azrepos_files[0].endswith(".deb"):
28+
print("Error: cannot find scalar-azrepos .deb to sign")
29+
exit(1)
30+
31+
scalar_to_sign = os.path.basename(scalar_files[0])
32+
azrepos_to_sign = os.path.basename(azrepos_files[0])
33+
34+
auth_json = {
35+
"Version": "1.0.0",
36+
"AuthenticationType": "AAD_CERT",
37+
"TenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
38+
"ClientId": aad_id,
39+
"AuthCert": {
40+
"SubjectName": f"CN={aad_id}.microsoft.com",
41+
"StoreLocation": "LocalMachine",
42+
"StoreName": "My",
43+
},
44+
"RequestSigningCert": {
45+
"SubjectName": f"CN={aad_id}",
46+
"StoreLocation": "LocalMachine",
47+
"StoreName": "My",
48+
}
49+
}
50+
51+
input_json = {
52+
"Version": "1.0.0",
53+
"SignBatches": [
54+
{
55+
"SourceLocationType": "UNC",
56+
"SourceRootDirectory": source_root_location,
57+
"DestinationLocationType": "UNC",
58+
"DestinationRootDirectory": destination_location,
59+
"SignRequestFiles": [
60+
{
61+
"CustomerCorrelationId": "01A7F55F-6CDD-4123-B255-77E6F212CDAD",
62+
"SourceLocation": scalar_to_sign,
63+
"DestinationLocation": os.path.join("signed", scalar_to_sign),
64+
},
65+
{
66+
"CustomerCorrelationId": "01A7F55F-6CDD-4123-B255-77E6F212CDAD",
67+
"SourceLocation": azrepos_to_sign,
68+
"DestinationLocation": os.path.join("signed", azrepos_to_sign),
69+
}
70+
],
71+
"SigningInfo": {
72+
"Operations": [
73+
{
74+
"KeyCode": "CP-450779-Pgp",
75+
"OperationCode": "LinuxSign",
76+
"Parameters": {},
77+
"ToolName": "sign",
78+
"ToolVersion": "1.0",
79+
}
80+
]
81+
}
82+
}
83+
]
84+
}
85+
86+
policy_json = {
87+
"Version": "1.0.0",
88+
"Intent": "production release",
89+
"ContentType": "Debian package",
90+
}
91+
92+
configs = [
93+
("auth.json", auth_json),
94+
("input.json", input_json),
95+
("policy.json", policy_json),
96+
]
97+
98+
for filename, data in configs:
99+
with open(filename, 'w') as fp:
100+
json.dump(data, fp)
101+
102+
# Run ESRP Client
103+
esrp_out = "esrp_out.json"
104+
result = subprocess.run(
105+
[esrp_tool, "sign",
106+
"-a", "auth.json",
107+
"-i", "input.json",
108+
"-p", "policy.json",
109+
"-o", esrp_out,
110+
"-l", "Verbose"],
111+
cwd=workspace)
112+
113+
if result.returncode != 0:
114+
print("Failed to run ESRPClient.exe")
115+
sys.exit(1)
116+
117+
if os.path.isfile(esrp_out):
118+
print("ESRP output json:")
119+
with open(esrp_out, 'r') as fp:
120+
pprint.pp(json.load(fp))
121+
122+
scalar_signed = os.path.join(destination_location, "signed", scalar_to_sign)
123+
if os.path.isfile(scalar_signed):
124+
print(f"Success!\nSigned {scalar_signed}")
125+
126+
azrepos_to_sign = os.path.join(destination_location, "signed", azrepos_to_sign)
127+
if os.path.isfile(azrepos_to_sign):
128+
print(f"Success!\nSigned {azrepos_to_sign}")
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
name: "Build Signed Debian Packages"
2+
3+
on:
4+
workflow_dispatch:
5+
release:
6+
types: [released]
7+
8+
jobs:
9+
build:
10+
name: Build
11+
runs-on: ubuntu-18.04
12+
steps:
13+
- uses: actions/checkout@v2
14+
15+
- name: Setup .NET Core
16+
uses: actions/setup-dotnet@v1
17+
with:
18+
dotnet-version: 3.1.302
19+
20+
- name: Install dependencies
21+
run: dotnet restore --force
22+
23+
- name: Build Linux packages
24+
run: |
25+
BRANCH=$(git branch --show-current)
26+
if [ "${BRANCH:0:9}" = "releases/" ]; then
27+
SCALARVERSION="${BRANCH:9}".0
28+
else
29+
SCALARVERSION=0.3.132.0
30+
fi
31+
echo $SCALARVERSION
32+
dotnet publish -c Release -p:ScalarVersion=$SCALARVERSION 'Scalar.Packaging.Linux/Scalar.Packaging.Linux.csproj'
33+
34+
# Because the actions/upload-artifact action does not allow you to specify
35+
# relative file paths we must first use a shell script to copy the
36+
# artifacts to a different directory.
37+
- name: Collect packages
38+
shell: bash
39+
run: |
40+
rm -rf to_upload
41+
mkdir to_upload
42+
cp ../out/Scalar.Packaging.Linux/deb/Release/*.deb to_upload
43+
44+
- name: Upload packages
45+
uses: actions/upload-artifact@v2
46+
with:
47+
name: DebianUnsigned
48+
path: to_upload/*
49+
50+
sign:
51+
name: Sign
52+
runs-on: windows-latest
53+
needs: build
54+
steps:
55+
- name: setup python
56+
uses: actions/setup-python@v2
57+
with:
58+
python-version: 3.8
59+
60+
- uses: actions/checkout@v2
61+
62+
- name: 'Download Unsigned Packages'
63+
uses: actions/download-artifact@v2
64+
with:
65+
name: DebianUnsigned
66+
path: tosign
67+
68+
- uses: Azure/login@v1.1
69+
with:
70+
creds: ${{ secrets.AZURE_CREDENTIALS }}
71+
72+
- name: 'Install ESRP Client'
73+
shell: pwsh
74+
env:
75+
AZ_SUB: ${{ secrets.AZURE_SUBSCRIPTION }}
76+
run: |
77+
az storage blob download --subscription "$env:AZ_SUB" --account-name gitcitoolstore -c tools -n microsoft.esrpclient.1.2.47.nupkg -f esrp.zip
78+
Expand-Archive -Path esrp.zip -DestinationPath .\esrp
79+
80+
- name: Install Certificates
81+
shell: pwsh
82+
env:
83+
AZ_SUB: ${{ secrets.AZURE_SUBSCRIPTION }}
84+
AZ_VAULT: ${{ secrets.AZURE_VAULT }}
85+
SSL_CERT: ${{ secrets.VAULT_SSL_CERT_NAME }}
86+
ESRP_CERT: ${{ secrets.VAULT_ESRP_CERT_NAME }}
87+
run: |
88+
az keyvault secret download --subscription "$env:AZ_SUB" --vault-name "$env:AZ_VAULT" --name "$env:SSL_CERT" -f out.pfx
89+
certutil -f -importpfx out.pfx
90+
Remove-Item out.pfx
91+
92+
az keyvault secret download --subscription "$env:AZ_SUB" --vault-name "$env:AZ_VAULT" --name "$env:ESRP_CERT" -f out.pfx
93+
certutil -f -importpfx out.pfx
94+
Remove-Item out.pfx
95+
96+
- name: Run ESRP Client
97+
shell: pwsh
98+
env:
99+
AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }}
100+
run: |
101+
python .github/run_esrp_signing.py
102+
103+
- name: Upload Signed Packages
104+
uses: actions/upload-artifact@v2
105+
with:
106+
name: DebianSigned
107+
path: |
108+
signed/*.deb

0 commit comments

Comments
 (0)