How to share a self-signed clickonce certificate with different clients for development - certificate

I am developing a clickonce C sharp project in Visual Studio.
On my main computer, I have generated a self-signed certificate for the clickonce manifest.
This works fine, I can compile, deploy and run.
I also sync this solution to my github account, and regularly pull updates down to a backup computer.
The backup computer is not able to simply compile this solution, as it gives errors in regards to self-signed keys.
I could generate a new one on the backup computer, but then when I deploy to same testbed, it causes issues because the certificate is from a different location.
I want to quickly be able to deploy from the backup computer in the event that there is an issue with the main.
How can I share the main computer's generated certificate with my backup environment without issue?
My apologies if this is straightforward or I am missing something obvious.

Run certmgr.msc (user) or certlm.msc (computer) and look in My Certificates for the certificate. Right click it an check if you can export it with the private key resulting in am PFX file (PKCS#12).
If this is not possible generate a new one with the -ExportPolicy Exportable option.

Related

How to sign code built using Azure Pipelines using a certificate/key in Azure Key Vault?

We're in the process of moving from on-premise build servers to Azure Pipelines. We produce "shrink-wrap" desktop software so clearly we need to sign all our binaries before releasing. Our current build infrastructure does this using a USB hardware token from GlobalSign, but clearly that isn't going to work when we're doing cloud builds - sadly, clouds are not equipped with USB ports :D
Now, GlobalSign has recently started advertising Azure Key Vault as a key storage option, and they're perfectly happy to sell this to us, but I'm not sure how we'd actually integrate that with our build pipelines (or indeed whether that's even possible).
Has anyone actually made this work?
Code Signing
I've been battling with Azure Key Vault and Azure Pipelines to get our code signed, and succeeded. So here's what I found out.
Critically, Extended Validation (EV) certificates used for code signing are very different animals to 'normal' SSL certificates. The standard ones can be exported as much as you like, which means you can upload it to Azure Pipelines and use it with the standard Microsoft Sign Tool.
However, once an EV certificate is in Azure Key Vault, it isn't coming out in any usual fashion. You must call it from Pipelines using the excellent Azure Sign Tool as discovered by Anodyne above
Get your certificate into Key Vault. You can use any certificate authority you like to generate the certificate, as long as they understand that you'll need an EV certificate, and critically one that has a hardware security module (HSM), and not one with a physical USB key. Any cloud based system like Key Vault will need an HSM version.
To get the permissions to access this certificate externally you can follow this page but beware it misses a step. So read that document first, then these summarised steps, to get the Key Vault set up:
Open the Azure portal, go to the Azure Active Directory area, and create an App registration: put in a memorable name, ignore the Redirect URI, and save it.
Go to your specific Key Vault, then Access control (IAM), then Add role assignment. Type the name of the app you just created into the select input box. Also choose a Role, I suggest Reader and then save.
The Missing Part: Still in the Key Vault, click the Access policies menu item. Click Add Access Policy and add your application. The Certificate Permissions need to have the Get ticked. And the Key Permissions, despite the fact that you may not have any keys at all in this vault, need to have Get and Sign. You would have thought these two would be in the certificate perms...
Go back to the application you just created. Select the Certificates & secrets, and either choose to upload a certificate (a new one purely for accessing the Key Vault remotely) or create a client secret. If the latter, keep a copy of the password, you won't see it again!
In the Overview section of the app will be the Application (client) ID. This, and the password or certificate, is what will be fed to the Azure Sign Tool later on in a Pipelines task.
Handling the actual code signing from Azure requires a number of steps. The following applies to Microsoft hosted agents, although similar issues will affect any private agents that you have.
The Azure Sign Tool needs the .NET Core SDK to be installed, but a version that's at least version 2.x, and since the latest .NET Core SDK is always used, this means as long as the version of Windows is current enough, you don't need to install it yourself. And you can see which version of the SDK is shipped with which Windows agent.
The current Hosted OS version in Azure Pipelines, also called Default Hosted, is, at the time of writing, Windows Server 2012 R2. Which isn't up to date enough. Installing a newer .NET Core SDK to overcome this is a time drag on every build, and although the installation works, calling the Azure Sign Tool may not work. It seems to be finding only older versions of the SDK, and throws this error: Unable to find an entry point named 'SignerSignEx3' in DLL 'mssign32'.
So the easiest thing to do is change your build to use a later OS image. Windows 2019 works like a charm. And there is no need to install any version of .NET Core.
Then create a command line task to install the Azure Sign Tool. You can use a .NET Core CLI task as well, but there is no need. In the task, type this:
set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
dotnet tool install --global AzureSignTool --version 2.0.17
Naturally using whichever version that you want.
The DOTNET_SKIP_FIRST_TIME_EXPERIENCE environment variable isn't strictly necessary, but setting it speeds things up quite a bit (see here for an explanation).
Finally, create another command line task and type in the Azure Sign Tool command that you wish to run with. On Windows this would be something like below, note with ^ not / as a line continuation marker. Naturally, see here for more parameter information:
AzureSignTool.exe sign -du "MY-URL" ^
-kvu https://MY-VAULT-NAME.vault.azure.net ^
-kvi CLIENT-ID-BIG-GUID ^
-kvs CLIENT-PASSWORD ^
-kvc MY-CERTIFICATE-NAME ^
-tr http://timestamp.digicert.com ^
-v ^
$(System.DefaultWorkingDirectory)/Path/To/My/Setup/Exe
And in theory, you should have success! The output of the sign tool is rather good, and usually nails where the problem is.
Re-issuing Certificates
If you need to re-issue a certificate, the situation is quite different.
In Azure, go to the certificate and click on it, opening a page showing the versions of that certificate, both current and older versions.
Click the 'New Version' button, probably accepting the defaults (depending on the choices you wish to make) and click 'Create'.
This takes you back to the Versions page, and there will be a message box stating 'The creation of certificate XXXX is currently pending'. Click there (or on the 'Certificate Operation' button) to open the 'Certificate Operation' side page. Once there, download the CSR (certificate signing request).
In GlobalSign, follow their instructions to re-issue the existing certificate. Once it has been re-issued, they will send an email describing how to download it.
Log into GlobalSign again, and after entering the temporary password, open the CSR and copy the whole text (which starts with -----BEGIN CERTIFICATE REQUEST-----) into GlobalSign. Submit it.
Download using the 'Install My Certificate' button. Then in the Azure 'Certificate Operation' side page - use the 'Merge Signed Request' button that to upload the .CER file to Azure. This creates the new version of the certificate.
Disable the old version of the certificate.
Yes, it's able to do this in Azure DevOps Service Build pipeline.
For normal situation, we usually use SignTool.exe commands to sign files. There is also an extension Code Signing in marketplace, which could sign a single file, you could use script to run SignTool.exe commands for multiple files.
So you can export your codesigning certificate to a pfx file, which you then upload as a secure file to Azure Devops secure file storage which makes it available to your builds.
Azure DevOps could store secure files. Check this link for details: Secure files
Azure Key Vault instance is kind of more complicated. We also have an Azure Key Vault task.
Use this task in a build or release pipeline to download secrets such
as authentication keys, storage account keys, data encryption keys,
.PFX files, and passwords from an Azure Key Vault instance.
The task can be used to fetch the latest values of all or a subset of
secrets from the vault, and set them as variables that can be used in
subsequent tasks of a pipeline.
Not sure how GlobalSign will integrate code sign with your environment. Theoretically, it's able to do this. For the detail parts and implementation, you may need to discuss with their pre-sales. Hope this helps.
If anyone else is looking for this and using RBAC, I found these steps essential:
Key Vault Reader on the RESOURCE GROUP
Key Vault Certificates Officer on the KEY VAULT and on the CERTIFICATE
Key Vault Crypto Office on the CERTIFICATE (to use the key for signing!)

