Unable to code sign appx package in Visual Studio: A look at build process and certificate issues.
It all started with issues in code signing. My client was using Signtool to sign his package and they were getting bunch of errors. The below screen grab shows us the errors.
MakeAppx failed to extract Appx to App.Windows10_0.0.2.0_ARM
Ensure AppxManifest and signing cert Publishers name match..
Get-Content:Cannot find path 'C:\Temp\APPXOutput\App...\AppxManifest.xml' because it does not exist.
At C:\Program Files (x86)\Microsoft SDKs\WindowsPhoneApp\v8.1\...\BuildMDILAPPX.ps1:464 char:31
You cannot call a method on null valued expression
Well searching about such issues online you can see that there are lot of hits.
My hypothesis after reading this msdn link is “The issue they were facing was because the subject name of the certificate must match the Publisher attribute that is contained in the Identity element of the AppxManifest.xml file that is stored within the package. “ So in other words before we even sign the application we have to add the pfx file in Packaging Tab of Appxmanifest, is that happening correctly? So I set out to verify how is he getting his packages. Right when we had to add the pfx file into Visual Studio we were getting the error,
“The Manifest Designer cannot import the certificate”.
The certificate you have selected is not valid for signing because it is either expired or has other issues.
Clearly the certificate had not expired. I tried the same with a Test Cert I had created and it worked splendidly. I went to check out the certificate properties of our customer. I found out that Code Signing in Enhanced Key usage was not checked. From my experience in the past I know that the certificate needs to have Code Signing as an Enhanced Key Usage. This link enlists How Visual Studio validates certificates.
We went through lot of work arounds online . One of which is to go to Certificate Properties - Certificate Purposes - Enable only the following properties and unchecking properties that were invalid for this purpose (everything but Code Signing). That doesn't work.
During packaging, Visual Studio validates the specified certificate in the following ways:
- Verifies the presence of the Basic Constraints extension and its value, which must be either Subject Type=End Entity or unspecified.
- Verifies the value of the Enhanced Key Usage property, which must contain Code Signing and may also contain Lifetime Signing. Any other EKUs are prohibited.
- Verifies the value of the KeyUsage (KU) property, which must be either Unset or DigitalSignature.
- Verifies the existence of a private key exists.
- Verifies whether the certificate is active, hasn’t expired, and hasn't been revoked
Now that we have verified that customer’s certificate is not valid for code signing. So the obvious next step is to acquire a certificate which meets the above conditions. What I am proposing below is not a solution for the issue. Solution is to acquire certificate matching the requirements. This is to provide some insight into the files used while building.
This customer wanted to get the product out in their test hardware for now and then eventually buy a cert which would meet the requirements and asked us if we can do something that could allow them to continue with their plans. Please note that the below is not recommended. Microsoft requires you to use proper code signing certificates. I would not call this a work around. But it gives you a good idea of how the build happens. Msbuild is the build engine that builds all types of applications in Visual Studio. What msbuild does is it uses targets which contain tasks to divide the work, kick in different tools and build the components. We went to on of such target files which conatins flags for certain validation checks C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\AppxPackage. In there we got hold of Microsoft.AppxPackage.Targets. This target file contains flags, one of which is EnableSigningChecks
<!-- Flags controlling certain features -->
<AppxPrependPriInitialPath Condition="'$(AppxPrependPriInitialPath)' == ''">true</AppxPrependPriInitialPath>
<EnableSigningChecks Condition=" '$(EnableSigningChecks)' == '' ">true</EnableSigningChecks>
<AppxStrictManifestValidationEnabled Condition="'$(AppxStrictManifestValidationEnabled)' == ''">true</AppxStrictManifestValidationEnabled>
We changed this flag to false . After this we restarted Visual Studio and we were able to add the certificate which is obvious provided the falg turned off. This just disables the signing checks and you will be able to add the cert. This is clearly not some thing we recommend, certificate with valid conditions has to be used for your appx files. I hope this gives some insight into these target files. Previously I had written a blog giving you similar insights. I hope the information is useful. Feel free to put your questions in comment section.