Reputation: 2896
int rtn = BIO_do_handshake(sbio);
printf("\n.. returns %d .. \n",rtn);
if( rtn <= 0)
{
fprintf(stderr, "Error in SSL handshake\n");
ERR_print_errors_fp(stderr);
}
I write this code from here
but the BIO_do_handshake() always return 0 why ?
the certificates are fine!!
any ideas ??
Please help me..
thanks
Upvotes: 6
Views: 2162
Reputation: 102386
We really need to see more code, but here's how I use BIO_new_ssl_connect
and friends. Did you call BIO_new_ssl_connect
? Did you call BIO_set_conn_hostname
? Did you call BIO_do_connconnect
?
The code below connects to www.random.org and prints the result to the screen. There sre some other checks you must do, but they are outside the scope of hot to use BIO_new_ssl_connect
and friends.
Also, the bio read loop is not robust, so don't use it in production code (the sample serves another purpose). Finally, you could use ERR_print_errors_fp
for printing errors. In production, I do other things so ERR_print_errors_fp
is usually not enough (hence the reason for a simple fprintf
).
long ret = 1;
unsigned long ssl_err = 0;
SSL_CTX* ctx = NULL;
BIO *bio = NULL, *out = NULL;
SSL *ssl = NULL;
/* Cipher suites, https://www.openssl.org/docs/apps/ciphers.html */
const char* const PREFERRED_CIPHERS = "kEECDH:kEDH:kRSA:AESGCM:AES256:AES128:3DES:SHA256:SHA84:SHA1:!aNULL:!eNULL:!EXP:!LOW:!MEDIUM!MD5";
do {
/* https://www.openssl.org/docs/ssl/SSL_library_init.html */
ret = SSL_library_init();
ssl_err = ERR_get_error();
ASSERT(ret == 1);
if(!(ret == 1))
{
fprintf(stderr, "SSL_library_init: %lu (0x%lx)\n", ssl_err , ssl_err);
break; /* failed */
}
/* https://www.openssl.org/docs/ssl/SSL_CTX_new.html */
const SSL_METHOD* method = SSLv23_method();
ssl_err = ERR_get_error();
ASSERT(NULL != method);
if(!(NULL != method))
{
fprintf(stderr, "SSLv23_method failed: %lu (0x%lx)\n", ssl_err , ssl_err);
break; /* failed */
}
/* http://www.openssl.org/docs/ssl/ctx_new.html */
ctx = SSL_CTX_new(method);
ssl_err = ERR_get_error();
ASSERT(ctx != NULL);
if(!(ctx != NULL))
{
fprintf(stderr, "SSL_CTX_new failed: %lu (0x%lx)\n", ssl_err , ssl_err);
break; /* failed */
}
/* https://www.openssl.org/docs/ssl/ctx_set_verify.html */
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, bio_pin_pubkey_callback);
/* Cannot fail ??? */
/* https://www.openssl.org/docs/ssl/ctx_set_verify.html */
SSL_CTX_set_verify_depth(ctx, 5);
/* Cannot fail ??? */
/* Remove most egregious. Because SSLv2 and SSLv3 have been removed, */
/* a TLSv1.0 handshake is used. The client accepts TLSv1.0 and above. */
const long flags = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
long old_opts = SSL_CTX_set_options(ctx, flags);
UNUSED(old_opts);
/* http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html */
ret = SSL_CTX_load_verify_locations(ctx, "random-org-chain.pem", NULL);
ssl_err = ERR_get_error();
ASSERT(1 == ret);
if(!(1 == ret))
{
/* Non-fatal, but something else will probably break later */
fprintf(stderr, "SSL_CTX_load_verify_locations failed: %lu (0x%lx)\n", ssl_err , ssl_err);
/* break; */
}
/* https://www.openssl.org/docs/crypto/BIO_f_ssl.html */
bio = BIO_new_ssl_connect(ctx);
ssl_err = ERR_get_error();
ASSERT(bio != NULL);
if(!(bio != NULL))
{
fprintf(stderr, "BIO_new_ssl_connect failed: %lu (0x%lx)\n", ssl_err , ssl_err);
break; /* failed */
}
/* https://www.openssl.org/docs/crypto/BIO_f_ssl.html */
/* This copies an internal pointer. No need to free. */
BIO_get_ssl(bio, &ssl);
ssl_err = ERR_get_error();
ASSERT(ssl != NULL);
if(!(ssl != NULL))
{
fprintf(stderr, "BIO_get_ssl failed: %lu (0x%lx)\n", ssl_err , ssl_err);
break; /* failed */
}
/* https://www.openssl.org/docs/ssl/ssl.html#DEALING_WITH_PROTOCOL_CONTEXTS */
/* https://www.openssl.org/docs/ssl/SSL_CTX_set_cipher_list.html */
ret = SSL_set_cipher_list(ssl, PREFERRED_CIPHERS);
ssl_err = ERR_get_error();
ASSERT(1 == ret);
if(!(1 == ret))
{
fprintf(stderr, "SSL_set_cipher_list failed: %lu (0x%lx)\n", ssl_err , ssl_err);
break;
}
/* https://www.openssl.org/docs/crypto/BIO_s_connect.html */
ret = BIO_set_conn_hostname(bio, HOST_NAME ":" HOST_PORT);
ssl_err = ERR_get_error();
ASSERT(1 == ret);
if(!(1 == ret))
{
fprintf(stderr, "BIO_set_conn_hostname failed: %lu (0x%lx)\n", ssl_err , ssl_err);
break;
}
/* https://www.openssl.org/docs/crypto/BIO_s_file.html */
out = BIO_new_fp(stdout, BIO_NOCLOSE);
ssl_err = ERR_get_error();
ASSERT(NULL != out);
if(!(NULL != out))
{
fprintf(stderr, "BIO_new_fp failed: %lu (0x%lx)\n", ssl_err , ssl_err);
break;
}
/* https://www.openssl.org/docs/crypto/BIO_s_connect.html */
ret = BIO_do_connect(bio);
ssl_err = ERR_get_error();
ASSERT(1 == ret);
if(!(1 == ret))
{
fprintf(stderr, "BIO_do_connect failed: %lu (0x%lx)\n", ssl_err , ssl_err);
break;
}
/* https://www.openssl.org/docs/crypto/BIO_f_ssl.html */
ret = BIO_do_handshake(bio);
ssl_err = ERR_get_error();
ASSERT(1 == ret);
if(!(1 == ret))
{
fprintf(stderr, "BIO_do_handshake failed: %lu (0x%lx)\n", ssl_err , ssl_err);
break;
}
/* Could examine ssl here to get connection info */
BIO_write(out, "\n", 1);
BIO_puts(bio, "GET / HTTP/1.0\r\nConnection: close\r\n\r\n");
BIO_READ_TOP:
{
char buff[1536]; int len = 0;
/* https://www.openssl.org/docs/crypto/BIO_read.html */
len = BIO_read(bio, buff, sizeof(buff));
if(len > 0)
BIO_write(out, buff, len);
if(BIO_should_retry(bio)) goto BIO_READ_TOP;
}
func_ret = SUCCESS;
} while (0);
if(out)
BIO_free(out);
if(bio != NULL)
BIO_free_all(bio);
if(NULL != ctx)
SSL_CTX_free(ctx);
Upvotes: 2