From a2dcf87e10ad4119bfb1aa740cb4701a163c7372 Mon Sep 17 00:00:00 2001
From: Nikolaj Bjorner <nbjorner@microsoft.com>
Date: Wed, 27 Feb 2019 14:43:39 -0800
Subject: [PATCH] add ESRP signing of nuget packages

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
---
 scripts/authorization.json  | 15 ++++++++++
 scripts/mk_nuget_release.py | 57 +++++++++++++++++++++++++++++++++++--
 scripts/policy.json         |  8 ++++++
 3 files changed, 78 insertions(+), 2 deletions(-)
 create mode 100644 scripts/authorization.json
 create mode 100644 scripts/policy.json

diff --git a/scripts/authorization.json b/scripts/authorization.json
new file mode 100644
index 000000000..97fb21dfa
--- /dev/null
+++ b/scripts/authorization.json
@@ -0,0 +1,15 @@
+{
+  "Version": "1.0.0",
+  "AuthenticationType": "AAD_CERT",
+  "ClientId": "1c614a83-2dbe-4d3c-853b-effaefd4fb20",
+  "AuthCert": {
+    "SubjectName": "1c614a83-2dbe-4d3c-853b-effaefd4fb20.microsoft.com",
+    "StoreLocation": "LocalMachine",
+    "StoreName": "My"
+  },
+  "RequestSigningCert": {
+    "SubjectName": "1c614a83-2dbe-4d3c-853b-effaefd4fb20",
+    "StoreLocation": "LocalMachine",
+    "StoreName": "My"
+  }
+}
diff --git a/scripts/mk_nuget_release.py b/scripts/mk_nuget_release.py
index db7a1af64..ebd0e0ba7 100644
--- a/scripts/mk_nuget_release.py
+++ b/scripts/mk_nuget_release.py
@@ -7,6 +7,7 @@
 # 3. copy over Microsoft.Z3.dll from suitable distribution
 # 4. copy nuspec file from packages
 # 5. call nuget pack
+# 6. sign package
 
 import json
 import os
@@ -22,6 +23,7 @@ import mk_project
 data = json.loads(urllib.request.urlopen("https://api.github.com/repos/Z3Prover/z3/releases/latest").read().decode())
 
 version_str = data['tag_name']
+version_num = version_str[3:]
 
 print(version_str)
 
@@ -50,7 +52,8 @@ def classify_package(f):
             ext, dst = os_info[os_name]
             return os_name, f[:-4], ext, dst
     return None
-        
+
+
 def unpack():
     shutil.rmtree("out", ignore_errors=True)
     # unzip files in packages
@@ -103,17 +106,67 @@ Linux Dependencies:
 </package>"""
 
     with open("out/Microsoft.Z3.nuspec", 'w') as f:
-        f.write(contents % version_str[3:])
+        f.write(contents % version_num)
         
 def create_nuget_package():
     subprocess.call(["nuget", "pack"], cwd="out")
 
+nuget_sign_input = """
+{
+  "Version": "1.0.0",
+  "SignBatches"
+  :
+  [
+   {
+    "SourceLocationType": "UNC",
+    "SourceRootDirectory": "%s",
+    "DestinationLocationType": "UNC",
+    "DestinationRootDirectory": "%s",
+    "SignRequestFiles": [
+     {
+      "CustomerCorrelationId": "42fc9577-af9e-4ac9-995d-1788d8721d17",
+      "SourceLocation": "Microsoft.Z3.%s.nupkg",
+      "DestinationLocation": "Microsoft.Z3.%s.nupkg"
+     }
+    ],
+    "SigningInfo": {
+     "Operations": [
+      {
+       "KeyCode" : "CP-401405",
+       "OperationCode" : "NuGetSign",
+       "Parameters" : {},
+       "ToolName" : "sign",
+       "ToolVersion" : "1.0"
+      },
+      {
+       "KeyCode" : "CP-401405",
+       "OperationCode" : "NuGetVerify",
+       "Parameters" : {},
+       "ToolName" : "sign",
+       "ToolVersion" : "1.0"
+      }
+     ]
+    }
+   }
+  ]
+}"""
+
+def sign_nuget_package():
+    package_name = "Microsoft.Z3.%s.nupkg" % version_num
+    input_file = "out/nuget_sign_input.json"
+    output_path = os.path.abspath("out").replace("\\","\\\\") 
+    with open(input_file, 'w') as f:
+        f.write(nuget_sign_input % (output_path, output_path, version_num, version_num))
+    subprocess.call(["EsrpClient.exe", "sign", "-a", "authorization.json", "-p", "policy.json", "-i", input_file, "-o", "out\\diagnostics.json"])
+    
+    
 def main():
     mk_dir("packages")
     download_installs()
     unpack()
     create_nuget_spec()
     create_nuget_package()
+    sign_nuget_package()
 
 
 main()
diff --git a/scripts/policy.json b/scripts/policy.json
new file mode 100644
index 000000000..badebe683
--- /dev/null
+++ b/scripts/policy.json
@@ -0,0 +1,8 @@
+{
+  "Version": "1.0.0",
+  "Intent": "ProductRelease",
+  "ContentType": "Binaries",
+  "ContentOrigin": "1stParty",
+  "ProductState": "Next",
+  "Audience": "ExternalBroad"
+}