Closed delasy closed 1 year ago
Also I tried pretty much every TLS client method with SSL_CTX_new
, makes no difference
ssl_write(ssl, request);
should be
ssl_write(ssl, data);
TLS_client_method() would be the right method to use. And cdn.thelang.io requires TLSv1.2 or above to connect.
works: openssl s_client -state -debug -connect cdn.thelang.io:443 openssl s_client -tls1_2 -state -debug -connect cdn.thelang.io:443
fails: openssl s_client -tls1 -state -debug -connect cdn.thelang.io:443
Thanks for fixing typo in code, I reformatted a lot of code to provide example, might have missed something.
As I wrote in comment above I tried TLS_client_method
, TLSv1_client_method
, TLSv1_1_client_method
, TLSv1_2_client_method
, even DTLSv1_2_client_method
.
No difference in results between all these methods.
I just did test with clean openssl-v3.0.7 on Ubuntu 22.04 amd64
With this code (fixed request problem mentioned above and used TLSv1_2_client_method
):
With this setup
sudo apt-get update
sudo apt-get install -y build-essential cmake clang
git clone --depth=1 --branch openssl-3.0.7 https://github.com/openssl/openssl.git
pushd openssl
CC=clang perl Configure no-tests --prefix="$PWD/build"
make
make install_sw
popd
vim main.c
clang main.c "$PWD/openssl/build/lib64/libssl.so.3" "$PWD/openssl/build/lib64/libcrypto.so.3" -w -o a.out -I"$PWD/openssl/build/include"
./a.out
And it still doesn't work
@t-j-h , on my machine (macOS 13.1 OpenSSL 1.1.1s) openssl s_client -state -debug -connect cdn.thelang.io:443
doesnt work
But command above works on Ubuntu 22.04 amd64 with OpenSSL 3.0.2, but the code still doesn't work it throws error:
400781E4A17F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:354:
You are missing a call to SSL_set_tlsext_host_name to let the underlying service know what the right backing host to connect to.
It is a subtle problem in that the backend server doesn't know what incoming service you are requesting but it has no way of actually telling you what you have done wrong at this level.
i.e. the server behind cdn.thelang.io isn't responding with a TLS handshake as it doesn't know you actually want to connect to cdn.thelang.io behind that front end server which is why it fails.
Your replacement code with it working is:
#include <stdbool.h>
#include <netdb.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define THE_EOL "\n"
bool lib_openssl_init = false;
int create_fd (char *hostname, char *port) {
struct addrinfo *addr = NULL;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(hostname, port, &hints, &addr) != 0) {
fprintf(stderr, "Error: failed to resolve hostname address" THE_EOL);
exit(EXIT_FAILURE);
}
int fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (fd == -1) {
fprintf(stderr, "Error: failed to create socket" THE_EOL);
exit(EXIT_FAILURE);
}
if (connect(fd, addr->ai_addr, addr->ai_addrlen) == -1) {
fprintf(stderr, "Error: failed to connect to socket" THE_EOL);
exit(EXIT_FAILURE);
}
freeaddrinfo(addr);
return fd;
}
SSL *create_ssl (int fd,char *hostname) {
if (!lib_openssl_init) {
SSL_library_init();
lib_openssl_init = true;
OPENSSL_add_all_algorithms_conf();
}
ERR_clear_error();
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
if (ctx == NULL) {
ERR_print_errors_fp(stderr);
fprintf(stderr, "Error: failed to create SSL context" THE_EOL);
exit(EXIT_FAILURE);
}
SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, fd);
SSL_set_tlsext_host_name(ssl,hostname);
if (SSL_connect(ssl) != 1) {
ERR_print_errors_fp(stderr);
fprintf(stderr, "Error: failed to connect to socket with SSL" THE_EOL);
exit(EXIT_FAILURE);
}
return ssl;
}
void ssl_write (SSL *ssl, char *data) {
if (SSL_write(ssl, data, strlen(data)) == -1) {
ERR_print_errors_fp(stderr);
fprintf(stderr, "Error: failed to write SSL data" THE_EOL);
exit(EXIT_FAILURE);
}
}
void request (char *data, char *hostname, char *port) {
int fd = create_fd(hostname, port);
SSL *ssl = create_ssl(fd,hostname);
ssl_write(ssl, data);
SSL_shutdown(ssl);
printf("Success" THE_EOL);
}
int main () {
request("GET / HTTP/1.1\r\n\r\n", "api.thelang.io", "443");
request("GET / HTTP/1.1\r\n\r\n", "cdn.thelang.io", "443");
}
@t-j-h Wow... that's definitely not something I would be able to solve myself, glad you are here to help. Thank you very much!
Hello, I'm using OpenSSL on daily basis and things were working good until I tried to download file from AWS S3 behind AWS CloudFront with Amazon issued certificate. I feel like I'm missing some piece of code that will make it working, not sure what it is though.
What I tried:
TLSv1.2_2021
Ways I tried to solve it:
brew install openssl
v1.1.1sapt install libssl-dev
no-dso no-shared no-tests no-threads
no-dso no-shared no-tests no-threads
On all platforms I tried, it shows error:
Also I tried:
https.get
works without any issuesurllib.request.urlopen
works without any issuesIn example below it successfully connects to
api.thelang.io
but fails forcdn.thelang.io
.api.thelang.io
is hosted on AWS EC2 with Let's Encrypt issued certificate, butSSL_connect
doesn't likecdn.thelang.io
for some reason.Code example I'm trying to make working: