If you’re like me—writing internal apps for a small company—you create your own self-signed certificates when publishing a ClickOnce application. Visual Studio will create these certificates for you automatically on the first publish, but they’ll only be good for a couple of years. That’s when you find yourself under pressure, updating a malfunctioning application, and suddenly you’re getting an error when trying to push out your fixes.
A great tool to renew your certificates is RenewCert, written by Cliff Stanford. Using this tool, you can quickly extend the expiration date of your signing certificate to 5 years from the current date. Much thanks are due to Cliff for figuring this all out! This stuff isn’t really documented anywhere.
But I found a few limitations:
- I couldn’t run it in a setting without VC++ installed. The author acknowledges this issue, but with walking the dependencies I couldn’t manage to find them all. I had to run this on a remote computer so it was a deal-breaker.
- I couldn’t get the thing to compile on my system. I’ve rooted around C++ apps before and I could probably figure it out, but I just didn’t want to.
- Because I couldn’t compile I couldn’t extend the expiration date beyond 5 years, like 25 years for example.
- I wanted to use it as part of a tool to move a ClickOnce app from one location to another. I needed a way to determine if a certificate was out of date by running a command line tool and checking the [generic]errorlevel[/generic] output.
So I set about rewriting the app in C#. The hardest part was tracking down all the P/Invoke declarations. The [generic]CertCreateSelfSignCertificate[/generic] API was particularly finicky. The rewrite works the same way as the original with a hard-coded year, but you can always hard-code your own or add support for an additional argument.
New features include:
- If you don’t supply a CN, it will look up the original and use it rather than a placeholder.
- You can use a “/e” argument to see if the given certificate has expired.
- All cleanups are wrapped in a [csharp]try..finally[/csharp] so you’re less likely to destabilize the system (which I did a couple of times and had to restart).
Here’s a complete example:
set certFile=C:\My Project\MyCert.pfx
renewcert “%certFile%” /e
if %errorlevel% equ 0 echo Certificate is not expired. & goto SkipCertRenew
echo Certificate is out of date and must be renewed!
renewcert “%certFile%” “%certFile%”
if %errorlevel% neq 0 echo Error %errorlevel% renewing certificate.
Like the original author, I got it working and stopped, so it’s not the prettiest thing in the world—mea culpa. But this should be easier to extend to suit your needs.
Download: RenewCert.zip (for VS 2010)