Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C SSL\u接受失败,SSL\u获取\u错误返回1_C_Linux_Security_Ssl_Openssl - Fatal编程技术网

C SSL\u接受失败,SSL\u获取\u错误返回1

C SSL\u接受失败,SSL\u获取\u错误返回1,c,linux,security,ssl,openssl,C,Linux,Security,Ssl,Openssl,我是SSL套接字编程的新手,我的第一个任务是让SSL服务器客户端工作并理解它 我已经获得了浮动在web上的服务器和客户端源代码,并根据我的openssl库(从源代码编译)对它们进行了编译 当我启动服务器时,我可以使用accept系统调用创建一个普通的clientfd,但是SSL\u accept失败 clientsocketfd=accept(serversocketfd,NULL,0); serverssl=SSL\u new(SSL\u server\u ctx); 如果(!serverss

我是SSL套接字编程的新手,我的第一个任务是让SSL服务器客户端工作并理解它

我已经获得了浮动在web上的服务器和客户端源代码,并根据我的openssl库(从源代码编译)对它们进行了编译

当我启动服务器时,我可以使用accept系统调用创建一个普通的clientfd,但是SSL\u accept失败

clientsocketfd=accept(serversocketfd,NULL,0);
serverssl=SSL\u new(SSL\u server\u ctx);
如果(!serverssl)
{
printf(“错误SSL_new\n”);
返回-1;
}
SSL\u set\u fd(serverssl、clientsocketfd);
如果((ret=SSL_接受(服务器SSL))!=1)
{
printf(“握手错误%d\n”,SSL\u get\u错误(serverssl,ret));
返回-1;
}
SSL\u accept
打印失败
握手错误1

为什么
SSL\u accept
失败并出现错误1


服务器源:

/*---------------------------------------------------------------------*/
/*---主-创建SSL套接字服务器---*/
/*---------------------------------------------------------------------*/
int main(int计数,字符*字符串[])
{SSL_CTX*CTX;
int服务器;
char*portnum;
如果(计数!=2)
{
printf(“用法:%s\n”,字符串[0]);
出口(0);
}
portnum=strings[1];
SSL_库_init();
ctx=InitServerCTX();/*初始化SSL*/
装载证书(ctx,“newreq.pem”、“newreq.pem”);/*装载证书*/
server=OpenListener(atoi(portnum));/*创建服务器套接字*/
而(1)
{struct sockaddru in addr;
int len=sizeof(addr);
SSL*SSL;
int client=accept(server,(struct sockaddr*)&addr,&len);/*像往常一样接受连接*/
printf(“连接:%s:%d\n”,
inet_ntoa(地址sin_地址),ntohs(地址sin_端口));
ssl=ssl_new(ctx);/*使用上下文获取新的ssl状态*/
SSL_set_fd(SSL,客户端);/*将连接套接字设置为SSL状态*/
Servlet(ssl);/*服务连接*/
}
关闭(服务器);/*关闭服务器套接字*/
SSL_CTX_free(CTX);/*发布上下文*/
}
/*---------------------------------------------------------------------*/
/*---初始化SSL服务器并创建上下文---*/
/*---------------------------------------------------------------------*/
SSL_CTX*InitServerCTX(无效)
{SSL_方法*方法;
SSL_CTX*CTX;
OpenSSL_add_all_algorithms();/*加载并注册所有密码等*/
SSL_load_error_strings();/*加载所有错误消息*/
method=SSLv3_server_method();/*创建新的服务器方法实例*/
ctx=SSL_ctx_new(方法);/*从方法创建新上下文*/
如果(ctx==NULL)
{
错误打印错误fp(stderr);
中止();
}
返回ctx;
}
OpenSSL版本和编译选项如下:

/usr/bin/openssl版本-a
OpenSSL 1.0.2g 2016年3月1日
构建日期:可复制构建,未指定日期
平台:debian-amd64
选项:bn(64,64)rc4(16x,int)des(idx,cisc,16,int)河豚(idx)
编译器:cc-I.-I-I../include-fPIC-DOPENSSL_PIC-DOPENSSL_线程-D_可重入
-DDSO_DLFCN-DHAVE_DLFCN_H-m64-DL_ENDIAN-g-O2-fstack强力保护剂
-Wformat-Werror=格式安全性-Wdate-time-D\u-FORTIFY\u-SOURCE=2-Wl,
-b符号函数-Wl,-z,relro-Wa,--noexecstack-Wall-DMD32_REG_T=int
-DOPENSSL_IA32_SSE2-DOPENSSL_BN_ASM_MONT
-DOPENSSL_BN_ASM_MONT5-DOPENSSL_BN_ASM_GF2m-DSHA1_ASM-DSHA256_ASM
-DSHA512_ASM-DMD5_ASM-DAES_ASM-DVPAES_ASM-DBSAES_ASM
-DWHIRLPOOL_ASM-DGHASH_ASM-DECP_NISTZ256_ASM
OPENSSLDIR:“/usr/lib/ssl”

显然,SSLv3在一些Linux发行版(如Ubuntu 16.04)发行的软件包中被禁用:

openssl(1.0.2g-1ubuntu1)xenial;紧急程度=中等

  • 与Debian合并,剩下的更改。
    • 在不更改ABI的情况下禁用SSLv3:
      • debian/patches/no-sslv3.patch:不使用 无ssl3方法选项
      • debian/规则:不要使用no-ssl3-method,不要碰撞soname
      • debian/patches/engines-path.patch:别撞到我
      • debian/patches/version-script.patch:别碰我
      • debian/patches/soname.patch:已删除
      • debian/lib*:别碰我
因此,您需要使用另一种方法:

method = SSLv3_server_method();
国家手册页:

如果基础BIO是非阻塞的,SSL_accept()也将返回 当基础BIO无法满足SSL_accept()的需要时 继续握手,通过返回值-1指示问题。 在本例中,调用SSL_get_error(),返回值为 SSL\u accept()将产生SSL\u ERROR\u WANT\u READ或SSL\u ERROR\u WANT\u WRITE。 然后,呼叫过程必须在采取适当措施后重复呼叫 满足SSL_accept()需要的操作

我相信这意味着您的代码应该如下所示:

while (1)
{
    int acc = SSL_accept(ssl);
    if (acc == 0)
    {
        /* Hard error */
        exit(-1);
    }
    else if (acc == -1)
    {
        int err = SSL_get_error(ssl, ret);
        if (err == SSL_ERROR_WANT_READ)
        {
            /* Wait for data to be read */
        }
        else if (err == SSL_ERROR_WANT_WRITE)
        {
            /* Write data to continue */
        }
        else if (err == SSL_ERROR_SYSCALL || err == SSL_ERROR_SSL)
        {
            /* Hard error */
            exit(-1);
        }
        else if (err == SSL_ERROR_ZERO_RETURN)
        {
            /* Same as error */
            exit(-1);
        }
    }
    else
    {
        /* Continue */
        break;
    }
}

OpenSSL在
/apps/s_client.c
/apps/s_server.c

中有示例代码,请检查所有返回值。将注释放在代码右侧的注释样式有多有用?你能看到那些评论而不必玩滚动条吗?这样评论是个坏主意。你花了多少时间来创建这些漂亮的ASCII艺术盒注释?嗨,谢谢你,我使用了ubuntu 14.04,代码通过了方法创建的错误。我得到一份工作