Reputation: 14869
I am trying to use SSL without any certificate. I've read that it is possible so I am writing code without the calls to set it. According to the documentation it should be the right list of steps. Do you know if that is really possible?
I am using CENTOS 6.4.
When I run I always receive error
14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
Below is my code for the Server
int main() {
int res = -1;
SSL_library_init();
SSL_load_error_strings();
SSL_CTX *sslctx = SSL_CTX_new( SSLv23_server_method());
res = SSL_CTX_set_cipher_list(sslctx,"aNULL");
if(0 == res) {
cerr << "SSL_CTX_set_cipher_list" << endl;
std::exit(EXIT_FAILURE);
}
int res = -1;
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(kPort);
memset(&addr.sin_zero,0,8);
int sfd = socket(AF_INET,SOCK_STREAM, 0);
if(sfd == -1) {
cerr << "Socket Failed" << endl;
std::exit(EXIT_FAILURE);
}
res = bind(sfd, (const sockaddr*)&addr, sizeof(addr));
if(res == -1) {
cerr << "Bind Failed" << endl;
std::exit(EXIT_FAILURE);
}
res = listen(sfd,kBackLog);
if(res == -1) {
cerr << "Listen Failed" << endl;
std::exit(EXIT_FAILURE);
}
sockaddr_in client_addr;
socklen_t client_addr_len;
int cfd = accept(sfd, (sockaddr*)&client_addr, &client_addr_len);
if(cfd == -1) {
cerr << "Accept Failed" << endl;
std::exit(EXIT_FAILURE);
}
cout << "Client Connected" << endl;
// new SSL context.
SSL *cSSL = SSL_new(sslctx);
res = SSL_set_fd(cSSL, cfd);
cout << res << endl;
if(0 == res) {
cerr << "Error on SSL_set_fd" << endl;
close(sfd);
std::exit(EXIT_FAILURE);
}
res = SSL_set_cipher_list(cSSL, "aNULL");
if(0 == res) {
cout << "failure on SSL_set_cipher_list";
close(sfd);
std::exit(EXIT_FAILURE);
}
//Here is the SSL Accept portion. Now all reads and writes must use SSL
cout << "call to SSL_accept" << endl;
res = SSL_accept(cSSL);
switch(res)
{
case 0:
case -1: {
cout << "error on SSL_accept("<< res << ")" << endl;
std::exit(EXIT_FAILURE);
}
}
char buf[4];
res = SSL_read(cSSL, (char*)buf, 4);
switch(res) {
case 0:
case -1: {
cout << "error on SSL_read("<< res << ")" << endl;
std::exit(EXIT_FAILURE);
}
}
cout << buf << endl;
}
And below the one for the client
int main() {
int res = -1;
SSL_library_init();
SSL_load_error_strings();
//OpenSSL_add_all_algorithms(); I didn't find this in man pages.
SSL_CTX *sslctx = SSL_CTX_new( SSLv23_client_method());
res = SSL_CTX_set_cipher_list(sslctx,"aNULL");
if(0 == res) {
cerr << "SSL_CTX_set_cipher_list" << endl;
std::exit(EXIT_FAILURE);
}
int res = -1;
int sfd = socket(AF_INET, SOCK_STREAM, 0);
CHECK(sfd,"socket");
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(kPort);
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // #include <arpa/inet.h>
res = connect(sfd, (const sockaddr*)&addr, sizeof(addr));
CHECK(res, "connect");
if(-1 == res) {
cerr << "Error on Connect" << endl;
close(sfd);
std::exit(EXIT_FAILURE);
}
SSL *cSSL = SSL_new(sslctx);
if(NULL == cSSL) {
cerr << "Error on SSL_new" << endl;
close(sfd);
std::exit(EXIT_FAILURE);
}
res = SSL_set_fd(cSSL, sfd);
if(0 == res) {
cerr << "Error on SSL_set_fd" << endl;
close(sfd);
std::exit(EXIT_FAILURE);
}
res = SSL_set_cipher_list(cSSL, "aNULL");
if(0 == res) {
cout << "failure on SSL_set_cipher_list";
close(sfd);
std::exit(EXIT_FAILURE);
}
cout << "calling SSL connect" << endl;
res = SSL_connect(cSSL);
switch(res) {
case 0:
case -1: {
cerr << "Error on SSL_connect("<< res << ")" << endl;
print_ssl_error(cSSL, res);
close(sfd);
std::exit(EXIT_FAILURE);
}
}
cout << "SSL write" << endl;
char buf[4] = {'a','b','c','\n'};
SSL_write(cSSL, buf, 4);
sleep(10);
close(sfd);
}
Upvotes: 1
Views: 1959
Reputation: 102245
I am trying to use SSL without any certificate.
You need to use Anonymous Diffie-Hellman (ADH) or Anonymous Elliptic Curve Diffie Hellman (AECDH). When using anonymous schemes, the server does not send its certificate.
Call SSL_set_cipher_list
before SSL_connect
. According to ciphers(1)
, the cipher you want is aNULL
. aNULL
includes both ADH
and AECDH
.
Do you know if that is really possible?
Yes, its possible. But its a bad idea to use anonymous cipher suites because they are prone to active attacks. That is, they can be Man-in-the-Middle'd.
Also, most clients and servers are configured to reject anonymous cipher suites via "!aNULL"
cipher suite list. So you might find in practice that you can't really connect to anything.
Upvotes: 1