简体   繁体   English

使用C中的套接字传输和验证证书(openssl)

[英]Transmission and verification of certificate (openssl) with socket in c

I have to write these codes in c. 我必须在c中编写这些代码。 I have already generate the certificate of one terminate t1: t1.pem, which is generated by openssl. 我已经生成了一个终止t1的证书:t1.pem,它是由openssl生成的。 The communication between the terminates t1 and t2 has been established via socket in c. 终端t1和t2之间的通信已通过c中的套接字建立。

Now I want to send this certificate to another terminate t2.and I want t2 to receive the certificate, verify it and answer with an acceptance to t1. 现在我想将此证书发送到另一个终止t2。我希望t2接收该证书,对其进行验证并接受对t1的答复。 When t1 get this acceptance, it will the rest of stuffs.. 当t1获得此认可时,它将剩下的东西..

But I don't know how to do these things. 但是我不知道该怎么做。

For example, I transmit t1.pem as a string? 例如,我将t1.pem作为字符串传输? But in t2 side, how can I do to verify? 但是在t2端,我该如何验证? I know there are functions in openssl to do so, but I'm not so clear about it. 我知道openssl中有一些函数可以做到这一点,但是我不太清楚。 At last, normally, the acceptance should be like how? 最后,通常情况下,验收应该如何?

@.@...a lot of questions here.. sorry...if someone could give me some guide.. Thanks a lot in advance! @。@ ...这里有很多问题..对不起...如果有人可以给我一些指导..在此先多谢!

Here is a sample code which should help you: 这是一个示例代码,可以帮助您:

Server 服务器

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

int main()
{
int server_sockfd, client_sockfd;
int server_len, client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;

int result = 0;
//ssl initiation
SSL_library_init();
SSL_load_error_strings();
SSL_METHOD *meth = SSLv3_server_method();
SSL_CTX *ctx = SSL_CTX_new(meth);

SSL_CTX_use_certificate_file(ctx, "server_crt.pem", SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, "server_key.pem", SSL_FILETYPE_PEM);



//unnamed socket
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

//naming
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(9734);
server_len = sizeof(server_address);
result = bind(server_sockfd, (struct sockaddr *)&server_address, server_len);

if(result<0)
{
    printf("\nBinding Error");
}

//connection
listen(server_sockfd, 5);
while(1)
{
    char ch;
    printf("server waiting\n");

//accept connection

    client_len = sizeof(client_address);
    client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len);
    printf("\nConnected\n");
    SSL* ssl;
    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, client_sockfd);

//handshake

    SSL_accept(ssl);
    printf("\nHandshake Done\n");

//exchage message
    result = SSL_read(ssl, &ch, sizeof(ch));

    if(result<0)
    {
        printf("\nreading Error");
    }
    ++ch;
    result = SSL_write(ssl, &ch, sizeof(ch));


    if(result<0)
    {
        printf("\nwriting Error");
    }

    close(client_sockfd);
}
}

Client 客户

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

void check_cert(SSL* ssl)
{

//ssl initiation
/*SSL_library_init();
SSL_load_error_strings();
const SSL_METHOD *meth;
meth = SSLv3_method();
SSL_CTX *ctx;
SSL *_ssl;
ctx = SSL_CTX_new(meth);*/

}

int main()
{
int sockfd;
int len;
struct sockaddr_in address;
int result=0;
char ch = 'A';


//ssl initiation
SSL_library_init();
SSL_load_error_strings();
SSL_METHOD *meth;
meth = SSLv3_client_method();
SSL_CTX *ctx;
SSL* ssl;
ctx = SSL_CTX_new(meth);    
result = SSL_CTX_load_verify_locations(ctx, "cacert.pem", 0);
//result = SSL_CTX_load_verify_locations(ctx, NULL, "/home/cdac/Desktop/test/cert");
printf("\nCA load result = %d\n", result);
printf("\nSSL initialized");

//socket for client
sockfd = socket(AF_INET, SOCK_STREAM, 0);

//naming socket
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_port = htons(9734);
len = sizeof(address);
printf("length====\n%d",len);
printf("Socket done\n");





//connecting server
result = connect(sockfd, (struct sockaddr *)&address, len);
if(result <0)
{
    perror("oops: client\n");
    exit(1);
}
else
{
    printf("Socket Connected\n");
}

//ssl-ing the connection
ssl = SSL_new(ctx);
BIO *sbio;
sbio = BIO_new(BIO_s_socket());
BIO_set_fd(sbio, sockfd, BIO_NOCLOSE);
SSL_set_bio(ssl, sbio, sbio);
//SSL_CTX_set_verify_depth(ctx, 1);
//SSL_set_fd(ssl, sockfd);
result = SSL_connect(ssl);
printf("SSL_connect: %d\n", result);


if(SSL_get_peer_certificate(ssl)!=NULL)
{


//check cert
    //check_cert(ssl);
    //getting the CA certificate



    //_ssl = SSL_new(ctx);
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);


    int result_long = SSL_get_verify_result(ssl);
    printf("\nCertificate Check Result: %d", result_long);
    if (SSL_get_verify_result(ssl) != X509_V_OK)
        {
            printf("\nCertiticate Verification Failed\n");
            return 0;
            //exit(1);
        }
        else
        {
            printf("\nCertiticate Verification Succeeded");
        }

}
//taking input

printf("\nSay Char: \n");
scanf("%c",&ch);

//exchanging data

SSL_write(ssl, &ch, 1);
SSL_read(ssl, &ch, 1);
printf("char from server = %c\n", ch);
SSL_shutdown(ssl);  
close(sockfd);
exit(0);
}

The codes are simple and self explanatory. 该代码简单易懂。

如果您尝试使用openssl建立通信,请参阅此OpenSSL教程

here's some starting notes for you ... 这是给您的一些开始笔记...

server
{
    SSL_CTX_new()
    SSL_CTX_* set_cipher_list,set_mode,set_options
    SSL_CTX_* set_default_passwd_cb,use_certificate_file,use_PrivateKey_file etc

    SSL_new()
    SSL_set_fd(,socket)    
    SSL_set_accept_state()

    SSL_read()/SSL_write()

    SSL_shutdown()        
    SSL_free()

    SSL_CTX_free()
}

client
{
    SSL_CTX_new()
    SSL_CTX_* set_cipher_list,set_mode,options
    SSL_CTX_* load_verify_locations,set_verify etc

    SSL_new()
    SSL_set_fd(,socket)
    SSL_set_connect_state()

    SSL_read()/SSL_write()

    SSL_shutdown()
    SSL_free()

    SSL_CTX_free()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM