Read certificate from pdf - c#

I'm using ITextSharp in order to read certificate informations from digitally signed pdf document.
The ITextSharp.Text.Pdf.PdfPKCS7 class exposes three properties:
Certificates (as list)
SignCertificate (as single object)
SignCertificateChain (as list)
How can I combine these three properties in order to achieve all info about a single certificate?
I'd be able to show all certificate path (all nested certificates).

Certificates gives you the list in no particular order, including certificates that weren't used for the main signature.
SignCertificate gives you the certificate of the actual signer.
SignCertificateChain gives you the list where the first Certificate is the SignCertificate, the next is the certificate of the instance that issued the SignCertificate, the next is the certificate of the instance that issued the previous certificate, and so on. This can return less certificates than Certificates, because only the certificates used for the main signature will be returned.
So you don't need to 'combine' the properties to show the certificate path, you just need SignCertificateChain. Note that your question isn't entirely clear:
'all info about a single certificate'
kind of contradicts with
'show all certificate path (all nested certificates)'
If you want to visualize the chain that resulted into the signing certificate, you need to look at more than a single certificate (unless the certificate was self-signed in which case there's only one element in the chain).

Related

X509Store Location versus Store?

I am using the X509Store in C# DotNet to traverse the certificate stores. However, I am not clear on what the difference is between a certificate location and a certificate store. For example, the locations are LocalUser and LocalMachine. Examples of Stores are My (Personal) and Root. What is the difference between the Personal store on LocalMachine versus Personal store on LocalUser? What does it even mean to have a Personal store on LocalMachine?
There are a few purposed stores (C# name in bold, UI display name in parenthetical italics):
My (Personal): when searching for a leaf/end-entity certificate this store is usually what gets searched. This is usually the only store that has certificates with associated private keys.
If you browse to a site using client authentication certificates IE will choose candidate certs from the My store. (Forward reference: The location for this is CurrentUser)
When configuring IIS from a GUI it will show certificates from the My store. (Forward reference: The location for this is LocalMachine)
Root (Trusted Root Certificate Authorities): When doing a chained-trust decision, such as in TLS, if the other end of the chain is represented in this store then the original cert is trusted.
In addition to the certs explicitly in this store it exposes a virtual view over AuthRoot.
AuthRoot (Third-Party Root Certification Authorities): When registering an additional trusted root you "should" do it in the 3rd party store, for... reasons? While the LocalMachine one seems to work fine, the CurrentUser one seems to mostly be for show.
CertificateAuthority (Intermediate Certificate Authorities, known as "CA" to the underlying system): This is a repository of known intermediate certificates. When doing a chain build the system will look for a parent here, then in Root, then maybe over the Internet. If the chain was trustworthy then the certs in the middle of the chain may be cached here for future lookups.
Disallowed (Untrusted Certificates): If a part of a certificate chain is found in this store, the chain is considered untrustworthy.
AddressBook (Other People): A collection of certificate that you know about. Yep, about that specific. It gets searched by some programs/libraries when trying to match a peer certificate. For example, a find-by-issuer-and-serial-number notice in SignedXml.
There are a couple more standard ones, you can read about them at TechNet. You can also create your own certificate store using the X509Store(string, StoreLocation) overload. (It's sometimes useful for managing applications, but the certificate manager UI gets a bit confused when you have private keys in a custom store; it expects them only in the My store).
So that's StoreName. StoreLocation is perhaps better thought of as "store owner". A standard user could decide that they trust certificates issued by some private CA, so they could add it to their Root store. Since it's their store it won't affect any other users on the system. The system itself also owns stores. For example, the TLS certificate for the computer really belongs to "the computer", and multiple administrators may be involved with managing it. Since it's pretty unusual to search through your friend's stuff, the StoreLocation comes down to "me, as a user" (CurrentUser) or "this computer" (LocalMachine) for which store to use.
Things get slightly murky now: On Windows almost every CurrentUser store (with a notable exception of the My store) exposes a view into the LocalMachine equivalent store. So when you enumerate the certificates in CurrentUser\Root you're getting both the certificates explicitly added to CurrentUser\Root and also the certificates explicitly added to LocalMachine\Root. This can cause confusion since you can see a certificate when enumerating, call Remove with it as an argument, and it's still there when enumerating again.
In my experience, most interactions with cert stores are to the My store. At which point the decision tree comes down to something like this:
Am I a service with a dedicated user account?
new X509Store(StoreName.My, StoreLocation.CurrentUser)
Am I service without a dedicated user account?
new X509Store(StoreName.My, StoreLocation.LocalMachine)
Else
new X509Store(StoreName.My, StoreLocation.CurrentUser)
But that's a big generalization.
The personal store for LocalMachine contains machine certificates. An example of a certificate that lives in such store is a SSL certificate that is used by IIS to protect HTTP traffic. There is only one such store on the machine.
The personal store for LocalUser contains user certificates. An example of such certificate is an S/MIME certificate used to sign email messages. Each user has his/her own store of this type.

Given two X509Certificate how to tell if one is signed by the other

I have two serialized certificates in the DB from which I can construct the X509Certificate. How to tell if one certificate is signed by the other. I don't want to check based on the IssuerName as it is not reliable(for my scenario).
IssuerName property and Authority Key Identifier extension are the way to find relationships between certificates. Once you match them, you can verify if the supposedly parent certificate is actually the CA certificate of the one being checked. I am not sure that such checks are possible with .NET Framework alone, and our SecureBlackbox does this easily, with one method.

Validate if certificate is revoked

I have the following situation:
Java Applet for digital signature - on client side
Validation of digital signature and digital certificate - on server side
I'm using the following C# code to validate the signature and the certificate:
ContentInfo content = new ContentInfo(pdf);
SignedCms signedMessage = new SignedCms(content, true);
signedMessage.Decode(assinatura);
signedMessage.CheckSignature(false);
Where:
pdf - signed pdf file
assinatura - pdf's signature - in my case, the signature it's not with the pdf file
By the tests I made, the code validate the certificate chain, the expiration and others...
However, I would like to know a few things:
This code validates that the certificate used for signing is revoked? If it does not validate, how could I make such a validation system at this point?
Is there a way to create a certificate that is revoked for testing?
Revocation check is performed by
Obtaining CRL that can contain information about the status of the certificate
Sending OCSP request to the server authorized to respond to such requests
If OCSP server's URL is present, OCSP is the preferred (for security) method to check revocation, but in general both checks should be performed.
OCSP and CRL operations are supported by our SecureBlackbox, CryptLib, BouncyCastle. In SecureBlackbox you will find a high-level CertificateValidator class which does all checks for you (at the same time letting you interfere in all aspects of the procedure).
There's no way to create a revoked certificate unless you run your own private certificate authority (but if you did, probably there would be no question). The reason is that you can't put your certificate's ID to the CRL sent by CA (or make the third-party OCSP responder do this).
Oh, I can see one way - buy a certificate, then contact the CA and tell them that you've disclosed the private key. They will block the certificate. But this is quite costly method :).

Clearly recognize a certificate in Windows certificate store

I'm developing a library which generates XML data and signates the generated XML. I've installed a pkcs12 certificate (generated with OpenSSL from pem file) into the windows certificate store.
I'm loading the certificate from C# code with
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 cert = null;
foreach (var item in store.Certificates)
{
if (item.SubjectName.Name.Contains("CN=IDENTIFIER"))
{
cert = item;
break;
}
}
store.Close();
In my case the CN identifier is: my prename + surname. The cert comes from a third party. So I think I have no influence on the identifiers.
And here comes the question:
Is there any way to identify exactly this certificate from C#. In future it could be possible, that multiple certificates have the same X509 parameters (CN etc etc).
Thank you in advance.
Yes, it's possible that CN contains the same identifier (eg. when the certificate is issued for business entity).
Certificates are usually distinguished by one of following combinations:
1) Issuer name (not CN, but RDN, complete name record with multiple fields) + certificate serial number (it's unique within one CA)
2) Issuer name + certificate hash
If you don't know the issuer name before searching for the certificate, you can present the list of found certificates to the user and once he select one of certificates, store certificate hash for future reference.
On smaller systems (end-user's computer) the number of certificates in MY store is usually small and the chance of hash collision is minimal. On large systems the chance is higher and that's why Issuer name is used as well.
Expanding on Eugene's answer...
The Certificates property of X509Store is an X509CertificateCollection.
You'll probably be interested in its Find method and the X509FindType. It offers a number of ways to search for a certificate. Strictly speaking, both the subject DN and the subject alternative names should matter to identify the entity associated with a certificate. However, few tools do this from a presentation point of view (this could get quite cluttered in a table for example).
As GregS and Eugene pointed out, the certificate thumbprint (also known as fingerprint/hash in other tools) will identify a specific certificate uniquely, irrespectively of its issuer. It can be used with X509FindType.
Thumbprints are used in multiple places in the Windows/.Net/SSL world. In particular, it's the way to pick a given certificate to install on an HTTPS port.

Can I verify an XMLDSIG signature in .NET without requiring the root certificate be installed?

I'd like to use XMLDSIG for verifying that a .config file has not been tampered with. I also want to be able to verify the signature chain so that I can trust the signature.
I've got three certificates in the chain:
Root CA -> Intermediate Signing CA -> Signing Key
I check that the file is signed with a key that is issued by the intermediate CA.
I'd like to do this without installing any certificates in the user's Windows certificate store. These are self-signed certificates, so not every user is going to want me installing them in their Root store. I don't have a problem with installing them in my root store.
I have the original .CER files -- they're included in the Signature block, and I can include them with the verification code. I can build a certificate chain from this by using X509ChainPolicy.ExtraStore.
If the certificates are not installed in the root store, and I verify the chain, then X509Chain.Build returns false, and the chain has a X509ChainStatusFlags.UntrustedRoot in it.
Can I add trusted certificates just for the duration of this operation?
Assuming you have physical copies of the public keys of ALL signing certs in the trust chain, then this is possible by using the OpenSSL command line tool.
http://www.madboa.com/geek/openssl/#verify-standard
It's a bit of a steep learning curve at first, but a very powerful utility.
If you don't have the signing certs, then you cannot verify anything. That would be the same as trying to verify a human signature without having seen the original. You have nothing to compare to, so how could you verify the authenticity?
Update
There's something here perhaps that could help you:
http://social.msdn.microsoft.com/Forums/eu/clr/thread/1966a6e8-b6f4-44d1-9102-ec3a26426789

Categories

Resources