Can you install an SSL certificate on a server other than where the CSR was generated?

I have recently been tasked with automating our certificate issuance/renewal process via PowerShell. Having never worked in this space prior, I'm doing a lot of on the fly learning.
The idea is to make the execution stateless, meaning we can have one server running a script that requests certificates and simply store them to be installed on the appropriate machines later. That will likely be automated as well. My question is this: when I generate a CSR on the server, and the certificate is ultimately issued by DigiCert, can that certificate only be installed on that server? My research says yes, and yet I tested this by installing an already issued certificate on my local machine and it worked. I had not generated the CSR for that certificate on my machine, yet I was able to install it without error. Would the problems only come in when binding the certificate to a site?
Any insight would be greatly appreciated.

Best deploy method for registry and certificates

I need to deploy some registry keys and install certificates in some stores on each of my clients computer.
To avoid errors and make it easy to use, I want to create an automated process to do so, but I don't what are the options.
What are the possibilities to upgrade the windows registry and install a few certificates?
Batch files?
Installer?
Deployment package?
The sweetest thing would allow my clients to configure their computer by clicking a button right into one of my ASP.net page, is it possible?
I'm facing the following problem :
On windows XP, the utility called "certutil", that is used to deploy certificates is unavailable.
To install it, I must install on each client the Windows server 2003 Administration tools and it's cumbersome.
The best solution I've found so far is to export my certificates from the registry, and install them through my clients' registry ! I can only share a big .REG file that will do all the installation work.
Each one of my certificates must go into the following registry key :
[HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates\Root\Certificates]
And by exporting my registry, I can therefore share the exported .REG file to allow other users to install them!
Can I have trouble with that solution ? Is there a better way ?
Thanks for your help!
I looked again at the group policy preference I was using. There is an option "Run in logged-on user's security context (user policy option)" that I enabled and now the registry entry is persisting

