-
Notifications
You must be signed in to change notification settings - Fork 166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] Package cannot automatically update when the signing certificate has changed #365
Comments
Thanks jagbarcelo for figuring this one out. We have the exact same issue. 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. |
We ran into this issue too, our Certificate Authority changed the "State" field (from shortname to fullname). The issue is the "Family name" (app manifest -> Packaging tab). This name is a Hash of all the characters in the signin certificate. We thought about leaving .appinstaller (and UWP) because of that (it will be extremely painfull to do it again at every changes of CA policies). It's pretty sad because the auto-update and remote installation functionalities are awesome! One fix is to use a self-signed certificate (you can copy/paste the fields of the old certificate) but it feels unprofessional. |
This problem could be solved if the "Family name" was editable or if, at least, there were an alternative "Family name", call it Custom, Legacy or Migration that could be used solely for application updates, from one old Family name (due to the expiring certificate) to a new Family name (generated with the new certificate). Right now renewing our signing-certificates is far from being painless for us, developers. |
I have a different scenario with the same cause. The package is made available via the Windows Store but also because of customers where store access is blocked also may obtain it directly from my website. Obviously I can't use the Microsoft Store cert when I distribute myself, so a customer that originally obtained the store version cannot upgrade. |
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. |
Any update on this? |
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 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 |
Step 4 : Sign the catalog with the old certificate. The old certificate has expired. Is this process going to work? |
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)? |
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 MicrosoftDocs/msix-docs#304 (comment) 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). |
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? |
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. |
Here is a summary of my thoughts on this.
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. |
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. |
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.
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. |
It is my understanding that a brand new customer receiving Release B or Release C will be required to install Old-Cert to be able to install the release. This is not reasonable. Nor is it reasonable to require me to release a "Release-B as upgrade" and separately "Release-B as new" in parallel. Maybe the doc confused me about that requirement, but that is how I read it. |
I don't think that any brand-new users installing Release B would require anything particular to be installed. Release B would be signed with the still-valid Old-Cert, just as any other any earlier releases (Release A and previous ones). On the other hand, brand-new users installing Release C directly, would never know there was a previous Old-Cert at all. In no case, final users would need to install any certificates (expired or not) in their local machines. My request is that the MSIX upgrade subsystem should be modified to allow upgrades in the app whenever any of these two things happens:
|
I'm no expert in PKI, but I think that's what revocation is for.
Yes, something being signed is no proof that it is safe. But if an app is signed by anybody but the publisher, that's a pretty good sign that somebody may be trying to impersonate the publisher and the app is not safe.
I don't think that is true. For example, the names "CN=Jane Doe, C=US" and "CN=Jane Doe, C=UK" probably refer to different people.
Could you expand on why you think that? |
That's more or less the same as for the existing feature :)
This part is basically what the Persistent Identity feature does. Only that instead of endorsing the key/cert, we endorse the cert subject; and the artifact goes in new version instead of the old one. That way, if you re-new your certificate again and are able to preserve the new subject name, the same artifact would still work.
This is only possible if the release schedule lines up with having both certs. With the current feature, you can generate the signed artifact during this time window, then sit on it until you are ready to publish a new release and include the artifact in it even if the overlapping window is now long gone.
I see that as a pretty big drawback. The feature as it is now was designed so that upgrading would work between any two versions, regardless of how many you skip.
I'd expect that to not be possible in most cases due to the overlapping window being too small to fit more than one release. For example, with an app released twice a year with a cert expiration of 1 year, you would only be able to use the same cert for two releases, and the overlapping window will be even less than that.
Yes, it would change as it is derived from the package name and the publisher name (which matches the cert subject). Which is a problem as it is supposed to identify a package across versions and it is used in different places. For example, the Shared Package definition uses it and Package Dependencies are defined in terms of Name + Publisher. |
@dianmsft I am going to try out the process of including the catalog, under the assumption that the line in the Persistant Identity doc that says "You will still need to install the old certificate (recommended with timestamp) on the machine for the platform to install the package that was signed by the new certificate" in the document is being mis-understood by us and that the expired certificate does not need to be installed on end user systems. If I can prove that this works we can simply request a rewording of that line. The question becomes how to trick WAP Publishing in Visual Studio to include the /pb option when makemsix is run? Is there an underdocumented element to include in the WAP project xml Property Group? |
@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 MicrosoftDocs/msix-docs#333) and they replied:
... and back to square one... (sigh) |
@TimMangan It should not work without the expired certificate(*); and if it does that's a bug. If the signature is not trusted, then there isn't much difference with it not being signed as anybody could create a fake certificate and use it to sign. (*) It can be any certificate in the certificate chain, it doesn't need to be yours specifically. For example, it can be the one from the CA root, which could still be valid.
@TimMangan @jagbarcelo I think a flow like this would work:
Or if you can get VS to pass the
Windows Application Packaging projects are not my area of expertise, so the following may actually be very a bad idea and not officially supported but.... |
No luck with that. When we included It seems Visual Studio 2022 (Community at least) does not support the /pb option, not even when passed manually inside the I'm starting to lose all hope that this issue would ever be solved for real-world usable scenarios in a simple way, instead of a twisted cumbersome tweak using commands that cannot be reproduced/scripted/integrated in Visual Studio which is what we use. We are forced to follow the least friction path and ask our users to uninstall, reboot and reinstall the app again. |
That probably means that the version of makeappx you are using does not support this feature. It is available starting on build 22000. I imagine that VS uses an SDK with version matching your project's target platform, so if you are targeting something older than build 22000, you won't be able to use it. |
From this document:
@dianmsft @lechacon Does that mean we have to use the Windows 11 SDK or does that mean this feature is only supported on Windows 11? (The requirements section specifies only the SDK, but it's not clear to us) Just to document our problems here too:
|
For anyone looking for the same (see the above question about requirements), I found an answer in the docs repo. Thanks @Marv51 for testing this! TL;DR
|
I'm just starting with code-signing and wondering if this is still an issue. |
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 I 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 :-) |
@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. 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. |
The Persistent Identity doc states that:
Does that mean that, as time passes and the publisher CN changes, newer versions of the package should include artifacts passing the buck to each subsequent change? That is, one artifact for Publisher1->Publisher2, another for Publisher2->Publisher3, etc. And after the package has accumulated 5 of those changes, it is no longer possible to maintain the chain for updates to keep working if there are further publisher changes? On the flip side, 5 publisher changes would likely take several years, by which time hopefully a more permanent solution is found. But unless the Persistent Identity feature gets backported to Win 10, it doesn't help us that much. |
@mikehearn
Yes, that is correct. |
Is this ever going to be resolved? |
We implemented an alternative approach in Hydraulic Conveyor, a packaging tool that can make MSIX files. It detects if the signing identity has changed and if so, forces an uninstall/reinstall cycle on app startup. https://conveyor.hydraulic.dev/11.0/configs/escape-hatch/ Although mostly targeted at cross-platform app developers, you can use Conveyor to make MSIX files and appinstaller update streams that are only for Windows as well. Conveyor works around bugs in MSIX and Windows 10 to provide more reliable installs and updates, and also supports forcing synchronous updates on app startup,. I hope we can help people who need a better MSIX experience here! |
MS, this is still relevant and creates a lot of unnecessary frustration. |
|
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
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:
And in the EventLog (same channel as before):
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.
The text was updated successfully, but these errors were encountered: