msix-packaging: [BUG] Package cannot automatically update when the signing certificate has changed
Project MSIX SDK (Package created using VS Community 2019 16.6.4)
Describe the bug Package cannot automatically update when the signing certificate has changed.
To Reproduce
- Sign and deploy your application using a certificate. You keep on using it and updating your app, and your user base grows.
- Later on (two years in our case) the certificate is near expiration and we ask for another one. Due to changes in the Certificate Authority, or even ourselves if we move from one location to another, or whatever the reason, the new certificate is slightly different (maybe now it is all uppercase letters in the CN field).
- Sign (with the new certificate) and deploy again your application, but in this case none of your users can update because of the following EventLog error (channel: Microsoft-Windows-AppXDeploymentServer/Operational):
Error 04/08/2020 12:44:09 AppXDeployment-Server 651 (3)
Error en la operación AppInstaller con el código de error 0x80070490. Detalle: No se ha encontrado el elemento.
If users manually force the installation of the package browsing to the webpage where it is published (by clicking in the “ms-appinstaller:?source=https://the.web.site.com/AppPackages/PackageProject.appinstaller” hyperlink) they receive the following error message:
The translation goes like:
Ask the developer for a new app package. This package may conflict with a package already installed, or it depends on things not installed here (package dependencies), or is made for a different architecture (0x80073CF3)
And in the EventLog (same channel as before):
Error 04/08/2020 12:58:35 AppXDeployment-Server 429 (4)
Windows cannot install package 967439b3-5b2b-4167-839c-0ba174a6c946_3.2.17.0_neutral_~_cb1zszxp1a70a because a different package 967439b3-5b2b-4167-839c-0ba174a6c946_3.2.16.0_neutral_~_wytc7bwvwy2aa with the same name is already installed. Remove package 967439b3-5b2b-4167-839c-0ba174a6c946_3.2.16.0_neutral_~_wytc7bwvwy2aa before installing.
Summing up, a conflict with a package with the same name that already exists, because the update is detected as a different package.
Expected behavior There should be a way to keep on updating our applications despite changes in the signing certificate. Because of a company moving from one city to another, or a Certifcate Autority changing its policies (now enforces everything in upper cases). That shoudn’t mean that our whole user base must do a manual uninstall and reinstallation of the application.
Screenshots If applicable, add screenshots to help explain your problem.
Platform x64 and x86 at least. Not tested in any other.
Additional context This thread Updating existing app with new certificate UWP deals with the same problem. I suppose it does not matter what kind of target application you are making since the issue comes at the core of the distribution process. It is not so much what you are publishing but more the way to do it.
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 7
- Comments: 36 (7 by maintainers)
Here is a summary of my thoughts on this.
• Last year, the algorithm had changed to remove the “POSTAL=” field. I was told that this was for my security, but since the rest of the address can be gleamed from the certificate I didn’t feel any more secure. • This year, the algorithm has changed to always include an “OU=”, and even if one is not provided in the CSR they just duplicate the “O=” field using it.
I don’t know how you can fix this without breaking everything first, but something needs to be done or you will see many vendors staying with/returning to MSI deployments.
This is not an acceptable process.
CAs require certificate renewal every year so this process says I’d have to start building chains of expired certificates for the catalog. In four years I’ll be telling them, yeah just install these 4 expired certificates on all of your systems and then you can install this product. And not only for the upgrade, but also a net-new company getting this software for the first time.
Unacceptable for the software vendor, and certainly not acceptable for the customer. There is no world in which I would advise the customer that they should install and rely upon an expired certificate. So, I guess I’ll be telling customers to uninstall and reinstall again this year.
I guess that being its own CA, Microsoft never has to deal with these issues. But how are you going to move your partners to want to release as MSIX like this?
@florelis We’ve been looking into this feature a bit more now, but it appears to be hard to use for a few interacting reasons (beyond the VS Studio issues which don’t affect us because we don’t use the native toolchain at all).
The problem is the decision to stop maintaining Windows 10. That’s still most of the market share and given current trends, it will be many years until Windows 11 is the main version in use let alone having replaced 10. That means that using the publisher bridge effectively forks the packaging. From that moment on you need a separate MSIX+appinstaller update stream for Win10 vs Win11. The Win11 one must continue to express the old app identity and be signed with the new cert, but therefore can’t be installed on Win10. The Win10 MSIX must be signed under the new non-expired identity, therefore it can’t be used to upgrade anything. Users must uninstall and reinstall. Also users must be given the right package at install time depending on their OS version, and any code that relies on or uses the package identity needs to handle the fact that there may be >1 identity in use for the same app.
This generates enormous logistical complexity. Multiple sets of “independent” MSIX packages with their own update streams, needing to keep them separated, etc.
Now, if Win10 got backports of this feature the problems mostly go away. We could potentially detect users are not fully updated and tell them to apply OS updates in order to re-enable app updates. That’s harder when the upgrade we’re asking the user to apply is Win11, which isn’t even available to all users. But we know from bitter experience that the MSIX team seem either to be prevented by internal rules or uninterested in maintaining the technology for Win10. Whatever the reason, Win10 has to be taken as fixed just as if it were shipped on a CD.
That constraint means we’ll probably need to look at alternatives to the publisher bridge, like just forcing an uninstall+reinstall cycle any time the CN has changed. And longer term, look into moving away from MSIX (somehow - it’s not like there are great alternatives). It has some wonderful features but the state of the tech in Win10 just isn’t good enough, yet Win10 is the OS that matters most.
I realize you’re a dev and don’t directly influence these decisions but please do send this feedback up the chain. Package identity is a key part of the Windows platform strategy but devs can’t adopt it when a basic part of the story doesn’t work on Win10.
I understand that this process is awkward at best, so I want to offer some insight to at least explain some of it.
Ensuring that an update to an app comes from the same publisher is very important. If someone manages to take over the identity of an app in an update, they would have access to the app’s data (like credentials stored in a Credential Locker) which isn’t good. The way this is prevented is by ensuring that the app is signed by the same entity. The issue is that if the cert subject changes there is no easy way to be sure that the new and old certificates belong to the same entity. I know it is problematic for you to not be able to update your app in that case, but that same mechanism is what prevents an attacker from hijacking it.
What the Persistent Identity feature provides is a way for you to let the OS know that two different subjects refer to the same entity. If the cert subject changes from A to B, this is done by having an artifact stating “A is also called B” that is signed by A. Now, to be sure that the artifact is legit (and not faked by an attacker), the signature needs to be valid. That means that it was created before cert A expired, that the system trusts on cert A, and that the artifact is timestamped (if past the expiration).
If you have any suggestion of how to make it easier while still being secure, I can bring it to the team for consideration.
Is this ever going to be resolved?
Oh, I left off one more thing. Any persistent identity solution for the software publisher should also cover the scenario where the name of the publisher changes due to merger/acquisition.
Two years later and this issue is still making our lives miserable. Our certificate is near expiration again and we’ve just asked for a new one. This time (again) the CA has changed some fields and our new certificate (again) does not have the exact Subject information in it.
According to Persistent Identity documents seem incomplete (or feature is broken), and makeappx gives uninformative error message, “the device will need to have the old certificate in order to install the package and use this feature”, meaning that we need a way to install the old (expiring) certificate in our users machines, in order for the “MSIX persistent identity” to work at all. This means not only for existing customers (for upgrading) but also for new installations (really???). At least that’s what is implied after reading the 2nd consideration and the comment posted by @dianmsft in https://github.com/MicrosoftDocs/msix-docs/issues/304#issuecomment-1159260121 in the former issue.
Again, we are forced to follow the least friction path and ask our user’s to manually uninstall the program, reboot and reinstall it again in order to keep on receiving updates. The workaround described in https://docs.microsoft.com/en-us/windows/msix/package/persistent-identity is completely useless as it is now (besides not being described in enough detail).
Thanks jagbarcelo for figuring this one out. I can confirm this.
We have the exact same issue. Our certificate ran out in May 2019, we updated to a new one (until 2021).
Result: All users who have the app with the old certificate installed, can’t update to any new version with the new certificate since May 2019, without seeing the error message “this package may conflict with a package already installed”.
Installation in our case: Also via an update url with appinstaller file.
MS, this is still relevant and creates a lot of unnecessary frustration.
Wow, this is discouraging. But I followed the steps at MSIX persistent identity and created the files, added the certificate etc. I am using VS2022 17.5.1 but get an error
0x80080218 - The published bridging artifact is invalidI found this link that explained you should keep using the original CN in the appmanifest, which I had changed to the new one. After changing that it build. After fixing my update site SUCCESS it worked, updates happen automatically.
Wow, this is a very complex procedure to go through but at least it works, thank you for sorting this out. My new cert is good for 3 years so hopefully nothing else happens in the mean time 😃
@dianmsft, @TimMangan I also tried the process described in https://docs.microsoft.com/en-us/windows/msix/package/persistent-identity but got stuck in the Create the package section. We are using Visual Studio too but the documentation was so lean and short that we couldn’t find a way to pass that stage.
Then I ask for more information about it to the guys who made that documentation (see https://github.com/MicrosoftDocs/msix-docs/issues/333) and they replied:
… and back to square one… (sigh)
@lechacon
Let’s try and made up an scenario where we have a near-expiry certificate, let’s call it Old-Cert, and another certificate New-Cert. Both certificates have an overlapping window where both are valid (the old one is not yet expired and the new one is already issued and valid). This is the only prerequisite for the procedure that is described below (an overlapping window).
Let’s suppose we have a MSIX application that has been released for quite some time, always signed with the Old-Cert. In the next image these releases are Release A and any other release before that one, in red.
Now, we reach the point where a new version is required to be launched into market (Release B). This time we have both certificates available but the developer will still sign that release with the Old-Cert. Besides that, and here comes the interesting step, the public key of the New-Cert will also be signed (using private key of Old-Cert) timestamped, and included in Release B.
That public-key of New-Cert, being signed with the private-key of the Old-Cert is the only key-chain that the MSIX upgrade subsystem will need to ensure that, whenever a new release comes into play (Release C in the image) it will be a valid one: the new release will be valid if it still comes signed with the Old-Cert or by the New-Cert that was preapproved in an earlier release (Release B).
Finally, the time comes to launch Release C, that will be signed only with New-Cert. When the MSIX upgrade is launched, it will see that it is not signed with Old-Cert, but it is signed with the New-Cert which was preapproved in an earlier release, and will proceed and install the upgrade as normal (maybe it needs to change the target directory of the application, since the Family Name might probably change).
There is no need for a Persistent Identity as it was defined in https://docs.microsoft.com/en-us/windows/msix/package/persistent-identity. We only need a way to create a single-point-in-time continuity between two different certificates, and that can be ensured by simply signing the public-key of the new one with the private-key of the old one.
@TimMangan
I think this solution would work in your scenario too. It would not matter if any field in the New-Cert matches or not any in the Old-Cert, since the approval derives from the fact that the New-Cert was signed by the Old-Cert as a legit succesor of it.
The only drawback that I can think of this procedure is the case where some users seldomly used the application, they skipped Release B, and tried to update from Release A to Release C (without knowing of Release B because they didn’t open the application during the time it was published). In that case the upgrade will fail, since they didn’t go through Release B which set the foundations for the certificate upgrade. However, in order to minimise the chances of that scenario to happen, the developer could release several versions of the application (Release B1, Release B2, Release B3… during an extended overlapped window), all of them including the signed New-Cert, and approving it as a legit new certificate for any later release.
Any one sees any flaws in this procedure? Could it be implemented something like this in the MSIX upgrade subsystem?
Just my two cents (I hope they’re worth more than that). Regards.
You can find at the end of the article:
It seems not
Ours machines or customers?
It’s currently in the Insider Build, but will it be available for currents versions of Windows (1909, 2004, 20H2, 21H1)?
We introduced a new feature that is currently in an Insider Build that tackles the issue of packages unable to update due to signing certificate changes. Here is the link to the documentation: https://docs.microsoft.com/en-us/windows/msix/package/persistent-identity
I now have the issue in a way more common with all of you. I have been through two different CAs (Sectigo and Digicert) and they both refuse to include the additional fields that were in my previous certificate. Thus my customers cannot upgrade. and must manually uninstall / install. The certificate should not cause package lineage to fail. Either fix that or give us an additional field in the AppXManifest used to generate the PublisherId hash used in Package Family Name.
This issue is also mentioned in the Tech community galley here: https://techcommunity.microsoft.com/t5/msix-deployment/how-and-why-publisherid-packagefullname-and-ca-s-break-the/m-p/2494204
We have had this issue the last week or so. Our problem was caused by the subject name having been changed on the re-issue of the certificate. Once we corrected this our issue was resolved.
We are deploying via a URL and appinstaller.