When .net says "certificate valid", what is it checking? - x509

I'm using the SignedXml.CheckSignature(X509Certificate2, boolean) method. I would like to know what checks are performed when deciding the validity of the certificate. I have verified that the Current User/Not Trusted list is checked. The documentation says it will use the "address book" store, searching by subject key identifier, to build the certificate chain. I imagine this means the Local Machine and Current User certificate stores?
Am I right to think that certificate revocation and signature timestamp are not checked? To do an OCSP check for certificate revocation, am I obliged to use Bouncy Castle?

In the remarks in the msdn article you link to one finds:
In version 1.1 of the .NET Framework, the X.509 certificate is not verified.
In version 2.0 and later, the X.509 certificate is verified.
In version 2.0 and later of the .NET Framework, the CheckSignature method will search the "AddressBook" store for certificates suitable for the verification. For example, if the certificate is referenced by a Subject Key Identifier (SKI), the CheckSignature method will select certificates with this SKI and try them one after another until it can verify the certificate.
Thus, first of all the behavior of that method has changed in different .NET framework versions. So for reproducible results, you had better not count on that method even check the certificate at all.
Furthermore, the formulation try them one after another until it can verify the certificate sounds like there just might be the mathematical test whether or not the certificate is signed by its alleged issuer.

https://referencesource.microsoft.com/#System.Security/system/security/cryptography/xml/signedxml.cs,b9518cc2212419a2
It checks
The certificate has no Key Usage extension, or the Key Usage extension has either Digital Signature or Non Repudiation usages enabled
The certificate chains up to a trusted root authority
The certificate has not been revoked
The certificate was not expired when you called this method
It doesn't know when the document was signed, so it doesn't answer that question.
That none of the certificates in the chain are explicitly prohibited by the user or system configuration.

Related

iOS Alamofire SSL Pinning with both certificate about to expire and a new certificate

My application implements SSLPining with leaf certificate. And it's about to expire.
I researched and got the answer:
Some time before the certificate expires, release a new version of your app with a replacement cert in the pin list, as well as the original cert
How can i add both replacement cert and original cert to my project?
I just need to add a new certificate with any name and Will Alamofire go through all the certificate files I declare and if any match will it allow the connection?
Thanks
Yes, that will work. Alamofire's PinnedCertificatesTrustEvaluator gathers all certificates from the main bundle by default and checks to see whether the certificate received is within that set. So as long as both certificates are within that set, either of them should work.

Is Self-Signed IdentityServer4 signing credential good enough in production?

We are using IdentityServer4 and our version loads the signing key from a PFX file in file system or from the windows certificate store. Using the certificate works. The question is - which certificate issuer should be used in production?
Is a certificate from a public CA recommended? Or is it enough to have a self-signed certificate (without a CA at all) such as it can be created with IIS Manager?
In our tests we have found that the client could still validate the signature in the access token, even if the signing certificate would not have a valid CA chain on the client.
In the docs, it says that you can also use raw key material instead of a certificate:
http://docs.identityserver.io/en/latest/topics/crypto.html#token-signing-and-validation
In this scenario there would be no CA chain whatsoever.
That leads me to the assumption, that when the client loads the public signing key (via the HTTP(s) endpoint), the CA chain information might not be passed anyways. Is that right? Through the loading mechanism via HTTPs you also have a combined security mechanism.
So my conclusion is that for the signing credential a self-signed cert is just as safe as one from VeriSign. Can this be confirmed?
There is no certificate involved in signing and verifying the tokens. Only a private and public key (RSA or ECDSA key).
However a certificate can be useful to "import/transport" the keys into .NET. So, because of that we don't care about who issued the certificate.
When importing the key, one approach is to bundle the certificate that holds the public key + the private key and store it in a PKCE#12 file (.pfx/.p12 extension). Then load that file into .NET. Before .NET 5 working with keys was a bit hard.
The more important thing is that you can manage and deploy the private key in a secure way and that it is persisted over time.
Optionally, you can add support for key-rotation.

How can I specify a SHA-256 algorithm for signing the certificate?

I built an Apereo CAS demo server with a WAR overlay (with which
different services should be authenticated).
I have set up delegated authentication with SAML2 (for integrating
with italian SPID system), following this guide
https://apereo.github.io/2019/02/25/cas61-delegate-authn-saml2-idp/
I copied the SP metadata to a IDP configuration.
This IDP is a test IDP instance, meant to check if SP metadata and the SAML request are ok.
When I run the server and I browse it,
I can see the second login form, but when I click it, the validation checks shows some errors.
Among them there is the following:
"The certificate must be signed with a valid algorithm."
"The certificate must not be signed using the SHA1 algorithm (deprecated)."
I am pretty sure that SHA-256 would be fine with the IDP validator.
In the documentation
https://apereo.github.io/cas/development/integration/Delegate-Authentication-SAML.html
I see that the following parameter should be in charge of specifying
the signing certificate algorithm:
cas.authn.pac4j.saml[].signature-algorithms:
Its description is
# Required: false
# Type: java.util.List<String>
# Owner: org.apereo.cas.configuration.model.support.pac4j.saml.Pac4jSamlClientProperties
# Module: cas-server-support-pac4j-webflow
# Collection of signing signature algorithms, if any, to override the global defaults.
# cas.authn.pac4j.saml[].signature-algorithms:
I don't know what values are allowed there. I googled a lot but with no luck.
I have tried to set that list like this
cas.authn.pac4j.saml[0].signature-algorithms=["sha256WithRSAEncryption"],
cas.authn.pac4j.saml[0].signature-algorithms=["SHA256withRSA"] but,
after clicking the SAML login button, I always get the following
error:
org.pac4j.saml.exceptions.SAMLException: org.pac4j.saml.exceptions.SAMLException: Could not determine the signature parameters
at org.pac4j.saml.crypto.DefaultSignatureSigningParametersProvider.build(DefaultSignatureSigningParametersProvider.java:60)
...
How can I specify a SHA-256 algorithm for signing the certificate?

