I am trying to connect to Bloomberg FIX (EMSX) through SSL using QuickFIX/n.
I have got 3 .pem files from Bloomberg using which I have to configure the SSL connectivity. I have gone through all the available reference material on the internet but in vain.
Can anybody help in doing this configuration??
Thanks in advance.
Have a look at using Stunnel and check out this question...
QuickFIX/n expects .pfx extension files. See http://quickfixn.org/tutorial/configuration.html#ssl
This extension is normally used for PKCS #12 encoded files which contain the certificate and the private key, protected by a password.
You may need to convert your .pem files so that you have one .pfx file which contains your private key and the certificate and another file which contains your CA Certificate. The SSLCertificate and SSLCACertificate configuration parameters of the QuickFIX/n session should then be set to the path of these two files. SSLCertificatePassword should contain the password.
QuickFIX/n is strict and requires the FIX Acceptor (Bloomberg EMSX in this case) to have the x509v3 extended key attribute "TLS Web Server Authentication" (1.3.6.1.5.5.7.3.1) to be explicitly present in the server certificate that is presented during the SSL handshake.
If not present, you will get an error message in the QuickFIX/n session event log:
Remote certificate is not intended for server authentication: It is
missing enhanced key usage 1.3.6.1.5.5.7.3.1
Some FIX Acceptors still don't define this in their server certificate, so even if you go to the effort of converting your PEM files to PFX, it still won't work.
You can use Stunnel which doesn't seem to mind what purpose was intended for the server certificate that is presented. As an added bonus Stunnel understands PEM files so no need to convert. However, you should be aware that if your end goal is end-to-end encryption, the hop between your QuickFIX/n application and Stunnel will be in clear text.
Related
I am attempting to build an application that would make use of client-certificates to authenticate the user attempting to access the application. I am using a self-signed CA as described here. While, I have done quite a bit of research, I have yet to come away with the "proper" approach to authenticating a client-certificate.
First, it seems as if this can be done at both the application level (using .NET classes such as X509 store) or in IIS itself. What are the advantages or disadvantages of each approach?
If I were to choose to validate the certificate with in my application code, what is the proper field to validate? For example, this question uses the serial number. However, for my "test" certificates, the serial number is literally four characters (not counting spaces). What is the proper approach to ensuring that the client-certificate really was issued by me?
I attempted to apply this at the server level (I am using IIS Express for testing). However, I do not get a request for a certificate, just a 403.7 - Forbidden, error ( with the following web.config settings <access sslFlags="Ssl,SslNegotiateCert,SslRequireCert" />). However, if I remove SslRequireCert, I am able to at least "see" many certificates using the following code snippet:
X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate cert = store.Certificates[0];
Even if this issue (3) were resolved, is there any way, using IIS, to authenticate a certificate without having to map it to a Windows account?
I have tried installing the client certificate both in Firefox and in my PCs keystore. Thanks for any guidance.
While working on this question, I identified that the problem is slightly different than initially stated, so I am changing title and description
I'm trying to authenticate myself against WebService using my client certificate. I am using WebRequest for that purpose. I need to use self-signed certificate, without registering it in Windows X509 trusted root store.
The way I know if client certificate is presented or not is by examining request object on the server
I tried to use code from this question as a guidance. It doesn't work on .NET. Here is my code:
var certificate = new X509Certificate2(Properties.Resources.MyCert);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(host);
req.ClientCertificates.Add(certificate);
WebResponse resp = req.GetResponse();
var stream = resp.GetResponseStream();
What I observe is that even though req.ClientCertificates does contain certificate with a valid private key, that certificate is never presented to server. I get no indication from WebClient that certificate is not used during handshake.
If I put certificate into "trusted root", the code will work (even when certificate is not in "personal").
My questions are:
Since certificate is usable when it's placed in "trusted root", I assume it is likely due to policy or something of that kind. Is it possible to coerce .NET to ignore policy settings and use supplied client certificate during TLS negotiation?
If abovementioned coercion is not possible, is there a call which will tell me ahead of time, that certificate I am about to use is not usable, and will be ignored? Alternatively, if such call is not available, could I make WebClient fail indicating a certificate error, instead of silently skipping over?
NOTE: I am aware that configuring certificates as described by Microsoft will work. This is NOT what I am looking for. I don't want to register potentially insecure certificate in trusted root, because this is potentially security hazard. I want to use cert on client without registering in store, or at least to get an exception indicating that certificate cannot be used. I realize that there can be multiple reasons why certificate cannot be used for a session, but there must be an exception, or at least some sort of indication on the client side that it cannot use specified cert. Instead, client simply doesn't present one.
When you instantiate your X509Certificate2, is the PrivateKey property set? If it is null, you are missing the private key, meaning the SSL/TLS client will be unable to authenticate you.
Make sure you are loading the certificate from a PFX file (or similar) instead of a CER. These contain the private key, too. They are usually password protected for that purpose. See How to retrieve certificates from a pfx file with c#? for more info.
I'm trying to develop an ASP.net site that reads the clientCertificate to ensure a smart card was used to access the website (trying to do away with username/password login).
The process I have in my mind is:
User registers an account and C# records user's clientCertificate (public).
The user can then log in the next time with that same clientCertificate, and they are now an authenticated user if hash valid.
I will use the code below to ensure authenticity of certificate. The browser should deal with private keys and ensure the certificate was NOT faked.
Based on Subject+certificate combination, C# assigns them their role-access.
The following code can be used for authenticity of certificate right?
X509Certificate x509Cert = new X509Certificate(Request.ClientCertificate.Certificate);
SHA1 sha = new SHA1CryptoServiceProvider();
byte[] hashvalue = sha.ComputeHash(Request.ClientCertificate.Certificate);
byte[] x509Hash = x509Cert.GetCertHash();
// compare x509Hash WITH hashvalue to ensure they are a match.
// If not, possibly faked certificate, not a real smartcard???
Is this how SmartCard authentication process should work???
If you just need to authenticate users with client certificates you should do this in IIS. You do not need to add any code at all to your application:
Specify Whether to Use Client Certificates (IIS 7)
Unless you need to link client certificates with database accounts or perform an additional validation step. But still for client certificate authentication I would stick with IIS settings.
Update:
In case you need to manipulate the client certificate you can do:
X509Certificate2 x509Cert2 = new X509Certificate2(Page.Request.ClientCertificate.Certificate);
And then access its properties such as:
x509Cert2.Subject
However, leave the validation piece up to IIS. If the client presents a bad certificate your asp.net code will not even execute since IIS will reject it
See this thread, sir. You do not need to verify authenticity explicitly in your code. IIS will do it for you.
Does IIS do the SSL certificate check or do I have to verify it?
IIS even tries to check revocation lists (however, this is often disabled if the CRL is large). An OCSP responder should be used to validate in cases where the CRL is very large or latency in checking it is high http://www.axway.com/products-solutions/email-identity-security/identity-security/va-suite.
Client-certificate authentication is done during the SSL/TLS handshake.
It is usually done using a Public Key Infrastructure, whereby the server has a (fixed) list of trusted CA certificates which it uses to verify the client certificate (in the same way as clients to it for the server). Once the certificate is presented to your application after this stage, you will know that:
the client has the private key for that certificate (guaranteed by the Certificate Verify message in the TLS handhsake (the SSL/TLS stack will verify this for you, no need to implement anything);
the client has the identity described in the certificate, because you will have verified it against your trusted CA.
The verification against a trusted CA requires the user to be registered with that CA in advance. You can't just authenticate any certificate if it hasn't been issued by a CA you trust. (Mapping the certificate's subject to a local user ID is another matter: you could do this upon first connection if needed: have your own database or directory service to map the Subject DN to another kind of user ID in your application, for example.)
User registers an account and C# records user's clientCertificate
(public). The user can then log in the next time with that same
clientCertificate, and they are now an authenticated user if hash
valid.
It sounds like you want to allow any certificate to be presented and use it for the initial registration, without necessarily resorting to a commonly trusted CA.
This is possible in principle, and I've done this to explore alternatives to PKI in Java.
To do this, you need to let any certificate through as far as the SSL/TLS handshake is concerned, and verify the certificate itself later. (You do need to use some form of verification.) You are still guaranteed with this that the client has the private key for the public key certificate it has presented.
Doing this requires two steps:
You need to be able to advertise the fact that you're going to accept any certificate, by sending an empty list of certification authorities in the Certificate Request TLS message (explicitly allowed by TLS 1.1).
Configure the SSL/TLS stack to trust any certificate (once again, when you do this, do not forget to implement your own verification system within your application, otherwise anything will really get through).
In .Net, while it should be possible to address the second point using a remote certificate validation callback, I have never found a way to alter the first point (this was also asked in this question).
In Java, the JSSE's X509TrustManager allows you to address both points.
I'm trying to figure out if there is any way to have a .NET client use a client certificate without involving the Windows keystore in any way.
I have a code snippet like this:
test1.Service s = new test1.Service();
X509Certificate c = X509Certificate.CreateFromCertFile(#"C:\test.pem");
s.ClientCertificates.Add(c);
int result = s.TestMethod();
However, this only works if I also have the certificate referenced in "test.pem" installed in my certificate store. I assume this is because the key is necessary for the negotiation. If I don't have the cert/key in the store, the cert is not sent with the request.
What I want to do is be able to provide both the certificate and private key from a file or files and not involve the Windows certificate store in any way.
Is there any way to do this?
I'm going to post an answer to my own post, but will leave it open to see if others can solve it different.
Basically, I'm punting. If you have a PKCS12 file (with both key and cert in it) you can use the X509Certificate2 class to load that file and use it, and it won't interrogate the keystore.
I could not find a way to do this with flat PEM key and cert files (like what you'd need with Python, for example).
I am attempting to use the .Net System.Security.SslStream class to process the server side of a SSL/TLS stream with client authentication.
To perform the handshake, I am using this code:
SslStream sslStream = new SslStream(innerStream, false, RemoteCertificateValidation, LocalCertificateSelectionCallback);
sslStream.AuthenticateAsServer(serverCertificate, true, SslProtocols.Default, false);
Unfortunately, this results in the SslStream transmitting a CertificateRequest containing the subjectnames of all certificates in my CryptoAPI Trusted Root Store.
I would like to be able to override this. It is not an option for me to require the user to install or remove certificates from the Trusted Root Store.
It looks like the SslStream uses SSPI/SecureChannel underneath, so if anyone knows how to do the equivalent with that API, that would be helpful, too.
Any ideas?
It does not look like this is currently possible using the .NET libraries.
I solved it by using the Mono class library implementation of System.Security.SslStream, which gives better access to overriding the servers behavior during the handshake.
What the certificate validation is doing is validating all certificates in the chain. In order to truely do that it just contact the root store of each of those cerficates.
If that's not something you want to happen you can deploy your own root store locally.
It is not the validation part I want to change. The problem is in the initial handshake, the server transmits the message informing the client that client authentication is required (that is the CertificateRequest message). As part of this message, the server sends the names of CAs that it will accept as issuers of the client certificate. It is that list which per default contains all the Trusted Roots in the store.
But if is possible to override the certificate root store for a single application, that would probably fix the problem. Is that what you mean? And if so, how do I do that?