Transmission and verification of certificate (openssl) with socket in c
I have to write these codes in c. I have already generate the certificate of one terminate t1: t1.pem, which is generated by openssl. The communication between the terminates t1 and t2 has been established via socket in 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. When t1 get this acceptance, it will the rest of stuffs..
But I don't know how to do these things.
For example, I transmit t1.pem as a string? But in t2 side, how can I do to verify? I know there are functions in openssl to do so, but I'm not so clear about it. At last, normally, the acceptance should be like how?
@.@...a lot of questions here.. sorry...if some开发者_JAVA百科one could give me some guide.. Thanks a lot in advance!
If you are trying to establish communication using openssl have a look at this OpenSSL tutorial.
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()
}
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.
精彩评论