windows_signing.md
1 # Windows Signing 2 3 # Description 4 5 This document describes how the signing of Windows application was configured. 6 7 # Certificates 8 9 The signing uses two types of Certificates: 10 11 * Self-Signed Code Signing certificate for development and PR builds 12 * [DigiCert](https://www.digicert.com/) standard release Code Signing certificate 13 14 ## Self-Signed Certificate 15 16 This certificate was created on using the following PowerShell commands: 17 ```Powershell 18 $cert = New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname status.im -Subject "Dev Status Cert" -type CodeSigning 19 $pwd = ConvertTo-SecureString -String 'SUPER-SECRET-PASSWORD -Force -AsPlainText 20 Export-PfxCertificate -cert $cert -FilePath Status-Destkop-SelfSigned.pfx -Password $pwd -CryptoAlgorithmOption AES256_SHA256 21 ``` 22 Which should create a `Status-Destkop-SelfSigned.pfx` file encrypted with the provided password. 23 24 Keep in mind that the `-type CodeSigning` flag is important. 25 26 For more details see [this article](http://woshub.com/how-to-create-self-signed-certificate-with-powershell/). 27 28 ## DigiCert Certificate 29 30 This certificate is was purchased on 23rd of September 2020 from [DigiCert.com](https://www.digicert.com/). 31 It is a `Microsoft Authenticode` certificate and should be valid for 2 years. 32 33 # Continuous Integration 34 35 The Jenkins setup which makes use of these certificates makes them available under different job folder under different credential names. This way we can sign non-release builds while not making them appear to a user as a release build. The self-signed certificate should trigger windows warnings when starting the application. 36 37 The way this works is certificates are split across two Jenkins job folders: 38 39 * [status-desktop/platforms](https://ci.status.im/job/status-desktop/job/platforms/credentials/store/folder/domain/_/) - Release and Nightly builds. 40 * [status-desktop/branches](https://ci.status.im/job/status-desktop/job/branches/credentials/store/folder/domain/_/) - Branch and PR builds. 41 42 These folders contain different certificates, which provides another layer of security in case someone submits a malicious PR which attempts to extract valuable secrets. In this setup the only thing they might possibly extract would be the self-signed certificate and its password. 43 44 The exact access to the credentials is hidden from malicious eyes that can inspect `Jenkinsfile`s in this repo, and instead are implemented in our private [`status-jenkins-lib`](https://github.com/status-im/status-jenkins-lib) repository under `vars/windows.groovy`. 45 46 # Known Issues 47 48 #### `Error: Store::ImportCertObject() failed. (-2146893808/0x80090010)` 49 50 This error would appears when trying to sign binaries with `signtool.exe` when Jenkins was accessing the Windows CI slave via SSH. 51 52 The solution was to switch the setup to deploy the [Jenkins Remoting Agent Service](https://www.jenkins.io/projects/remoting/) using the [WinSW](https://github.com/winsw/winsw) utility to run it as a Windows service. 53 54 #### `CertEnroll::CX509Enrollment::_CreateRequest: Access denied. 0x80090010 (-2146893808 NTE_PERM)` 55 56 You cannot create a self-signed certificate in a PowerShell instance without elevated privilidges. You might have to run the shell as system administrator. 57 58 # Links 59 60 * https://github.com/status-im/infra-ci/issues/28 61 * https://github.com/status-im/status-desktop/issues/2170