Does CAPI check the signature on certificate (made by Root certificate or by a parent certificate) when a method X509Certificate2.Verify is called? Is the answer is Yes what CAPI-method performs the checking?
Thanks!
X509Certificate.Verify method executes CertCreateCertificateChainEngine unmanaged function. The function performs all checks, including chain building, certificate path and signature validation for each certificate and revocation checking. CRL signatures are checked as well.
Related
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.
Does root CA certificate in a certificate chain will also checked for revocation status using CRL downloaded from the root CA CDP?
It depends on certificate chaining engine implementation. For example, Microsoft CryptoAPI defaults to no revocation checking. Options are:
Leaf certificate only
Entrie chain, including root
Entire chain excluding root
.NET wrapper X509Chain defaults to entire chain excluding root. Applications are responsible to configure revocation checking options when calling chaining engine. Non-Microsoft platforms and tools (OpenSSL, for example) are configurable as well and exact default behavior depends on an implementation and client configuration.
I have a package that I signed with my own certificate, issued by my own CA.
I signed a nuget package with the certificate.
When I add the root CA in the trust store of the machine, I can verify the signature successfully with nuget, using
nuget verify test.nupkg -Signatures
But, if I remove the root from the trust store, and instead, I add the thumbprint of my certificate as a trusted signers, in nuget, setting allowUntrustedRoot to true, I cannot verify the signature, for some reason.
> nuget trusted-signers
Registered trusted signers:
1. MyCert [author]
Certificate fingerprint(s):
[U] SHA256 - 39544DEE346D61EB2FF5CF4A35EF4B42DE5B4641E1B9AAA098A2A5291F683631
But
> nuget verify test.nupkg -Signatures
Verifying Test
C:\test.nupkg
Signature Hash Algorithm: SHA256
WARNING: NU3027: The signature should be timestamped to enable long-term signature validity after the certificate has expired.
Signature type: Author
Verifying the author primary signature with certificate:
Subject Name: CN=Test Certificate, OU=Test, C=BE
SHA1 hash: 679B1E503720C69D981B9CC4F0199D5D8593375A
SHA256 hash: 39544DEE346D61EB2FF5CF4A35EF4B42DE5B4641E1B9AAA098A2A5291F683631
Issued by: CN=Test Root, OU=Test, O=Test, C=BE
Valid from: 10/31/2019 10:29:54 AM to 9/24/2023 11:37:39 AM
NU3018: The author primary signature found a chain building issue: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.
WARNING: NU3018: The author primary signature found a chain building issue: The revocation function was unable to check revocation because the revocation server could not be reached. For more information, visit https://aka.ms/certificateRevocationMode.
WARNING: NU3018: The author primary signature found a chain building issue: The revocation function was unable to check revocation for the certificate.
Finished with 1 errors and 3 warnings.
Package signature validation failed.
What's the point of adding a trusted signer and setting allowUntrustedRoot to true if the signature is not verify. I mean, it's apparently enough to add the root certificate to the trust store for the signature to be verified, without doing anything with the configuration.
I would like, if possible, to be able to not import the root CA in the trust store, and only use the configuration of Nuget to verify successfully the signature.
Thanks.
Our belief is that if you tried to use that package in a project with those trust policy settings appropriately in nuget.configs, restore will succeed.
Please confirm that.
Next, nuget verify has a -config switch -- please try passing in the path to your nuget.config.
If the first test works, and the second test doesn't, nuget may have a bug in the verify command. If so, please file an issue at https://github.com/nuget/home/issues/
-Rob Relyea (NuGet Client Team)
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.
I noticed that in the keytool documentation it reads
"jarsigner [...] checks whether or not the public key of that certificate is 'trusted', i.e., is contained in the specified keystore."
whereas the jarsigner manpage states
"A keystore is not required when verifying [...]", and that the utility will always verify against the certificate supplied with the jar.
In the way I see it that would kind of defeat the purpose, since it would only certify that the jar was not altered since it was signed but not that it was signed by some specific authority/supplier.
Is there some way to make the verification fail if the certificate used to sign the jar is not known/trusted on the runtime system?
Or do I have to use a script to call
jarsigner -verify -verbose -keystore ...
and parse the output to see whether there is an entry for the signing certificate in the local (runtime) keystore?
Confused,
Peter
jarsigner utility is quite useless for JAR signature verification, as it does not verify the signer certificate, does not check trusted timestamps on the signature and does not provide usable result (parsing console output is not a good solution).
To avoid this limitations we have chosen to write our own verify_jar utility.