Command line installation of Code Signing certificates, .p12 files, and mobileprovisions

I work at a company who does 3rd party iOS development for various enterprises. I've been tasked with researching a better way to build and deploy code to these enterprises. Based on the Apple TOS, they cannot use an application signed with our Enterprise certificate (they're not "in house"). The code needs to be signed with their (our clients) Enterprise certificate. Here are a few possible solutions I've seen -
1) Send the code to the client, and have the client build it. This is a no-go.
2) Create a library with the application code and send the .so file, and the headers, to the client for building. We're currently doing it this way but are looking at making this easier on the client/us.
3) Have the client send us their certificate, mobileprovision, and .p12 file and then we build the application using their certificate. This could work but could become a management nightmare.
We've come up with an idea that is kind of a mix of these ideas. The idea involves building a customer portal where the client can upload their files (cert, p12, provision) to our Mac server and the Mac will automagically build their application, properly signed. The problem I'm having, however, is I can't seem to find out how to automate the installation of certificates and provisions.
So with that said, does anyone know of a way to install a CodeSign certificate (with a .p12 file) and a mobile provision file from the command line? Once installed is there also a way to remove the items from the command line?
Any help, ideas, and/or input would be greatly appreciated. Thanks!
You should be able to manage those resources in the keychain using the security (http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/security.1.html) command. The script I'm using to control command line builds might be a useful reference: https://gist.github.com/949831
Admittedly I've only ever had a maximum 2 external clients plus my own stuff at one time, so it was mostly only the same nightmare that it usually is by default, but how bad would it be if you had to manually do everything EXCEPT the provisioning profiles? In my experience once the client certs got added I never really messed with them again even with new projects (from the same clients.)
You could handle the provisioning profiles by simply copying the files into ~/Library/MobileDevice/Provisioning Profiles, and deleting them when no longer needed. It sounds like you are already set up to automate that process.
If you're currently installing the provisioning profiles by "dropping them onto xcode" I'd suggest you do it by copying into the folder anyway, because then the file names are preserved and so you actually can tell what you have installed by simply looking at the folder.

Move ClickOnce repository without reinstall in client machines. Is it possible?

I have a C# application (WinForms) (ClickOnce) whose repository is installed on a server that is about to crash, so my boss asked me to move the repository, but there are around 300 client machines which have the application installed.
The ClickOnce is signed with a Test Certificate.
Is it possible to move the repository without having to reinstall in the client machines?
Thanks in Advance
[EDIT]
I Have published the application to the new server, but the clients don't reach it, what else can I do? I think i should change something inside the manifest or something like that, but a actually don't know too much about ClickOnce... In any case, i would like to avoid the reinstallation on all the client machines, any ideas, suggestion? thanks in advance
The answer provided by Jhonny seemed promising to me, and I encountered an error when I tried it, which I had to solve. It had to do with certificates.
After following his setps, when I launch the ClickOnce app on the client machine, I get an error dialog: "Cannot Start Application".
When I click on the Details... button in the error dialog, the text file that opens shows that the app is trying to update from the Deployment Provider URL of the new server, but it gives this error:
"The deployment identity does not match the subscription."
The problem was the certificate used to publish the app on the old server was expired, and I had updated the certificate in the app published on the new server. The certificates didn't match.
The solution was to first publish the app to the old server with the new certificate, have the users open the app to get that update, then publish another new version with the Deployment URL of the new server, and copy the files to both servers. When the users updated the next time, they got the version of the app from the old server with the manifest pointing to the new server, and then, all subsequents updates were retrieved from the new server.
Here is what I have done, for people who may have the same issue.
Setup the new server on the publish package. (Project Properties, Publish Tab)
Publish to the new server
Copy the published files to the old server. (Include the .application file and the folder)
When the clients reach the old server, they will update, but the server location will be updated on the client to the new server name.
You could try to change the DNS alias so that it redirects to your new server.
The fact that the code signed using a certificate is not relevant, since code-signing certificates are not bound to a specific repository (as opposed to SSL certificates)
Btw, why don't you want to reinstall? The whole point of clickonce is to ease this kind of software update !!