简体   繁体   中英

Build fails when signing code in Azure Pipeline

I've searched everything I can think of and cannot find the solution. I've got a ClickOnce application that I am attempting to sign with a certificate that was created by our in house Certificate Authority. On my local machine, I can sign the code without issue, but when trying to build in an Azure Pipeline, I started running into issues.

I first attempted the typical route of checking the 'Sign the ClickOnce manifests' in VisualStudio. I then selected the cert and entered the password. The cert was imported into the certificate store and I was able to build on my local machine.

在此处输入图像描述

When running the pipeline in Azure, I got an error that due to the password, the certificate couldn't be imported. So I added the.pfx file in the Azure Library as a secure file, and added two tasks to my pipeline - one to download the secure file, and a Powershell task to import the cert. Once the cert was being imported successfully, my VSBuild task started failing with the following error.

An error occurred while signing: Failed to sign {AppName.exe}. SignTool Error: The signer's certificate is not valid for signing.

Most of the Google results for this error are due to an expired cert, but the cert I'm using was just generated within the past month and the expiration is several years out.

I have attempted countless different ways of getting this app to sign, all of which have resulted in the same error. Some of these attempts include:

  • using MSBuild task instead of VisualStudio Build
  • unchecked the 'Sign ClickOnce' and added custom targets in the.csproj file to execute commands for signtool.exe so I could fine tune which parameters to pass
  • use a Powershell script after the build (with no signing) to attempt to sign the manifests using Mage.exe

I've discussed this with our server admin and our Active Directory group and haven't had any luck getting this resolved as our organization primarily does web applications. This is the only clickonce application that I'm aware of in our organization.

This app has been around since 2013 and is only used by in house staff, but has recently been getting quarantined by Symantec because it's not signed, so I need to figure out how to sign it and get it to build in DevOps.

Our pipelines use an On Prem server (Server 2012 R2) if that helps determine the issue.

EDIT: To include a sample of the custom targets I've tried in the.csproj. This was my latest attempt where I added a timestamp url. I originally attempted without the timestamp server.

Also, I tried commenting out the AfterCompile target. The build would get past that part, and it would actually sign the manifest successfully using mage.exe, but then would fail on the last command that uses signtool.exe to sign the setup.exe. It seems that the issue is with signtool.exe and not necessarily an issue with the certificate since mage.exe can sign with it.

<PropertyGroup>
  <CertPath>
  </CertPath>
  <CertPass>
  </CertPass>
  </PropertyGroup>
  <Target Name="AfterCompile" Condition="'$(Configuration)|$(Platform)' != 'Debug|x86' ">
  <Exec Command="&quot;C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe&quot; sign /f &quot;$(CertPath)&quot; /fd sha256 /p $(CertPass) /v /t &quot;http://timestamp.comodoca.com?td=sha256&quot; &quot;$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\$(TargetFileName)&quot;" />
  </Target>
  <Target Name="SignManifest" AfterTargets="_DeploymentSignClickOnceDeployment" Condition="'$(Configuration)|$(Platform)' != 'Debug|x86' ">
  <Exec Command="&quot;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools\mage.exe&quot; -Sign &quot;$(_DeploymentApplicationDir)$(_DeploymentTargetApplicationManifestFileName)&quot; -cf $(CertPath) -pwd $(CertPass)" />
  <Exec Command="&quot;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools\mage.exe&quot; -Update &quot;$(PublishDir)$(TargetDeployManifestFileName)&quot; -AppManifest &quot;$(_DeploymentApplicationDir)$(_DeploymentTargetApplicationManifestFileName)&quot;" />
  <Exec Command="&quot;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools\mage.exe&quot; -Sign &quot;$(PublishDir)$(TargetDeployManifestFileName)&quot; -cf $(CertPath) -pwd $(CertPass)" />
  <Exec Command="&quot;C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe&quot; sign /f $(CertPath) /fd sha256 /p $(CertPass) /v /t &quot;http://timestamp.comodoca.com?td=sha256&quot; &quot;$(PublishDir)\setup.exe&quot;" />
  </Target>

And the relevant section of the build log.

在此处输入图像描述

Disclaimer: I am the owner of this tool.

I recently made an open-source add-in for Azure Pipelines that might solve this for you, available on the Azure DevOps Marketplace ( source is MIT, available on GitHub ). It works in either hosted or on-prem agents.

Simply build your app as normal (no need to publish in the build pipeline), then set up the ClickOnce Package task as a step in your deployment pipeline. Based on the settings you select in the task UI, it will create the application and deployment manifests each deployment. Files are specified using globbing patterns in the UI, rather than reading from the project file.

For signing, you can either specify a certificate by thumbprint (if it's installed on the build server), or add it as a secure file to Azure DevOps (you can secure the password by using a secure pipeline variable). You can also specify a timestamp server.

Given that you'd be migrating an existing package, I recommend you diff the old and new manifests to confirm they are correct before uploading to your deployment location.

EDIT: This add-in doesn't use Mage, it uses the MSBuild API to directly create ClickOnce manifests. I suspect this is the same mechanism used by MSBuild and (therefore) Visual Studio.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM