我正在写一个https服务器。我创建了csr并使用我的根证书为测试域签名。当客户端连接时,SSL_accept()成功完成。我正在使用Non-Blocking IO。因此,我将首先使用Windows中的WSARecv()和IOCP异步地在char缓冲区中接收数据。从该char缓冲区,我将其写入BIO(BIO_write返回写入的字节数),并尝试使用SSL_read()解密该BIO的内容时,它返回ssl_error_ssl并将错误字符串作为错误:00000001:lib(0):func (0):原因(1)。
我在这里添加了代码的结构。
const SSL_METHOD *method;
SSL_CTX *ctx;
method = SSLv23_method(); /* create new server-method instance */
ctx = SSL_CTX_new(method); /* create new context from method */
if ( ctx == NULL )
{
printf("SSL Context Creation failed\n");
}
//create bio
BIO *bioIn = BIO_new(BIO_s_mem());
BIO *bioOut = BIO_new(BIO_s_mem());
/* get new SSL state with context */
SSL *clientSSL = SSL_new(ctx);
SSL_set_bio(clientSSL, bioIn , bioOut);
/* set connection socket to SSL state */
SSL_set_fd(clientSSL, mClientSocket);
/* serverNameCallBack will set ctx with certificate created for this domain */
SSL_CTX_set_tlsext_servername_callback(ctx, serverNameCallback);
/* accept ssl connection */
SSL_accept(clientSSL);
//Using WSARecv() here to get encrypted request to a buffer
//read from buffer
//bridge->getBuffer() returns the buffer with encrypted data received
int retBio = BIO_write(bioIn, bridge->getBuffer(), bytesTransfered);
char *buffer = (char *)malloc(sizeof(char) * 1024);
ZeroMemory(buffer, sizeof(buffer));
int retSSL = SSL_read(clientSSL, (void*)buffer, 1023);
retSSL == -1和SSL_get_error(clientSSL,retSSL)返回SSL_ERROR_SSL
答案 0 :(得分:2)
由于一些博客,我解决了这个问题。执行此操作的正确顺序是,在调用ssl_accept之后,应创建BIO并将其与ssl对象关联。如果你在ssl_accept之前关联它,那么你必须以不同的方式处理它。你应该在调用ssl_accept之前设置SSL_set_accept_state。
这是正确的代码序列
const SSL_METHOD *method;
SSL_CTX *ctx;
method = SSLv23_method(); /* create new server-method instance */
ctx = SSL_CTX_new(method); /* create new context from method */
if ( ctx == NULL )
{
printf("SSL Context Creation failed\n");
}
/* get new SSL state with context */
SSL *clientSSL = SSL_new(ctx);
/* set connection socket to SSL state */
SSL_set_fd(clientSSL, mClientSocket);
/* serverNameCallBack will set ctx with certificate created for this domain */
SSL_CTX_set_tlsext_servername_callback(ctx, serverNameCallback);
/* set ssl handle to be used as a server */
SSL_set_accept_state(clientSSL);
/* accept ssl connection */
SSL_accept(clientSSL);
//Using WSARecv() here to get encrypted request to a buffer
//create bio
BIO *bioIn = BIO_new(BIO_s_mem());
BIO *bioOut = BIO_new(BIO_s_mem());
SSL_set_bio(clientSSL, bioIn , bioOut);
//read from buffer
//bridge->getBuffer() returns the buffer with encrypted data received
int retBio = BIO_write(bioIn, bridge->getBuffer(), bytesTransfered);
char *buffer = (char *)malloc(sizeof(char) * 1024);
ZeroMemory(buffer, sizeof(buffer));
int retSSL = SSL_read(clientSSL, (void*)buffer, 1023);