sudo apt-get install libssl-dev
gcc server.c -o server -lcrypto -lssl
vi server.c
#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_PORT 8080
#define CA_CERT_FILE "../openssl/ca/ca.crt"
#define SERVER_CERT_FILE "../openssl/server/server.crt"
#define SERVER_KEY_FILE "../openssl/server/server.key"
typedef struct sockaddr SA;
int TcpInit()
{
int listener;
do{
listener = socket(AF_INET, SOCK_STREAM, 0);
if( listener == -1 )
return 0;
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = 0;
sin.sin_port = htons(SERVER_PORT);
if( bind(listener, (SA*)&sin, sizeof(sin)) < 0 )
break;
if( listen(listener, 5) < 0)
break;
return listener;
}while(0);
return -1;
}
void print_peer_certificate(SSL *ssl)
{
X509* cert= NULL;
X509_NAME *name=NULL;
char buf[8192]={0};
BIO *bio_cert = NULL;
cert = SSL_get_peer_certificate(ssl);
if (cert == NULL) {
printf("SSL_get_peer_certificate() == NULL\n");
return;
}
if (SSL_get_verify_result(ssl) == X509_V_OK) {
printf("SSL_get_verify_result(ssl) == X509_V_OK\n");
}
name = X509_get_subject_name(cert);
X509_NAME_oneline(name,buf,8191);
printf("ServerSubjectName:%s\n",buf);
memset(buf,0,sizeof(buf));
bio_cert = BIO_new(BIO_s_mem());
PEM_write_bio_X509(bio_cert, cert);
BIO_read( bio_cert, buf, 8191);
printf("SERVER CERT:\n%s\n",buf);
if(bio_cert)BIO_free(bio_cert);
if(cert)X509_free(cert);
}
static int verify_cb(int res, X509_STORE_CTX *xs)
{
printf("SSL VERIFY RESULT :%d\n",res);
switch (xs->error)
{
case X509_V_ERR_UNABLE_TO_GET_CRL:
printf(" NOT GET CRL!\n");
return 1;
default :
break;
}
return res;
}
int main(int argc, char **argv)
{
SSL_CTX *ctx;
SSL *ssl;
X509 *client_cert;
char szBuffer[1024];
int nLen;
struct sockaddr_in addr;
int nListenFd, nAcceptFd;
nListenFd = TcpInit();
SSLeay_add_ssl_algorithms();
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
ERR_load_BIO_strings();
memset(&addr, 0, sizeof(addr));
int len = sizeof(addr);
nAcceptFd = accept(nListenFd, (struct sockaddr *)&addr, &len);
//int iMode = 1;
//int iret = ioctlsocket(nAcceptFd, FIONBIO, (u_long FAR*)&iMode);
ctx = SSL_CTX_new (SSLv23_method());
if( ctx == NULL)
{
printf("SSL_CTX_new error!\n");
return -1;
}
#define USE_CA_CERT
#ifdef USE_CA_CERT
// 使用 CA_CERT_FILE 檢查 Client 端的證書
printf("SSL_CTX_set_verify(SSL_VERIFY_PEER)\n");
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
if(!SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, NULL))
{
printf("SSL_CTX_load_verify_locations error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
#else
printf("SSL_CTX_set_verify(SSL_VERIFY_NONE)\n");
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
#endif
if(SSL_CTX_use_certificate_file(ctx, SERVER_CERT_FILE, SSL_FILETYPE_PEM) <= 0)
{
printf("SSL_CTX_use_certificate_file error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
if(SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY_FILE, SSL_FILETYPE_PEM) <= 0)
{
printf("SSL_CTX_use_PrivateKey_file error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
if(!SSL_CTX_check_private_key(ctx))
{
printf("SSL_CTX_check_private_key error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
ssl = SSL_new (ctx);
if(!ssl)
{
printf("SSL_new error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
SSL_set_fd (ssl, nAcceptFd);
while(1){
if(SSL_accept (ssl) != 1)
{
int icode = -1;
ERR_print_errors_fp(stderr);
int iret = SSL_get_error(ssl, icode);
printf("SSL_accept error! code = %d, iret = %d\n", icode, iret);
break;
} else
break;
}
print_peer_certificate(ssl);
memset(szBuffer, 0, sizeof(szBuffer));
nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer));
fprintf(stderr, "Get Len %d %s ok\n", nLen, szBuffer);
strcat(szBuffer, "\n this is from server========server resend to client");
SSL_write(ssl, szBuffer, strlen(szBuffer));
SSL_free (ssl);
SSL_CTX_free (ctx);
close(nAcceptFd);
}
gcc client.c -o client -lcrypto -lssl
vi client.c
#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_PORT 8080
#define SERVER_IP "127.0.0.1"
#define CA_CERT_FILE "../openssl/ca/ca.crt"
#define CLIENT_CERT_FILE "../openssl/client/client.crt"
#define CLIENT_KEY_FILE "../openssl/client/client.key"
void print_client_cert(char* path)
{
X509 *cert =NULL;
FILE *fp = NULL;
fp = fopen(path,"rb");
cert = PEM_read_X509(fp, NULL, NULL, NULL);
X509_NAME *name=NULL;
char buf[8192]={0};
BIO *bio_cert = NULL;
name = X509_get_subject_name(cert);
X509_NAME_oneline(name,buf,8191);
printf("ClientSubjectName:%s\n",buf);
memset(buf,0,sizeof(buf));
bio_cert = BIO_new(BIO_s_mem());
PEM_write_bio_X509(bio_cert, cert);
BIO_read( bio_cert, buf, 8191);
printf("CLIENT CERT:\n%s\n",buf);
if(bio_cert)BIO_free(bio_cert);
fclose(fp);
if(cert) X509_free(cert);
}
void print_peer_certificate(SSL *ssl)
{
X509* cert= NULL;
X509_NAME *name=NULL;
char buf[8192]={0};
BIO *bio_cert = NULL;
cert = SSL_get_peer_certificate(ssl);
if (cert == NULL) {
printf("SSL_get_peer_certificate() == NULL\n");
return;
}
if (SSL_get_verify_result(ssl) == X509_V_OK) {
printf("SSL_get_verify_result(ssl) == X509_V_OK\n");
}
name = X509_get_subject_name(cert);
X509_NAME_oneline(name,buf,8191);
printf("ServerSubjectName:%s\n",buf);
memset(buf,0,sizeof(buf));
bio_cert = BIO_new(BIO_s_mem());
PEM_write_bio_X509(bio_cert, cert);
BIO_read( bio_cert, buf, 8191);
printf("SERVER CERT:\n%s\n",buf);
if(bio_cert)BIO_free(bio_cert);
if(cert)X509_free(cert);
}
static int verify_cb(int res, X509_STORE_CTX *xs)
{
printf("SSL VERIFY RESULT :%d\n",res);
switch (xs->error)
{
case X509_V_ERR_UNABLE_TO_GET_CRL:
printf(" NOT GET CRL!\n");
return 1;
default :
break;
}
return res;
}
int main(int argc, char **argv)
{
char *address = SERVER_IP;
if(argc > 1)
{
address = argv[1];
}
SSL_METHOD *meth;
SSL_CTX *ctx;
SSL *ssl;
int nFd;
int nLen;
char szBuffer[1024];
SSLeay_add_ssl_algorithms();
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
ERR_load_BIO_strings();
print_client_cert(CLIENT_CERT_FILE);
// 使用SSL V3,V2
ctx = SSL_CTX_new (SSLv23_method());
if( ctx == NULL)
{
printf("SSL_CTX_new error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
#define USE_CA_CERT
#ifdef USE_CA_CERT
// 使用 CA_CERT_FILE 檢查 Server 端的證書
printf("SSL_CTX_set_verify(SSL_VERIFY_PEER)\n");
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb);
if(!SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, NULL))
{
printf("SSL_CTX_load_verify_locations error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
#else
printf("SSL_CTX_set_verify(SSL_VERIFY_NONE)\n");
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
#endif
#define USE_CERT
#ifdef USE_CERT
printf("SSL_CTX_use_certificate_file start!\n");
if(SSL_CTX_use_certificate_file(ctx, CLIENT_CERT_FILE, SSL_FILETYPE_PEM) <= 0)
{
printf("SSL_CTX_use_certificate_file error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
printf("SSL_CTX_use_PrivateKey_file start!\n");
if(SSL_CTX_use_PrivateKey_file(ctx, CLIENT_KEY_FILE, SSL_FILETYPE_PEM) <= 0)
{
printf("SSL_CTX_use_PrivateKey_file error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
if(!SSL_CTX_check_private_key(ctx))
{
printf("SSL_CTX_check_private_key error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
#endif
nFd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_addr.s_addr = inet_addr(address);
addr.sin_family = AF_INET;
addr.sin_port = htons(SERVER_PORT);
if(connect(nFd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
printf("connect\n");
ERR_print_errors_fp(stderr);
return -1;
}
ssl = SSL_new (ctx);
if( ssl == NULL)
{
printf("SSL_new error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
SSL_set_fd (ssl, nFd);
if( SSL_connect (ssl) != 1)
{
printf("SSL_new error!\n");
ERR_print_errors_fp(stderr);
return -1;
}
print_peer_certificate(ssl);
sprintf(szBuffer, "\nthis is from client+++++++++++++++client send to server");
SSL_write(ssl, szBuffer, strlen(szBuffer));
memset(szBuffer, 0, sizeof(szBuffer));
nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer));
fprintf(stderr, "Get Len %d %s ok\n", nLen, szBuffer);
SSL_free (ssl);
SSL_CTX_free (ctx);
close(nFd);
}
沒有留言:
張貼留言