Skip to content

Instantly share code, notes, and snippets.

@roodkcab
Created September 13, 2018 11:34
Show Gist options
  • Select an option

  • Save roodkcab/cbd71a81897f592a4109b30923dface4 to your computer and use it in GitHub Desktop.

Select an option

Save roodkcab/cbd71a81897f592a4109b30923dface4 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define MAXBUF 1024
#define CA_FILE "/cert/server.crt"
#define CLIENT_KEY "/cert/clientkey.pem"
#define CLIENT_CERT "/cert/client.crt"
#define KEY_PASSWD "testpass"
void ShowCerts(SSL * ssl)
{
X509 *cert;
char *line;
cert = SSL_get_peer_certificate(ssl);
if (cert != NULL) {
printf("x509 cert information:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("cert: %s\n", line);
free(line);
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("creator: %s\n", line);
free(line);
X509_free(cert);
} else {
printf("no cert info!\n");
}
}
int main(int argc, char **argv)
{
int sockfd, len;
struct sockaddr_in dest;
char buffer[MAXBUF + 1];
SSL_CTX *ctx;
SSL *ssl;
const SSL_METHOD *method;
if (argc != 3) {
printf("args error:\n\t\t%s IPADDR PORT\n\texample:\t%s 127.0.0.1 80\n", argv[0], argv[0]);
exit(0);
}
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
method = TLSv1_client_method();
ctx = SSL_CTX_new(method);
if (!ctx) {
printf("create ctx is failed.\n");
}
#if 0
const char * cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH";
if (SSL_CTX_set_cipher_list(ctx, cipher_list) == 0) {
SSL_CTX_free(ctx);
printf("Failed to set cipher list: %s", cipher_list);
}
#endif
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
/*SERVER CA FILE*/
if (SSL_CTX_load_verify_locations(ctx, CA_FILE, 0) != 1) {
SSL_CTX_free(ctx);
printf("Failed to load CA file %s", CA_FILE);
exit(1);
}
if (SSL_CTX_set_default_verify_paths(ctx) != 1) {
SSL_CTX_free(ctx);
printf("Call to SSL_CTX_set_default_verify_paths failed");
exit(1);
}
/*CLIENT CA FILE*/
if (SSL_CTX_use_certificate_file(ctx, CLIENT_CERT, SSL_FILETYPE_PEM) != 1) {
SSL_CTX_free(ctx);
printf("Failed to load client certificate from %s", CLIENT_KEY);
exit(1);
}
/*CLIENT PRIVATE KEY*/
SSL_CTX_set_default_passwd_cb_userdata(ctx, KEY_PASSWD);
if (SSL_CTX_use_PrivateKey_file(ctx, CLIENT_KEY, SSL_FILETYPE_PEM) != 1) {
SSL_CTX_free(ctx);
printf("Failed to load client private key from %s", CLIENT_KEY);
exit(1);
}
/*CHECK*/
if (SSL_CTX_check_private_key(ctx) != 1) {
SSL_CTX_free(ctx);
printf("SSL_CTX_check_private_key failed");
exit(1);
}
/*MULTIPLE HANDSHAKE*/
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket");
exit(errno);
}
bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(atoi(argv[2]));
if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {
perror(argv[1]);
exit(errno);
}
if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
perror("Connect ");
exit(errno);
}
/*CREATE SSL*/
ssl = SSL_new(ctx);
if (ssl == NULL) {
printf("SSL_new error.\n");
}
SSL_set_fd(ssl, sockfd);
if (SSL_connect(ssl) == -1) {
printf("SSL_connect fail.\n");
ERR_print_errors_fp(stderr);
} else {
printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
ShowCerts(ssl);
}
bzero(buffer, MAXBUF + 1);
//SSL_write(ssl, "ls /", 4);
len = SSL_read(ssl, buffer, MAXBUF);
if (len > 0) {
printf("msg:'%s',%d bytes data\n", buffer, len);
} else {
printf("error!code:%d,message: '%s'\n", errno, strerror(errno));
goto finish;
}
bzero(buffer, MAXBUF + 1);
strcpy(buffer, "from client->server");
len = SSL_write(ssl, buffer, strlen(buffer));
if (len < 0) {
printf("'%s' send error!code is %d,message '%s'\n", buffer, errno, strerror(errno));
} else {
printf("'%s' send success!,%d bytes data!\n", buffer, len);
}
finish:
SSL_shutdown(ssl);
SSL_free(ssl);
close(sockfd);
SSL_CTX_free(ctx);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment