C++ openssl: setting list of ciphers - c++

I have very basic C++ application that uses openssl library. Application sends request to server and the list of ciphersuites have to be the next:
4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53
Using SSL_set_cipher_list and SSL_set_ciphersuites I am setting list of ciphers. But when I use next list:
TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
I am getting 4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53-255. But I cannot understand where 255 in the end come from ? It shouldn't appear.

255 is a special cipher suit identifier. Reading RFCs when you deal with security is always useful.
RFC5746
3.3. Renegotiation Protection Request Signaling Cipher Suite Value
Both the SSLv3 and TLS 1.0/TLS 1.1 specifications require implementations to ignore data following the ClientHello (i.e., extensions) if they do not understand it. However, some SSLv3 and TLS 1.0 implementations incorrectly fail the handshake in such a case. This means that clients that offer the "renegotiation_info" extension may encounter handshake failures. In order to enhance compatibility with such servers, this document defines a second signaling mechanism via a special Signaling Cipher Suite Value (SCSV) "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", with code point {0x00, 0xFF}. This SCSV is not a true cipher suite (it does not correspond to any valid set of algorithms) and cannot be negotiated. Instead, it has the same semantics as an empty "renegotiation_info" extension, as described in the following sections. Because SSLv3 and TLS implementations reliably ignore unknown cipher suites, the SCSV may be safely sent to any server. The SCSV can also be included in the SSLv2 backward compatible CLIENT-HELLO (see Appendix E.2 of [RFC5246]).
Now you know the name TLS_EMPTY_RENEGOTIATION_INFO_SCSV and you can try to exclude it. But this may be not working.

Related

EPP Server SSL_Read hang after greeting

