Codesign Electron App - How to gracefully switch certificates? - code-signing

I have an electron app that originally was distributed with a certificate for an individual developer.
I'd like to now sign the next update to that app with a certificate from my organization, but when I do so, existing installations (upon auto update) throw an error that the code requirements aren't met.
Is there a way to properly sign an electron app with both the old and new certificate? I'd like to prevent my existing users from being interrupted.
Any help appreciated!
Thanks

We had a similar situation, with an Electron application for MacOS using auto-update, and we needed to switch to a new certificate without making everyone download and re-install the application manually. The auto-update process needs to recognize the new certificate. Rightfully so, the old version will refuse to update if the new certificate is not recognized.
Our strategy was:
look at the designated requirement (or DR) of the application, when signed with the old certificate, using codesign -d -v -r - <path-to-app>
look at the designated requirement of the application when signed with the new certificate
place the combined designated requirement, that includes both certificates, into an electron-builder-requirements.txt file
make sure that you do not include the identifier in the combined designated requirement string
make a reference to the electron-builder-requirements.txt in the electron-builder.yaml file (add a line under mac: like this requirements: electron-builder-requirements.txt)
publish a new version of the app, signed with the old certificate, but with the DR that contains information about both certificates
wait until nearly everyone has the version running on their desktop that includes mention of both certificates in the DR
update the build so that it uses the new certificate instead, and remove the electron-builder-requirements.txt file
release a new version of the app signed with the new certificate (no requirements file is needed, and it will list only its own cert in the DR)
An older version of the application that has a DR that includes information about both certificates will allow an auto-update to a new version that uses either certificate.
I found this document about signing code manually helpful in understanding the "designated requirement".
Update: here's an example of the electron-builder-requirements.txt file (I've modified some of the letters/numbers for privacy purposes):
designated => certificate leaf = H"2323ce6b0XXXXXXXX39f2064be999999997272b1" or anchor apple generic and certificate 1[field.1.2.840.199995.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.199995.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "6ZXXXXXXUY"

Related

Visual Studio certificate error "the manifest designer could not import the certificate": What is the reason?

I am currently developing a WinUI 3 application, but I believe the details of the application type are not that important for the question I have.
The application comes with a "Package project" for publishing the application using MSIX:
In the editor for the "Package.appxmanifest" file in the package project there is a "Packaging" tab that has a "Choose certificate" button for selecting a ".pfx" certificate file.
How I obtained the ".pfx" file:
My IT department logged onto my machine while the application for the windows certificate store was open. There we added a new "Code signing" certicate under "Own certicates", but which is not issued by me, but by the IT department. They told me that this certicate should also be trusted by client machines, when I publish applications signed with it, because it was issued by them and so it has a valid trust chain. Later I exported a pfx file based on that certicate which I am trying to use now.
Now, upon selecting this .pfx file in Visual Studio on the 'Packaging' tab, I get this error message:
Unfortunately the "The manifest designer could not import the certificate" error message does not come with the exact reason what the problem is.
I am quite sure that my certificate has a valid date and also is made for "Code signing".
I already found out that there are other users wondering about how to fix the certificate if this message appears. But nobody seems to know how to get told about the exact problem.
Is there some way I can use Visual Studio or Powershell or some other tool to tell me what the exact problem is for the certificate when I select it in Visual Studio and this error appears? I would like to have more detailed information than "there is something wrong with the exported .pfx certificate" that I can give to my IT department.
I am aware that I can specify this setting in the project file of the packing project in order to stop the error from appearing:
<EnableSigningChecks>false</EnableSigningChecks>
But I would also be very interested to know what the exact problem is. Thank you.
Additional information:
To check the pfx certicate file, I also executed the "certutil" command (with the -v option) as indicated here: https://superuser.com/a/580698/543294 In the large text dump file I find an issuer that I also find in the list of Trusted Root Certification Authorities of the certicate management application.
Did you edit the Publisher attribute of the element in your Package.appxmanifest to match the Subject property of the certificate?
This should not generate the error above. In the worst case, it could let you build the package and then fail to install it due to this mismatch, or it could fail to build the package.
What I suspect is that IT gave you a code signing certificate that they generated (instead of buying it from a certified vendor). This is perfectly fine if you plan to deploy your application only internally, inside your company, as they can deploy that certificate to all other machines from the company, so those machines trust it.
However, if the certificate was indeed generated by IT, and they didn't deployed yet to your machine, VS might see this is not a trusted certificate and could give this error.
You can check if the certificate is trusted by opening certmgr console and searching for the certificate in the Trusted Root Certification Authorities hive.
If it is not there, double click the PFX file and follow the wizard (from steps #4) to install it.

Xcode 9 - Embedded binary is not signed with the same certificate as the parent app

We have a project with an app main target and two extension targets: content extension and service extension. All of these have the exact same signing settings but I get this error when trying to create an archive in Xcode:
error: Embedded binary is not signed with the same certificate as the
parent app. Verify the embedded binary target's code sign settings
match the parent app's.
Embedded Binary Signing Certificate: - (Ad Hoc Code Signed) Parent
App Signing Certificate: iPhone Developer: XXXX XXXX (XXXXXXXX)
Obviously this is a keychain signing certificate issue. I had many older, expired certificates installed before and it compiled. Then I deleted all expired ones and now the builds fail. But the required certificates are installed and set properly in the project settings.
Time wasted on the issue: 2 days. Thanks Apple!
Can anyone point in the right direction here?
Found the solution here: Embedded binary is not signed with the same certificate as the parent app:
...
Make sure that your certificate is never ever set as Always Trust.
Access must be kept as Use System Default

signtool selects wrong (old) certificate for code-signing

I have a problem which I absolutely do not understand. A few days ago I issued a new codesigning certificate from our vendor (GlobalSign).
After logging in to the build server with the user that does the build / codesigning, I started certmgr, navigated to the Personal certificate storage and deleted the old certificate. Then I used the Import dialog to import the new certificate including it's private key.
A test build showed that signtool still uses the old certificate to sign the application. However, I'm unable to locate this certificate anywhere in the certmgr, not even by searching for that certificates SHA1 checksum.
After some googling I found this blogpost: http://qualapps.blogspot.de/2008/07/installing-code-signing-certificate.html
It stated the following:
Remove your old certificate. If you are renewing an existing certificate, then keeping the old certificates installed isn't usually useful, and having multiple certificates will break SIGNTOOL if signtool is searching the certificate store. Go to Control Panel / Internet Options / Content, click Certificates, select your old certificate, and click Remove. The old certificate will probably be on the Personal page if you allowed PVKIMPRT to decide where to put it.
I followed those instructions, but the only thing I can find is the new certificate.
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\signtool" sign /v /sm /n "my company name" /tr http://tsa.starfieldtech.com "the-setup.exe"
"my company name" is the name that is contained in both the old and the new certificate.
a. How can I find out where the old certificate is still stored and delete it?
b. How can I force signtool to use the new certificate, or at least fail?!
The workaround with using the PFX file and referencing to it is a good solution.
However, you may try the following:
add the parameter /s MY to the signtool parameters chain. "MY" links to the Personal store.
in certmgr.msc, look in other stores, if they do not contain a copy of the old certificate
add /a to the parameters chain. This will cause to "automatically select the best signing certificate" (whatever this means :))
you may wait until the old certificate expires. After that, it should automatically use only the new certificate
My situation seems similar, though in my case, putting the password for the certificate file in my build script wasn't an option. I was having trouble using any MMC snap-in to view (such as certmgr.msc) to view the certificate stores because Windows Server 2012 R2 wasn't allowing my non-admin build user to use the snap-ins. I resorted to trying a variation of a PowerShell script that I found here (https://social.technet.microsoft.com/Forums/windowsserver/en-US/7ed48943-22e2-4afd-aa77-2424d2a9eee1/how-to-delete-archived-certificates-using-the-certutil-command?forum=winserversecurity):
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "My","CurrentUser"
$MaxAllowedIncludeArchive = ([System.Security.Cryptography.X509Certificates.openflags]::MaxAllowed –bor [System.Security.Cryptography.X509Certificates.openflags]::IncludeArchived)
$store.Open($MaxAllowedIncludeArchive)
[System.Security.Cryptography.X509Certificates.X509Certificate2Collection] $certificates = $store.certificates
foreach ($cert in $certificates)
{
Write-Host $cert
}
$store.Close()
It showed me the certificate that was creating the conflict for me. (Strangely, trying to use certutil -viewstore My yielded a different set of certificates. (The placement of certificate stores is still unfortunately confusing to me.)
In my case, the problem was that I wanted a newer SHA256 certificate instead of my older SHA1 certificate so adding an appropriate /i argument to my signtool command (with the SHA256 issuer name) fixed my problem.

Code signing issue with Sparkle auto-update

I am using Sparkle for the first time, and having troubles getting things off the ground. When I check for updates, it correctly detects a newer version, downloads it, unarchives it, and then gives the following error:
Update Error!
An error occurred while extracting the archive. Please try again later.
The output log shows the following detail:
Sparkle: The appcast item for the update has no DSA signature.
The update will be rejected, because both DSA and Apple Code
Signing verification failed.
My archive is named "MyApp.pkg.zip", and contains only "MyApp.pkg". It has an apple ID digital signature. I verified this by downloading the zip manually, extracting it, running the PKG, and clicking the lock icon on the first install page.
The PKG has been created using Packages.
My appcast has the following:
<enclosure url="http://thedomain/MyApp.pkg.zip" sparkle:version="1.0.0.990" length="5752133" type="application/octet-stream" />
My .app also has the same Apple ID signature as the .pkg, though I don't think it matters at this point of the auto-update process.
So my question is: What am I doing wrong? How is Sparkle concluding that the digital signature is not sufficient, when the PKG is clearly digitally signed?
Do you have different certificates for signing the .app and the .pkg? When you go to create the certificate on Apple's Certificates site, you have to choose one or the other type.
You need to have two certificates, one for signing the .app and one for signing the .pkg.

Create iOS build with client's distribution profile

I have just finished an iOS app for a client, and have received a copy of their distribution profile (.cer format). I have dragged it into XCode as described in the docs from Apple. Now, I can select that profile for a distribution build, in the build settings for the project, but when I go to the target, I cannot select that profile? Any ideas on how to resolve that?
Also, is this the right way to go to create a distribution build, that the client can submit for approval?
Thanks!
- Lasse
You not only need their iOS Distribution Certificate, but the private key for that certificate as well (a password protected .p12 export from their Keychain will work).
You might want to install the client's certificates in a separate Mac User account as well (which will have its own Keychain), so as not to confuse your Keychain, since yours may already have your own certificates.
You need a copy of your client's signing identity. They can export it as a .p12 file from the keychain manager.

Resources