I am new to HTTPS/SSL.
I need to write a HTTPS client which will reject all the connection by saying unknown CA . As I understand (through wireshark capture) during SSL connection, first client will send the 'client hello' message. In reply to this server will send message with three record - 'server hello', certificate, 'server hello done'.
What I am trying to achieve here is when the server will send certificate, client should always reject it.
I am trying to achieve it with following code but no luck.
How can I get LWP to validate SSL server certificates?
It's ok if solution is in some other language.
It should be enough to do the connection with no (or dummy) CA certificates known to the client. Have you tried setting SSL_ca_path and SSL_ca_file to dummy values?
Edit:
If any language goes, why not try openssls s_client?
openssl s_client -connect www.stackoverflow.com:443
Related
I'm reading the spec and trying to understand exactly when 421 might be returned. An example is given but I don't completely understand it.
Background
The spec establishes two conditions that allow for connection reuse:
For TCP connections without TLS, this depends on the host having resolved to the same IP address.
and
For https resources, connection reuse additionally depends on having a
certificate that is valid for the host in the URI.
If the certificate used in the connection has multiple subjectAltName or any of the subjectAltName is a wildcard, then the connection can be reused for any request that has a hostname that is in the list of subjectAltNames or matches any of the wildcards.
Specific Example In the spec
In some deployments, reusing a connection for multiple origins can
result in requests being directed to the wrong origin server. For
example, TLS termination might be performed by a middlebox that uses
the TLS Server Name Indication (SNI) [TLS-EXT] extension to select an
origin server. This means that it is possible for clients to send
confidential information to servers that might not be the intended
target for the request, even though the server is otherwise
authoritative.
Please explain where my understanding of this example is wrong:
An https connection is established to a middlebox with a request that has domain x.com. The middlebox has IP address 1.2.3.4 and x.com resolves to that address. Using SNI, the TLS handshake has x.com and the middlebox returns a certificate valid for that domain. All messages on this connection go from the client to the middlebox or from middlebox to client. Applicaiton level messages from client to middlebox are forwarded by middlebox to an origin on a different connection. Messages from origin to middlebox are forwarded to the client. If the connection is to be reused, meeting the two conditions discussed above is not enough. Specifically, for a request with domain y.com: if y.com resolves to 1.2.3.4 and the middlebox has a certificate valid for y.com, there can still be a problem. Because the original connection did its TLS handshake using x.com and because handshakes are only done at the beginning of new connections, there is no way establishing an https connection that would get the certificate for y.com. So the client incorrectly sends a request on the same connection to y.com. The middlebox rejects the request because the certificate associated with the connection is valid for x.com - not y.com. (The x.com certificate is only valid for x.com and the y.com certificate is only valid for y.com).
None of your examples will trigger a 421 as far as I can see.
Yes you are correct that a connection needs both the IP address and the SAN field in the certificate to be valid - without those a connection should not be reused.
So what would trigger a 421? As far as I can tell it will be mostly due to different SSL/TLS setups.
For example:
Assume website A (siteA.example.com) and website B (www.example.com) are both on same IP address. Assume website A has a wildcard cert for *.example.com and website B has a specific one. Could be a few reasons for this: for example it serves an EV cert for the main website which can't be a wildcard cert.
So cert A covers website A and website B. As does the IP address. So if you are connected to website siteA.example.com, and then try to connect to www.example.com then technically, by HTTP/2 standards, you could reuse the connection. But we wouldn't want that to happen, as we want to use our EV cert. So the server should reject with a 421. Now in this example the webserver is able to distinguish the correct host and has a valid cert for that host so could, in theory, serve the correct content under the wildcard cert, instead of sending a 421 - but since that wildcard cert is not defined for that virtualhost it should not do this.
Other examples include if you have different ciphers set up on different hosts. For example site A has super lax HTTPS config, because it's not really secure content and they want to reach even legacy browsers, but site B has super secure config and only accepts the latest TLS version and strong ciphers. Here you obviously wouldn't want them to reuse the same connection details. See here for a real would example of this.
Also this is only an issue for certain browsers, depending on how they decide to connection share. This page shows how different each of them do this (at least at the time of this blog post not not aware of anything changing since then): https://daniel.haxx.se/blog/2016/08/18/http2-connection-coalescing/
Also note that some bugs will exist with this (for example: https://bugs.chromium.org/p/chromium/issues/detail?id=546991). Best advice is: if you do not want connection sharing to happen, have a different IP address and/or ensure no overlaps in certificates.
I would like to send an email from my Exchange email account via Mac Terminal. Is this possible, and if so, how would I go about doing so? I'm running OS X 10.10.5 and have my email set up on Microsoft Outlook 2011 for Mac. Thanks for the help!
Assuming you don't want to send email from your Outlook client for whatever reason, you'll need your user and pass in base64 handy to cut/past into the terminal. Go here for an example: How to test SMTP Auth using telnet
This comes with caveats. This is not SSL, so you're using SMTPS or StartTLS you'll need to do this all via OpenSSL s_client like this: Test SSL SMTP from command line
I've used these in the past and they work. If it doesn't work, you'll need to find out what SMTP connection strings are allowed. For clients I always ran SMTP Client Submission which listens on 587 and required STARTTLS prior to Auth. SMTPS on 465 was disabled...Lemme know if this works.
-Chase
I am writing a soap request over SSL using Savon and HTTPi, a Ruby soap client and an interface for Ruby HTTP clients, respectively. Here's the code:
client = Savon::Client.new(original_class.constantize.wsdl_url)
client.http.auth.ssl.cert_key_file = "path_to_the_key"
client.http.auth.ssl.cert_key_password = 'secret'
client.http.auth.ssl.cert_file = "path_to_the_certification"
client.http.auth.ssl.verify_mode = :none
#response = client.request :ins0, action do
soap.body = encoded_body
end
That's the only way I get this to work. But, I know that there is three others verify modes, which are:
:peer (SSL_VERIFY_PEER)
:fail_if_no_peer_cert (SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
:client_once (SSL_VERIFY_CLIENT_ONCE)
If I change the verify mode to any other of the above, I get this error:
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
Then comes my questions (among others I have):
Am I doing wrong if I keep the verify mode to :none? Is there any lack of security?
What does the error really mean? That my code is wrong or that my certificate (which is self-assigned --- I am in development environment) is not good?
I read the OpenSSL documentation about verify modes:
http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
About SSL_VERIFY_NONE, on Client Mode, says:
The result of the certificate verification process can be checked
after the TLS/SSL handshake using the SSL_get_verify_result(3)
function. The handshake will be continued regardless of the
verification result.
Should I be worried about it? Should I see verify mode :none as a dangerous thing?
I am asking that because since I can't make it work with the others verify modes, I would like to release the soap request over SSL feature the way it is working now. But I surely wouldn't do it if that could be dangerous.
It is NOT safe to set verify mode to :none (SSL_VERIFY_NONE). This opens up the code to being susceptible to man-in-the-middle attacks. With :none, there will be not server authentication. If an attacker intercepts the connection from my client, my client will not detect the difference and will give any sensitive data communicated through this socket to the attacker.
The mode flags :fail_if_not_peer_cert and :client_once are only for a server; meaning nothing to the client, it ignores them.
For client purpose, :peer (SSL_VERIFY_PEER) is the only one the matters. In order to use :peer, I need to have the root certificate used by the certificate in the client trustedstore.
A big thanks to Dave Thompson from OpenSSL User Support Mailing List. After I joined this list, I finally got help.
My Server is configured to accept both SSLv3 and TLS1.0 protocols. But a few clients are sending below handshake parameters and after the server hello, the client drops the connection and sends 'handshare failure(40) alert, not sure if it's the client fault or server.
Here's the initial client hello packet:
Secure Socket Layer
SSLv3 Record Layer: Client Hello
Content Type: Handshake (22)
Version: SSL 3.0 (0x0300) <-----------------
Length: 103
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 78
Version: TLS 1.0 (0x0301) <-------------
Random
Session ID Length: 0
Cipher Suites Length: 18
Cipher Suites (9 suites)
The Record layer is SSL 3.0 but the inside handshake protocol is TLS 1.0. My question is, is this the right way of doing it i.e. using different versions for each layer? if it is what method is it? I can't find it anywhere, I looked through the RFC but can't find any reference. Also, how can I produce such requests?
EDIT: I'm not interested in troubleshooting and fixing the issue, I just want to know how can I send such packets? Any command? And what should I name this method?
i.e. I can use curl or openssl to either use ssl3 or tls1 but that would send same version in both record layer and handshake layer:
curl -v -ssl3 https://www.mywebserver.com
Above curl command would look on wireshark:
EDIT2: Is this even legal? I have been googling around and can't find any example. Is it violating any rfc standards?
Thanks
Yes, this is legal (at least it was clarified in recent TLS specifications).
You can look this up in rfc5246 (TLS 1.2) or in rfc6101 (SSL 3.0) or other rfc's concerning the SSL/TLS. The problem is with the initial version of the record protocol and with the handshake protocol:
rfc5246:
Earlier versions of the TLS specification were not fully clear on
what the record layer version number (TLSPlaintext.version) should
contain when sending ClientHello (i.e., before it is known which
version of the protocol will be employed). Thus, TLS servers
compliant with this specification MUST accept any value {03,XX} as
the record layer version number for ClientHello.
TLS clients that wish to negotiate with older servers MAY send any
value {03,XX} as the record layer version number. Typical values
would be {03,00}, the lowest version number supported by the client,
and the value of ClientHello.client_version.
Regarding the handshake protocol, the client will negotiate the highest version that it has implemented:
client_version: The version of the TLS protocol by which the client wishes to
communicate during this session. This SHOULD be the latest
(highest valued) version supported by the client
I just want to know how can I send such packets? Any command?
openssl s_client -connect www.myserver.com:443 -no_ssl2
should produce something similar to the trace you provided.
I'm going crazy with Apple push notification!
I've developed my app and test notifications following Ray Wanderlich tutorial and everything worked fine until I changed the file .pem with the distribution one and changed the connection string from gateway.sandbox.push-apple.com to gateway.push-apple.com.
Now if I try to send a message the server returns
Warning: stream_socket_client() [function.stream-socket-client]: unable to connect to ssl://gateway.push.apple.com:2195 (Connection timed out)
Failed to connect: 110 Connection timed out
The php file and the .pem file are on a TMDHosting: I try to ask them if port number 2195 is closed because googling I found that the error means port is closed.
Though, I can't understand if the error is linked to the certificate or to the server.
The strange things is that if I follow the procedure with the Terminal to test the .pem file , everything seems to work
CONNECTED(00000003)
depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc/OU=Internet Services/CN=gateway.push.apple.com
i:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
1 s:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048)
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEXTCC..........
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Cupertino/O=Apple Inc/OU=Internet Services/CN=gateway.push.apple.com
issuer=/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
---
No client certificate CA names sent
---
SSL handshake has read 2541 bytes and written 2039 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES256-SHA
Session-ID:
Session-ID-ctx:
Master-Key: CBA98981BB512ED2FDF0C003F4556FDDA564BEBBEFC6528C37D8E0336BC141AEC6D7E014568B334B8330FFFE266E8CB4
Key-Arg : None
Start Time: 1332945845
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
This lets me to think that it's not a .pem problem...
Am I wrong?
I've already read all the similar question here, and tried to change the port number from 2195 to 30, but nothing changes.
Hints?
EDIT: I found that and seems equal to my problem: TMDHosting told me
...you are located under a shared hosting environment and opening a
port for you will be not possible. However note that the address to
which you are making a connection on port 2195 is not associate with
our server. In other words you are trying to make a connection to a
remote server on port 2195. In order to make this connection to the
port specified above you should make sure that the port is opened for
incoming connections on the remote server and not on the server on
which your account with us relies.
Do I need a VPS?
EDIT2:
In the tutorial I followed I found
.. you will need a server that is connected to the internet. Push
notifications are always sent by a server. For development you can use
your Mac as the server (which we’ll do in this tutorial) but for
production use, you need at least something like a VPS (Virtual
Private Server). A cheap shared hosting account is not good enough.
You need to be able to run a background process on the server, install
an SSL certificate, and be able to make outgoing TLS connections on
certain ports. Most shared hosting providers do not let you do this,
although they might if you ask. However, I really recommend using a
VPS host such as Linode.
At last I think I do need a VPS. Can you confirm for sure?
But why if I send push notification with the sandbox server it works properly without VPS?
LAST UPDATE: (hope to help someone) it seems like there was a bug because the right thing is that I cannot send push notification not to the sandbox nor to the production server from my hosting (TMDHosting): my shared hosting has not the 2195 port open. Changed provider: everything works.
Miwi,
Thanks for this detailed writeup.
We are having a similar issue and it is driving us nuts.
When we test the cert, it appears to work, other than:
"verify error:num=20:unable to get local issuer certificate"
Regardless, we get a valid handshake with the command line test of openssl, just as you do.
We can get the sandbox/dev cert to work as well.
Can you let us know what provider you switched to just in case we need to make the switch?
Thanks.