I have strange problems in ssl_read/ssl_write function with EPP server
After connected I read greeting message successfully.
bytes = SSL_read(ssl, buf, sizeof(buf)); // get reply & decrypt
buf[bytes] = 0;
ball+= bytes;
cc = getInt(buf);
printf("header: %x\n",cc);
printf("Received: \"%s\"\n",buf+4);
First 4 bytes are 00, 00, 09, EB and read 2539 bytes in greeting message.
After that, all operations like hello or logins are hand when SSL_read();
xml= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><eppxmlns=\"urn:ietf:params:xml:ns:epp-1.0\"><hello/></epp>";
char bb[1000] = {0};
makeChar(strlen(xml)+4, bb);
memcpy(bb+4, xml, strlen(xml)+4);
bytes = SSL_write(ssl,xml,strlen(xml)+4);
usleep(500000); //sleep 0.5 sec
memset(buf, 0, 1024);
printf("read starting.\n");
bytes = SSL_read(ssl, buf, 1024); //always hang here
buf[bytes]=0;
printf("%d : %s", bytes, buf);
I am confused. I read RFC documentations but I can not find answer.
in EPP documentation, they said "In order to verify the identity of the secure server you will need the ‘Verisign Class 3 Public Primary Certification Authority’ root certificate available free from www.verisign.com".
is it important?
is it important?
Yes, as outlined in RFC 5734 "Extensible Provisioning Protocol (EPP) Transport over TCP", the whole security of an EPP exchange is bound to 3 properties:
access list based on IP address
TLS communication and verification of certificates (mutually, which is why you - as registrar aka client in EPP communication - have often to send in advance the certificate you will use ot the registry)
the EPP credentials used at <login> command.
Failure to properly secure the connection can mean:
you as registrar sending confidential information (your own EPP login, various details on domains you sponsor or not, including <authInfo> values, etc.) to a third party not being the registry
and in reverse, someone mimicking you in the eyes of the registry hence doing operations on which you will have to get the burden of, including financially for all domains bought, and legally.
But even in general for all cases of TLS handshake, if you want to be sure to be connected, as client, to the server you think you are, you need to verify its certificate.
Besides trivial things (dates, etc.), the certificate:
should at least be signed by an AC you trust (your choice who you trust)
and/or is a specific certificate with specific fingerprint/serial and other characteristics (but you will have to maintain that when the other party changes its certificate)
and/or matches DNS TLSA records
In short, if you are new to both EPP and TLS and C/C++ (as you state yourself in your other question about Verisign certificate), I hugely recommend you do not try to do all of this by yourself at a so low level (for example you should never manipulate XML as you do above, it shouldn't be a string. Again, there are libraries to properly parse and generate XML documents). You should use an EPP library that leverage most of the things for you. Your registry may provide an "SDK" that you can use, you should ask it.
PS: your read is probably hanging because you are not sending the payload in the correct fashion (again, something an EPP library will do for you). You need to send the length, as 4 bytes (which you need to compute after converting your string to bytes using the UTF-8 encoding), and then the payload itself. I am not sure this is what your code does. Also your reading part is wrong: you should first read 4 bytes from server, this will give you the length (but do note they can theoretically arrive not necessarily in a single packet so one "ssl read" might not give all 4 of them, you need a loop), after which you know the length of the payload you will get which allows you to set up proper buffers, if needed, as well as detecting properly when you received everything.

TLS errors using Chilkat library to access Microsoft Graph APIs

I've been trying to use Chilkat library to play around and learn about using Microsoft Graph APIs but it seems I keeps getting TLS errors (connectFailReason 109) with even the simplest GETs and POSTs. This is what a typical log looks like:
ChilkatLog:
QuickGetSb:
DllDate: May 29 2021
ChilkatVersion: 9.5.0.87
UnlockPrefix: XXXXXXXXXXXXXXXX
Architecture: Little Endian; 32-bit
Language: C++ Builder / clang / 32-bit
VerboseLogging: 0
Component successfully unlocked using purchased unlock code.
url: https://graph.microsoft.com/v1.0/users
httpRequestStr:
a_quickReq:
quickHttpRequest:
httpVerb: GET
url: https://graph.microsoft.com/v1.0/users
openHttpConnection:
Opening connection directly to HTTP server.
httpHostname: graph.microsoft.com
httpPort: 443
tls: True
socket2Connect:
connect2:
connectImplicitSsl:
clientHandshake:
clientHandshake2:
ProcessHelloRetryRequest:
readHandshakeMessages:
WindowsError: An existing connection was forcibly closed by the remote host.
WindowsErrorCode: 0x2746
maxToReceive: 5
Failed to receive data on the TCP socket
Failed to read beginning of SSL/TLS record.
b: 0
dbSize: 0
nReadNBytes: 0
idleTimeoutMs: 60000
--readHandshakeMessages
--ProcessHelloRetryRequest
--clientHandshake2
--clientHandshake
Client handshake failed. (3)
--connectImplicitSsl
connectFailReason: 109
ConnectFailReason: 109
--connect2
--socket2Connect
connect: Socket fatal error.
--openHttpConnection
--quickHttpRequest
--a_quickReq
--httpRequestStr
Failed.
--QuickGetSb
--ChilkatLog
The library is not the very latest version but it isn't TOO old (about a year and a half - version 9.5.0.86). I didn't want to upgrade just yet because I have some "live" projects using this dev box (and this is just a "learning journey") so I was wondering if anyone can tell me whether the library version is the most likely issue or whether, perhaps, I'm missing some simple settings in the CkHttp object - the only thing I really do with it is set the auth token (which seems to have been retrieved correctly judging from the logs I output.
The actual API calls are pretty straightforward - mostly simple (slightly modified) examples from Chilkat website. But even the simplest http.quickGetStr("https://graph.microsoft.com/v1.0/me"); fails with a log similar to the above.
So, if anyone can suggest any properties to set to ckHttp to solve this issue (or confirm that library needs to be upgraded to access graph.microsoft.com - if, indeed, that is the case) - I would greatly appreaciate it.
Marko
This problem is already fixed. Contact support#chilkatsoft.com to get a pre-release build for v9.5.0.92.

Does SSL perform automatic renegotiation

I have a client server application written in c++ using SSL 1.0.1n for socket communication. I am trying to prevent renegotiation (it's a requirement). Nowhere in my code do I initiate a renegotiation.
I see openssl has a BIO_set_ssl_renegotiate_bytes and BIO_set_ssl_renegotiate_timeout that allows you to set up automatic renegotiation after a certain number of bytes are read or a timeout.
My question is if I don't set a value for either one of these, do they have a default value where SSL will still initiate a renegotiate automatically? I am having trouble figuring out what causes a renegotiation if not done in code.
I am trying to prevent renegotiation (it's a requirement)
Hopefully that requirement isn't in response to CVE-2009-3555. That was fixed in OpenSSL 0.9.8k in Nov 2009. TLSv1.1 and later protocols have never been subject to that vulnerability.
However, you can still set the SSL_OP_NO_RENEGOTIATION option via SSL_CTX_set_options() or SSL_set_options:
SSL_CTX_set_options
NAME
SSL_CTX_set_options, SSL_set_options, SSL_CTX_clear_options,
SSL_clear_options, SSL_CTX_get_options, SSL_get_options,
SSL_get_secure_renegotiation_support - manipulate SSL options
SYNOPSIS
#include <openssl/ssl.h>
long SSL_CTX_set_options(SSL_CTX *ctx, long options);
long SSL_set_options(SSL *ssl, long options);
long SSL_CTX_clear_options(SSL_CTX *ctx, long options);
long SSL_clear_options(SSL *ssl, long options);
long SSL_CTX_get_options(SSL_CTX *ctx);
long SSL_get_options(SSL *ssl);
long SSL_get_secure_renegotiation_support(SSL *ssl);
DESCRIPTION
SSL_CTX_set_options() adds the options set via bitmask in options to
ctx. Options already set before are not cleared!
SSL_set_options() adds the options set via bitmask in options to ssl.
Options already set before are not cleared!
SSL_CTX_clear_options() clears the options set via bitmask in options
to ctx.
SSL_clear_options() clears the options set via bitmask in options to
ssl.
SSL_CTX_get_options() returns the options set for ctx.
SSL_get_options() returns the options set for ssl.
SSL_get_secure_renegotiation_support() indicates whether the peer
supports secure renegotiation. Note, this is implemented via a macro.
NOTES
The behaviour of the SSL library can be changed by setting several
options. The options are coded as bitmasks and can be combined by a
bitwise or operation (|).
SSL_CTX_set_options() and SSL_set_options() affect the (external)
protocol behaviour of the SSL library. The (internal) behaviour of the
API can be changed by using the similar SSL_CTX_set_mode and
SSL_set_mode() functions.
During a handshake, the option settings of the SSL object are used.
When a new SSL object is created from a context using SSL_new(), the
current option setting is copied. Changes to ctx do not affect already
created SSL objects. SSL_clear() does not affect the settings.
...
The following modifying options are available:
...
SSL_OP_NO_RENEGOTIATION
Disable all renegotiation in TLSv1.2 and earlier. Do not send
HelloRequest messages, and ignore renegotiation requests via
ClientHello.
SECURE RENEGOTIATION
...
Note that the page has a "SECURE RENEGOTIAION" section. Read it.
Then, you really need to review your requirements. There's a good chance they're a decade out-of-date. By having you spend time and effort on problems that were fixed a decade ago, you're not spending time and effort fixing addressing current issues.

C++ Boost asio (OpenSSL) get cipher and TLS/SSL version of active connection

We have some SSL communication using Boost asio. Connecting and communication works fine, but now we'd like to show the actual TLS version and cipher used by the connection.
The Boost asio objects we use for the SSL connection are defined like this:
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
boost::shared_ptr<ssl_socket> m_psslsocket;
boost::asio::ssl::context* m_pcontext;
It looks like Boost asio doesn't really have an interface to query the connection for the cipher once it's set up.
I can get the OpenSSL SSL_CTX* pointer by calling this:
SSL_CTX* ctx = pContext->impl();
Or the OpenSSL SSL* by calling this:
m_psslsocket->native_handle()
But from the OpenSSL documentation I can't figure out how to get the used cipher and TLS version from this.
OpenSSL documentation says:
SSL_client_version() returns the numeric protocol version advertised by the client in the legacy_version field of the ClientHello when initiating the connection. Note that, for TLS, this value will never indicate a version greater than TLSv1.2 even if TLSv1.3 is subsequently negotiated. SSL_get_version() returns the name of the protocol used for the connection. SSL_version() returns the numeric protocol version used for the connection. They should only be called after the initial handshake has been completed. Prior to that the results returned from these functions may be unreliable.
So the answer is:
SSL_get_version(SSL*)

SSL Header returned by querycontextattributes is larger than expected using TLS1.2

I'm working to update a security library and I'm noticing some strange behavior when completing the SSL handshake and then calling querycontextattribute to obtain the header, maximum size, and trailer of the the messages. What I notice is when I have the grbitEnabledProtocols set to TLS 1_0 the handshake occurs as expected and returns a 5 byte header for the SSL packet as expected.
However, when I change the bit enabled protocol to either 0, and schannel selects tls 1.2, or if I set the bitenabled protocol to use TLS 1.2 when the function to query the message sizes is called, a 21 byte header is returned where 5 is expected.
Are there any additional calls that should be made when moving to TLS 1.2 as I have that would have not been necessary using TLS 1.0? Or, does returning the 21 byte header indicate an error in the processing of initializesecuritycontext that I'm not catching currently that should have been caught?