TLS Upgradation - web-services

public bool CheckValidationResult(ServicePoint sp,
System.Security.Cryptography.X509Certificates.X509Certificate cert, WebRequest req, int problem)
{
return true;
}
Here , I am in the position to access the web service using Tls 1.2 alone from the web service.
So , after adding the below lines before the return true in the method. ,
Then ,I can be able to access the service and also able to get the response.
Is it the correct way to handle these or any other way is there ? ? ?
Please help anyone who has experience on this .
Thanks in Advance.
//Here given protocol version with or operator accepting tls 1.1 ,1.2 and 1.0 along with ssl3
sp.Expect100Continue = true;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Tls12;

No, that is not the correct way! Although I am aware that 100's of developers do this (return true for certificate validation), however their communication is no longer secure and is now subject to middleman and replay attacks, which are the most-common SSL attacks known to man.
The truth is you need provide a "comprehensive implementation" for certificate validation, which is based-on several RFCs (search for: X.509 Certificate validation). At a minimum you need to check the certificates validity (dates), validate subject signature hash using CA's public key and validate CA's CRL revocations (ensure server certficate has not been revoked). However ...
To keep things simple, without degrading TLS's integrity, you could simply check the "problem" (int problem), then return true or false, based on the value of problem. The OS should set the problem value, based-on internal OS security policy. Personally, I still would prefer "comprehensive implementation", because OS security policy can be weak, inundated or corrupt (hacked). Let me know if you need more details on "comprehensive implementation"

Related

How to do "Client Authentification" if I'm not able to provide private key

