I have downloaded openssl from source, and I've built it like that (on linux using mingw32):
wget https://www.openssl.org/source/openssl-1.1.1q.tar.gz
tar -xvf openssl-1.1.1q.tar.gz
cd ./openssl-1.1.1q
./Configure enable-tls1_3 enable-tls1_2 no-async --cross-compile-prefix=i686-w64-mingw32- mingw
make -j 16
make install
And I try to complile the following file main.c
:
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/applink.c>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
//#pragma comment (lib, "Mswsock.lib")
//#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 512
#define FAIL -1
#define WIN32_LEAN_AND_MEAN
SOCKET OpenConnection(char* hostname, int port)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo* result = NULL;
struct addrinfo* ptr = NULL;
struct addrinfo hints;
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo("google.com", "449", &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
ptr = result;
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
}
return ConnectSocket;
}
SSL_CTX* InitCTX(void)
{
OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */
SSL_load_error_strings(); /* Bring in and register error messages */
const SSL_METHOD* method = TLSv1_2_client_method(); /* Create new client-method instance */
SSL_CTX* ctx = SSL_CTX_new(method); /* Create new context */
if (ctx == NULL)
{
ERR_print_errors_fp(stderr);
abort();
}
return ctx;
}
void ShowCerts(SSL* ssl)
{
X509* cert;
char* line;
cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
if (cert != NULL)
{
printf("Server certificates:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("Subject: %s\n", line);
//free(line); /* free the malloc'ed string */
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("Issuer: %s\n", line);
//free(line); /* free the malloc'ed string */
X509_free(cert); /* free the malloc'ed certificate copy */
}
else
printf("Info: No client certificates configured.\n");
}
int main(int argc, char* argv[])
{
char buf[1024];
char acClientRequest[1024] = { 0 };
SSL_library_init();
char* hostname = "google.com";
char* portnum = "449";
SSL_CTX* ctx = InitCTX();
int server = OpenConnection(hostname, atoi(portnum));
SSL* ssl = SSL_new(ctx); /* create new SSL connection state */
SSL_set_fd(ssl, server); /* attach the socket descriptor */
if (SSL_connect(ssl) == FAIL) {
ERR_print_errors_fp(stderr);
} else {
const char* cpRequestMessage = "";
printf("\n\nConnected with %s encryption\n", SSL_get_cipher(ssl));
/* get any certs */
ShowCerts(ssl);
/* encrypt & send message */
SSL_write(ssl, acClientRequest, strlen(acClientRequest));
/* get reply & decrypt */
int bytes = SSL_read(ssl, buf, sizeof(buf));
buf[bytes] = 0;
printf("Received: \"%s\"\n", buf);
/* release connection state */
SSL_free(ssl);
}
/* close socket */
closesocket(server);
/* release context */
SSL_CTX_free(ctx);
return 0;
}
Once I try to build it like this:
LANG=C i686-w64-mingw32-gcc main.c -lws2_32 -I"openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include" -fpermissive -o main.exe
I get the following errors:
LANG=C i686-w64-mingw32-gcc main.c -lws2_32 -I"openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include" -fpermissive -o main.exe
cc1: warning: command line option '-fpermissive' is valid for C++/ObjC++ but not for C
main.c: In function 'InitCTX':
main.c:77:5: warning: 'TLSv1_2_client_method' is deprecated [-Wdeprecated-declarations]
const SSL_METHOD* method = TLSv1_2_client_method(); /* Create new client-method instance */
^~~~~
In file included from openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include/openssl/e_os2.h:13:0,
from openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include/openssl/ssl.h:15,
from main.c:8:
openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include/openssl/ssl.h:1901:45: note: declared here
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_client_method(void))
^
openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include/openssl/opensslconf.h:124:37: note: in definition of macro 'DECLARE_DEPRECATED'
# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated));
^
openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include/openssl/ssl.h:1901:1: note: in expansion of macro 'DEPRECATEDIN_1_1_0'
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_client_method(void))
^
/tmp/ccvIModv.o:main.c:(.text+0x376): undefined reference to `OPENSSL_init_crypto'
/tmp/ccvIModv.o:main.c:(.text+0x392): undefined reference to `OPENSSL_init_ssl'
/tmp/ccvIModv.o:main.c:(.text+0x397): undefined reference to `TLSv1_2_client_method'
/tmp/ccvIModv.o:main.c:(.text+0x3a5): undefined reference to `SSL_CTX_new'
/tmp/ccvIModv.o:main.c:(.text+0x3be): undefined reference to `ERR_print_errors_fp'
/tmp/ccvIModv.o:main.c:(.text+0x3d9): undefined reference to `SSL_get_peer_certificate'
/tmp/ccvIModv.o:main.c:(.text+0x3fd): undefined reference to `X509_get_subject_name'
/tmp/ccvIModv.o:main.c:(.text+0x415): undefined reference to `X509_NAME_oneline'
/tmp/ccvIModv.o:main.c:(.text+0x436): undefined reference to `X509_get_issuer_name'
/tmp/ccvIModv.o:main.c:(.text+0x44e): undefined reference to `X509_NAME_oneline'
/tmp/ccvIModv.o:main.c:(.text+0x46f): undefined reference to `X509_free'
/tmp/ccvIModv.o:main.c:(.text+0x4ca): undefined reference to `OPENSSL_init_ssl'
/tmp/ccvIModv.o:main.c:(.text+0x508): undefined reference to `SSL_new'
/tmp/ccvIModv.o:main.c:(.text+0x51d): undefined reference to `SSL_set_fd'
/tmp/ccvIModv.o:main.c:(.text+0x528): undefined reference to `SSL_connect'
/tmp/ccvIModv.o:main.c:(.text+0x53d): undefined reference to `ERR_print_errors_fp'
/tmp/ccvIModv.o:main.c:(.text+0x554): undefined reference to `SSL_get_current_cipher'
/tmp/ccvIModv.o:main.c:(.text+0x55c): undefined reference to `SSL_CIPHER_get_name'
/tmp/ccvIModv.o:main.c:(.text+0x59e): undefined reference to `SSL_write'
/tmp/ccvIModv.o:main.c:(.text+0x5bb): undefined reference to `SSL_read'
/tmp/ccvIModv.o:main.c:(.text+0x5ed): undefined reference to `SSL_free'
/tmp/ccvIModv.o:main.c:(.text+0x608): undefined reference to `SSL_CTX_free'
If I try to use -lcrypto
and -lssl
flags:
LANG=C i686-w64-mingw32-gcc main.c -lws2_32 -lcrypto -lssl -I"openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include" -fpermissive -o main.exe
I get the following response:
cc1: warning: command line option '-fpermissive' is valid for C++/ObjC++ but not for C
main.c: In function 'InitCTX':
main.c:77:5: warning: 'TLSv1_2_client_method' is deprecated [-Wdeprecated-declarations]
const SSL_METHOD* method = TLSv1_2_client_method(); /* Create new client-method instance */
^~~~~
In file included from openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include/openssl/e_os2.h:13:0,
from openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include/openssl/ssl.h:15,
from main.c:8:
openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include/openssl/ssl.h:1901:45: note: declared here
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_client_method(void))
^
openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include/openssl/opensslconf.h:124:37: note: in definition of macro 'DECLARE_DEPRECATED'
# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated));
^
openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include/openssl/ssl.h:1901:1: note: in expansion of macro 'DEPRECATEDIN_1_1_0'
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_client_method(void))
^
/usr/bin/i686-w64-mingw32-ld: cannot find -lctypto
/usr/bin/i686-w64-mingw32-ld: cannot find -lssl
collect2: error: ld returned 1 exit status
The question is why these are undefined:
/tmp/ccvIModv.o:main.c:(.text+0x376): undefined reference to `OPENSSL_init_crypto'
/tmp/ccvIModv.o:main.c:(.text+0x392): undefined reference to `OPENSSL_init_ssl'
/tmp/ccvIModv.o:main.c:(.text+0x397): undefined reference to `TLSv1_2_client_method'
/tmp/ccvIModv.o:main.c:(.text+0x3a5): undefined reference to `SSL_CTX_new'
/tmp/ccvIModv.o:main.c:(.text+0x3be): undefined reference to `ERR_print_errors_fp'
/tmp/ccvIModv.o:main.c:(.text+0x3d9): undefined reference to `SSL_get_peer_certificate'
/tmp/ccvIModv.o:main.c:(.text+0x3fd): undefined reference to `X509_get_subject_name'
/tmp/ccvIModv.o:main.c:(.text+0x415): undefined reference to `X509_NAME_oneline'
/tmp/ccvIModv.o:main.c:(.text+0x436): undefined reference to `X509_get_issuer_name'
/tmp/ccvIModv.o:main.c:(.text+0x44e): undefined reference to `X509_NAME_oneline'
/tmp/ccvIModv.o:main.c:(.text+0x46f): undefined reference to `X509_free'
/tmp/ccvIModv.o:main.c:(.text+0x4ca): undefined reference to `OPENSSL_init_ssl'
/tmp/ccvIModv.o:main.c:(.text+0x508): undefined reference to `SSL_new'
/tmp/ccvIModv.o:main.c:(.text+0x51d): undefined reference to `SSL_set_fd'
/tmp/ccvIModv.o:main.c:(.text+0x528): undefined reference to `SSL_connect'
/tmp/ccvIModv.o:main.c:(.text+0x53d): undefined reference to `ERR_print_errors_fp'
/tmp/ccvIModv.o:main.c:(.text+0x554): undefined reference to `SSL_get_current_cipher'
/tmp/ccvIModv.o:main.c:(.text+0x55c): undefined reference to `SSL_CIPHER_get_name'
/tmp/ccvIModv.o:main.c:(.text+0x59e): undefined reference to `SSL_write'
/tmp/ccvIModv.o:main.c:(.text+0x5bb): undefined reference to `SSL_read'
/tmp/ccvIModv.o:main.c:(.text+0x5ed): undefined reference to `SSL_free'
/tmp/ccvIModv.o:main.c:(.text+0x608): undefined reference to `SSL_CTX_free'
And how I can fix them?
As @Gerhardh has pointed out I must compile my application with:
LANG=C i686-w64-mingw32-gcc main.c -lws2_32 -I"openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/include" -L"openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/lib" -fpermissive -o main.exe -lcrypto -lssl
At openssl-1.1.1q/C:/Program Files (x86)/OpenSSL/
there are 2 folder that need to keep an eye-notice:
includes
that contain the nessesary headerslib
that contain the nessesary librariesUsing -I
param provide the full path towards includes
dir and using -L
param provide the path towards the lib
dir.