Created
September 13, 2018 11:34
-
-
Save roodkcab/cbd71a81897f592a4109b30923dface4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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