I want to set up my local server to communicate with my client. They build TLS connection using Openssl. I try to implement double side authentication, like server would verify client and client also needs to verify server.
When I use certificates generated by my self, everything works fine. The code is as following. It's C++ code in client. I set up client cert, private key and intermediate cert. In server side I saved a CA cert.
The relationship is: CA signs intermediate cert, intermediate cert signs client cert.
As we know, the reason that we need to provide client private key is the client will signature a "challenge" then send to server. Server could get client public key by certificate chain and use it to decode the encrypt "challenge" to see if they matched. You could see this link for detailed process:
https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake
However in my scenario, I have no permission to get the private key. I only have an API to call, which takes the digest or anything we want to encode as input and return a string encoded by client private key.
Therefore I'm not able to pass any "ClientPrivateKeyFileTest" to TLS.
I searched openssl source code but all handshakes were done in this function: SSL_do_handshake() and I'm not allowed to modify this function.
// load client-side cert and key
SSL_CTX_use_certificate_file(m_ctx, ClientCertificateFileTest, SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(m_ctx, ClientPrivateKeyFileTest, SSL_FILETYPE_PEM);
// load intermediate cert
X509* chaincert = X509_new();
BIO* bio_cert = BIO_new_file(SignerCertificateFileTest, "rb");
PEM_read_bio_X509(bio_cert, &chaincert, NULL, NULL);
SSL_CTX_add1_chain_cert(m_ctx, chaincert)
m_ssl = SSL_new(m_ctx);
// get_seocket is my own API
m_sock = get_socket();
SSL_set_fd(m_ssl, m_sock)
// doing handshake and build connection
auto r = SSL_connect(m_ssl);
I think all handshake processes would be done after I call SSL_connect(). So I wonder is there other way I can do to complete the client-authentication?
For example, I could skip adding private key step but set up a callback function somewhere which can handle all cases when SSL needs to use private key to calculate something.
PS: The API is a black box in the client machine.
One more thing, these days I found that openssl engine may help this problem. But does anybody know what kind of engine is useful for this problem? The EC sign, verification or others?
Final update: I implemented a OpenSSL engine to reload EC_KEY_METHOD so that I'm able to use my own sign function.
Thanks a lot!

aws root pinning error CURLE_SSL_PINNEDPUBKEYNOTMATCH

I am using libcurl and shifting cert pinning to AWS root as per this document https://www.amazontrust.com/repository/
I used the SHA-256 Hash of Subject Public Key Information data from that website, formed a string:
static string PUBLIC_KEY = "sha256//fbe3018031f9586bcbf41727e417b7d1c45c2f47f93be372a17b96b50757d5a2;sha256//7f4296fc5b6a4e3b35d3c369623e364ab1af381d8fa7121533c9d6c633ea2461;sha256//36abc32656acfc645c61b71613c4bf21c787f5cabbee48348d58597803d7abc9;sha256//f7ecded5c66047d28ed6466b543c40e0743abe81d109254dcf845d4c2c7853c5;sha256//2b071c59a0a0ae76b0eadb2bad23bad4580b69c3601b630c2eaf0613afa83f92";
and set the string to curl
curl_easy_setopt(handle, CURLOPT_PINNEDPUBLICKEY, PUBLIC_KEY.c_str());
The curl error I get is CURLE_SSL_PINNEDPUBKEYNOTMATCH
Google does not have any insight into why, as far as I searched. If anyone has any input on how to fix this and still pin to the root, it would be super useful. Thanks.
Found the reason. Root pinning is not supported yet.
13.11 Support intermediate & root pinning for PINNEDPUBLICKEY
CURLOPT_PINNEDPUBLICKEY does not consider the hashes of intermediate & root certificates when comparing the pinned keys. Therefore it is not compatible with "HTTP Public Key Pinning" as there also intermediate and root certificates can be pinned. This is very useful as it prevents webadmins from "locking themself out of their servers".
Adding this feature would make curls pinning 100% compatible to HPKP and allow more flexible pinning.
https://curl.haxx.se/docs/todo.html

SSLSniff error: "SSL Accept Failed"

I'm trying to use SSLSniff's tool, and I have some technical issues... I've been looking for any similar problems, but the only results are from Twitter feeds, with no public useful answer. So, here it is:
(My version of SSLSniff is 0.8) I'm launching sslsniff with args:
sslsniff -a -c cert_and_key.pem -s 12345 -w out.log
where: cert_and_key.pem file is my authority's certificate concatenate with my unencrypted private key (in PEM format of course), and 12345 is the port where I redirect traffic with my iptables rule.
So sslsniff is correctly running:
INFO sslsniff : Certificate ready: [...]
[And anytime I connect with a client, there are these 2 following lines:]
DEBUG sslsniff : SSL Accept Failed!
DEBUG sslsniff : Got exception: Error with SSL connection.
On my client' side, I've register my AC as a trusted CA (with FF). Then when I connect through SSL I'm having the error:
Secure Connection Failed.
Error code: ssl_error_bad_cert_domain
What is super strange (moreover the fact that the certificate is not automatically accepted since it should be signed by my trusted CA) is that I cannot accept the forged certificate by clicking on "Add exception..." : I am always returning to the error page asking me to add an(other) exception...
Moreover, when I try to connect to for example: https://www.google.com, SSLSniff's log is completed with a new line :
DEBUG sslsniff : Encoded Length: 7064 too big for session cache, skipping...
Does anyone know what I'm doing wrong?
-- Edit to summer up the different answers --
The problem is that SSLSniff is not taking care of alternive names when it forges certificates. Apparently, Firefox refuses any certificate as soon as the Common Name doesn't match exactly the domain name.
For example, for Google.com : CN = www.google.com and there is no alternative name. So when you connect to https://www.google.com, it's working fine.
But for Google.fr : CN = *.google.fr, with these alternative names: *.google.fr and google.fr. So when you connect to https://www.google.fr, FF is looking for alternative names and, since it obviously doesn't find any, refuses the malformed certificate.
... So a solution would be to patch/commit... I don't know if Moxie Marlinspike has intentionally forgot this functionnality because it was too complicated, or if he was just not aware of this issue. Anyway, I'll try to have a look at the code.
The session encoded length error message: When caching the SSL session fails, it means that SSL session resumption on subsequent connections will fail, resulting in degraded performance, because a full SSL handshake needs to be done on every request. However, despite using the CPU more heavily, sslsniff will still work fine. The caching fails because the serialized representation of the OpenSSL session object (SSL_SESSION) was larger than the maximum size supported by sslsniff's session cache.
As for your real problem, note that sslsniff does not support X.509v3 subjectAltNames, so if you are connecting to a site whose hostname does not match the subject common name of the certificate, but instead matches only a subjectAltName, then sslsniff will generate a forged certificate without subjectAltNames, which will cause a hostname verification mismatch on the connecting client.
If your problem happens only for some specific sites, let us know the site so we can examine the server certificate using e.g. openssl s_client -connect host:port -showcerts and openssl x509 -in servercert.pem -text. If it happens for all sites, then the above is not the explanation.
Try a straight MITM with a cert you fully control , and make sure you don't have some OCSP/Perspectives/Convergance stuff meddling with things. Other than that, maybe add the cert to the OS trusted roots. I think FF on windows uses the windows cert store (start->run->certmgr.msc). It may also be worth trying with something like Burp to see if the error is localized to SSLSniff or all MITM attempts.

manual netlogon

Anyone know how I would do a manual netlogon or any other way to authenticate a user on a remote domain? I need to test authentication.
Right now we're using impersonation and calling an arbitrary function. The problem is that arbitrary winapi function that will login. The problem is that some domains allow that function to be called by null session thus causing false positives.
The only goal of this is to get reliable, fast authentication against a remote domain that the local computer is not added to so I wouldn't deny another approach.
This is the solution that we got from filing a MSDN ticket.
if(!LogonUser(username.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, &token))
{
debug->DebugMessage(Error::GetErrorMessageW(GetLastError()));
CloseHandle(token);
RevertToSelf();
return false;
}
if(!ImpersonateLoggedOnUser(token))
{
debug->DebugMessage(Error::GetErrorMessageW(GetLastError()));
CloseHandle(token);
RevertToSelf();
return false;
}
...
int err = NetUserModalsGet ....
if (err != ERROR_SUCCESS) logged_on = false;
RevertToSelf();
If all you want to do is answer the question "are these credentials valid for a given domain which I may not be a member of?" then you might see some millage in existing things that do this. A number of Linux/UNIX applications offer NTLM authentication against an arbitrary domain without domain membership. Most use winbindd, which I suspect running on a Windows system would be asking for trouble.
Notably though there's an apache module for this, which can run without any external dependencies. You might have some luck looking through their sources, in particular mod_ntlm.c and seeing how they craft the request packets for the domain controller and parse the responses.
Not sure if you've considered the fact that there are many infrastructure configuration concerns associated with using Windows integrated security on remote domains. Are the trust policies appropriately in place? Which SSPI are you using NTLM, Kerberos, PKU2U, DPA, etc?
Have these been appropriately configured for your usage scenario?
Ok... After hearing more about your scenario, have you considered leveraging a custom GINA?
http://msdn.microsoft.com/en-us/library/aa380543(v=VS.85).aspx

Exchange Web Services, try to use ExchangeImpersonationType

I am trying to use EWS, first time trying to use the ExchangeServiceBinding. The code I am using is below:
_service = new ExchangeServiceBinding();
//_service.Credentials = new NetworkCredential(userName, userPassword, this.Domain);
_service.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
_service.Url = this.ServiceURL;
ExchangeImpersonationType ei = new ExchangeImpersonationType();
ConnectingSIDType sid = new ConnectingSIDType();
sid.PrimarySmtpAddress = this.ExchangeAccount;
ei.ConnectingSID = sid;
_service.ExchangeImpersonation = ei;
The application is an aspnet 3.5 trying to create a task using EWS. I have tried to use impersonation because I will not know the logon user's domain password, so I thought impersonation would be the best fit. Any thoughts on how I can utilize impersonation? Am I setting this correctly, I get an error while trying to run my application. I also tried without impersonation just to try to see if I can create a task, no luck either. Any help would be appreciated. Thanks.
Without broader context of your code snip, I can't tell for sure what's wrong, but here are a few things you might find useful...
You mention you had trouble connecting without impersonation.
I'm assuming you are using Exchange Server 2007 SP1, yes?
Do you have a mailbox for which you do know the username and password? If so, consider trying to connect to that mailbox, just to see if you can send an email or query for inbox count. That will help verify your connection at least.
As to exchange impersonation,
have the permissions been set on the Client Access Server (CAS) to enable impersonation?
Have the permissions been set on either the mailbox or mailbox database (containing the mailbox you are attempting to access)?
are you in a cross-forest scenario that requires additional trust relationships?
If not, that might explain why you cannot connect.
Some links you might find useful
Configuring (http://msdn.microsoft.com/en-us/library/bb204095.aspx)
Using Exchange impersonation (http://msdn.microsoft.com/en-us/library/bb204088.aspx)
Access multiple resource mailboxes (http://msexchangeteam.com/archive/2007/12/13/447731.aspx)