Using self-signed certificate for code signing software

Currently our company uses a digital certificate from Versign/Symtanec for code signing our software.
We have someone in our company attempting to persuade us to use a self-signed certificate instead of one purchased from Verisign/Symantec. Partially as a "cost-down" procedure (even though they're pretty damn cheap for a 2-3 year renewal), and partially to make things easier in a patching sense, as the systems our software runs on (industrial machines) has installed software with a non-Windows certificate store in which our certificate also needs to be managed. Apparently they want use to use the Windows Root CA in order to generate our certificate so we don't have to keep patching new certificates on and our certificate will essentially last as long as the Windows Root CA is valid ...
Everywhere I've been looking, I've found that some people use self-signed certificates for things like website identity verification over the net, but when used in a code-signing context, there are a lot of examples for certificate generation and people saying that you can use them for testing in an environment that's closer to a production environment (which I have done in the past), but I can't find any hard reasons as to why not to use a self-signed certificate for code-signing production software.
It's been a while since I've had to look a the certificate side of things, but this just feels wrong.
It's possible that just I'm not experienced enough with certificates to see why this is a good idea. Does anyone have any input to help me understand the full implications of this?
Using a self-signed certificate should not work. The idea is that "someone trustable" (not you; but Verisign or some other party that should check your credentials) confirms that something is certified.
I'm not sure exactly how this works in Windows. Might be that they didn't implement something properly.
There is no problem using a self signed certificate in windows. Just put the root CA certificate and the signing cert in the Windows cert store of the client machines that will run the signed application and/or driver.
Managing self signed certs within an organization is a PITA. Hence why people pay good money to get somebody else to do it.
If you are going to distribute your signed code outside your organization it is even more painful as you will need to persuade your customers to accept your CA certificate, and nobody should ever accept a root certificate from an unknown source or sent via an insecure or unverifiable means.
See this answer for instructions on creating a self signed CA and signing certificates using it.
The same is possible (but in my opinion more complicated) using Windows PowerShell, The sequence is he same but the commands change.

How Can I Prevent Needing to Re-sign My Code Every 1 or 2 Years?

I was reading What happens when a code signing certificate expires - Stack Overflow and wondering about a more solid answer. The answer provided was more about setting up your own CA. Even with your own CA you will still need to deal with expiring code certificates.
If you signed the code without using a time stamping service, after the certificate expires your code will no longer be trusted, and depending on security settings it may not be allowed to run. You will need to re-sign all of your code with a new certificate, or with a renewed certificate, every 1 or 2 years.
Trusted (digital) timestamping allows the digital signature to be valid even after the certificate itself has expired. You would need to re-sign code with the new certificate only if you have made changes.
Does this all sound correct? If so, I need recommendations on what timestamping service to use, preferably from someone who has actually used one. I'd also like to know if there are any in-house solutions, similar to being your own CA.
Right now this applies to PowerShell scripts, but I will eventually have the same issue with other code.
Update: Sample of how to sign a PS script with a timestamp (you can make a script for this):
Set-AuthenticodeSignature -filepath "D:\Projects\A Sample\MyFile.ps1"
-cert gci cert:\CurrentUser\My -codesigning
| where -Filter {$_.FriendlyName -eq "Thawte Code Signing"}
-IncludeChain All
-TimeStampServer "http://timestamp.verisign.com/scripts/timstamp.dll"
Then, to see the Signer Certificate and TimeStamper Certificate, you can do this:
Get-AuthenticodeSignature MyFile.ps1 | fl *
It gives you the Subject (CN, OU, etc.), Issuer, Before/After Dates, and Thumbprints for both your cert and the timestamper's cert. You also get a message indicating the status of the signature.
You're better off selecting one of the trusted certificate providers (Verisign, Thawte, Comodo, etc.). This allows you to sign your software without the user explicitly trusting your private root CA. We've used both Verisign and Thawte, Comodo even GoDaddy with timestamping without any issues with the software becoming invalid even years after the certificate expires.
Time stamping is a free service -- it's really only a trusted provider verifying that you signed the file at a given time. Verisign's timestamp service is the standard one. The final example in the help for Set-AuthenticodeSignature demonstrates how to use it.
Lee Holmes [MSFT]
Windows PowerShell Development
Microsoft Corporation
You can't really escape having to resign code eventually. The advantage to running your own CA is that you could choose to issue your code-signing certs with longer lifetimes than the default, thereby allowing you to wait longer before having to resign anything. The downside is of course having another service or server (your CA) to deal with.