From 0647d0c8085a4c848450ba2debe0d71c80b3f67f Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Tue, 13 Mar 2018 08:52:34 -0600 Subject: [PATCH] Add pkcs12 examples client and remove build blockers implement better memory handling --- .gitignore | 1 + certs/generate-client-bundle.sh | 10 ++ certs/test-clientbundle.p12 | Bin 0 -> 4077 bytes tls/client-tls-pkcs12.c | 269 ++++++++++++++++++++++++++++++++ tls/client-tls-writedup.c | 15 +- 5 files changed, 288 insertions(+), 7 deletions(-) create mode 100755 certs/generate-client-bundle.sh create mode 100644 certs/test-clientbundle.p12 create mode 100644 tls/client-tls-pkcs12.c diff --git a/.gitignore b/.gitignore index 9c6c7a97..98f4d615 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ android/wolfssljni-ndk-sample/proguard-project.txt /tls/server-tls-epoll-threaded /tls/server-tls-nonblocking /tls/server-tls-threaded +/tls/client-tls-pkcs12 crypto/3des/3des-file-encrypt crypto/aes/aes-file-encrypt diff --git a/certs/generate-client-bundle.sh b/certs/generate-client-bundle.sh new file mode 100755 index 00000000..3aa3e206 --- /dev/null +++ b/certs/generate-client-bundle.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# set this to point to the wolfSSL root directory for updating certs +WOLFSSL_ROOT_DIR=~/clean-wolfssl + +cp ${WOLFSSL_ROOT_DIR}/certs/client-cert.pem ./ +cp ${WOLFSSL_ROOT_DIR}/certs/client-key.pem ./ +cp ${WOLFSSL_ROOT_DIR}/certs/ca-cert.pem ./ + +echo "wolfSSL test" | openssl pkcs12 -des3 -descert -export -in client-cert.pem -inkey client-key.pem -certfile ca-cert.pem -out test-clientbundle.p12 -password stdin diff --git a/certs/test-clientbundle.p12 b/certs/test-clientbundle.p12 new file mode 100644 index 0000000000000000000000000000000000000000..f58b62758788903abdd60936d7b7c10fff6bbc6c GIT binary patch literal 4077 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 literal 0 HcmV?d00001 diff --git a/tls/client-tls-pkcs12.c b/tls/client-tls-pkcs12.c new file mode 100644 index 00000000..542abf88 --- /dev/null +++ b/tls/client-tls-pkcs12.c @@ -0,0 +1,269 @@ +/* client-tls-pkcs12.c + * + * Copyright (C) 2006-2015 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * To test this example simply run against the default wolfSSL server: + * : cd ~/path-to-wolfssl-root/ + * : ./examples/server/server + */ + + +/* the usual suspects */ +#include +#include +#include + +/* socket includes */ +#include +#include +#include +#include + +/* wolfSSL */ +#include +#include +#include + +#define DEFAULT_PORT 11111 + +#define APP_ERR -999 +#define ERR_NO_CA_IN_P12 -1000 + +int main(int argc, char** argv) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_PWDBASED) && !defined(NO_ASN) \ + && !defined(NO_DES3) + int sockfd; + struct sockaddr_in servAddr; + char buff[256]; + size_t len; + + /* declare wolfSSL objects */ + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; +/*----------------------------------------------------------------------------*/ +/* updates from the original example client-tls.c */ +/*----------------------------------------------------------------------------*/ + byte buffer[5300]; + char file[] = "../certs/test-clientbundle.p12"; + char pass[] = "wolfSSL test"; + FILE *f; + int firstLoop = 1; + int root_ca_buf_size = -1, bytes, ret; + byte* root_ca_buf; + + WOLFSSL_BIO* bio; + WOLFSSL_EVP_PKEY* pkey; + WC_PKCS12* pkcs12; + WOLFSSL_X509* cert; + WOLFSSL_X509* tmp; + + WOLF_STACK_OF(WOLFSSL_X509)* ca; +/*----------------------------------------------------------------------------*/ + + /* Check for proper calling convention */ + if (argc != 2) { + printf("usage: %s \n", argv[0]); + return 0; + } + + /* Create a socket that uses an internet IPv4 address, + * Sets the socket to be stream based (TCP), + * 0 means choose the default protocol. */ + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + fprintf(stderr, "ERROR: failed to create the socket\n"); + return -1; + } + + /* Initialize the server address struct with zeros */ + memset(&servAddr, 0, sizeof(servAddr)); + + /* Fill in the server address */ + servAddr.sin_family = AF_INET; /* using IPv4 */ + servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */ + + /* Get the server IPv4 address from the command line call */ + if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) != 1) { + fprintf(stderr, "ERROR: invalid address\n"); + return -1; + } + + /* Connect to the server */ + if (connect(sockfd, (struct sockaddr*) &servAddr, sizeof(servAddr)) == -1) { + fprintf(stderr, "ERROR: failed to connect\n"); + return -1; + } + +/*----------------------------------------------------------------------------*/ +/* Extract cert, key, CA from PKCS12 file for use in mutual auth */ +/*----------------------------------------------------------------------------*/ + f = fopen(file, "rb"); + if (!f) { + printf("Error opening %s check the file\n", file); + return APP_ERR; + } + + bytes = (int)fread(buffer, 1, sizeof(buffer), f); + printf("Read %d bytes from file\n", bytes); + fclose(f); + + /* Initialize wolfSSL */ + wolfSSL_Init(); + + /* Create and initialize WOLFSSL_CTX */ + if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) { + fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); + return -1; + } + + bio = wolfSSL_BIO_new_mem_buf((void*)buffer, bytes); + if (!bio) { + printf("Failed to create bio\n"); + wolfSSL_CTX_free(ctx); + wolfSSL_Cleanup(); + close(sockfd); + return APP_ERR; + } + + wolfSSL_d2i_PKCS12_bio(bio, &pkcs12); + if (!pkcs12) { + printf("Failed the d2i_PKCS12_bio call\n"); + wolfSSL_CTX_free(ctx); + wolfSSL_Cleanup(); + wolfSSL_BIO_free(bio); + close(sockfd); + return APP_ERR; + } + + /* check parse with extra certs kept */ + ret = wolfSSL_PKCS12_parse(pkcs12, pass, &pkey, &cert, &ca); + if (ret != WOLFSSL_SUCCESS) { + printf("Failed to parse the PKCS12 data. ret = %d\n", ret); + ret = APP_ERR; + goto client_example_end_no_ssl; + } + + /* NOTE: these two calls are optional, only required for mutual auth */ + wolfSSL_CTX_use_PrivateKey(ctx, pkey); /* optional */ + wolfSSL_CTX_use_certificate(ctx, cert); /* optional */ + + /* This step is REQUIRED to validate the peer being connected to */ + if (ca != NULL) { + do { + tmp = wolfSSL_sk_X509_pop(ca); + if (tmp == NULL && firstLoop) { + return ERR_NO_CA_IN_P12; + } else if (tmp != NULL) { + /* do something interesting with tmp, maybe it's an intermediate + * CA, maybe it's the root CA? + */ + ret = wolfSSL_X509_get_isCA(tmp); + if (ret == 1) { + root_ca_buf = (byte*) wolfSSL_X509_get_der(tmp, + &root_ca_buf_size); + + wolfSSL_CTX_load_verify_buffer(ctx, root_ca_buf, + root_ca_buf_size, SSL_FILETYPE_ASN1); + wolfSSL_X509_free(tmp); + } else { + wolfSSL_X509_free(tmp); + } + } + firstLoop = 0; + /* Continue popping until no certs left or target cert is found */ + } while (tmp != NULL); + } + + /* Create a WOLFSSL object */ + if ((ssl = wolfSSL_new(ctx)) == NULL) { + fprintf(stderr, "ERROR: failed to create WOLFSSL object\n"); + ret = -1; + goto client_example_end_no_ssl; + } + + /* Attach wolfSSL to the socket */ + wolfSSL_set_fd(ssl, sockfd); + + /* Connect to wolfSSL on the server side */ + if (wolfSSL_connect(ssl) != SSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to connect to wolfSSL\n"); + ret = -1; + goto client_example_end; + } + + /* Get a message for the server from stdin */ + printf("Message for server: "); + memset(buff, 0, sizeof(buff)); + fgets(buff, sizeof(buff), stdin); + len = strnlen(buff, sizeof(buff)); + + /* Send the message to the server */ + if (wolfSSL_write(ssl, buff, (int) len) != len) { + fprintf(stderr, "ERROR: failed to write\n"); + ret = -1; + goto client_example_end; + } + + /* Read the server data into our buff array */ + memset(buff, 0, sizeof(buff)); + if (wolfSSL_read(ssl, buff, sizeof(buff)-1) == -1) { + fprintf(stderr, "ERROR: failed to read\n"); + ret = -1; + } + + /* Print to stdout any data the server sends */ + printf("Server: %s\n", buff); + +client_example_end: + /* Cleanup and return */ + wolfSSL_free(ssl); /* Free the wolfSSL object */ +client_example_end_no_ssl: + wolfSSL_EVP_PKEY_free(pkey); + wolfSSL_X509_free(cert); + wc_PKCS12_free(pkcs12); + wolfSSL_BIO_free(bio); + wolfSSL_sk_X509_free(ca); + wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ + wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */ + close(sockfd); /* Close the connection to the server */ + #else + #ifndef OPENSSL_EXTRA + printf("wolfSSL not configured with --enable-opensslextra\n" + #endif + + #ifdef NO_PWDBASED + printf("wolfSSL not configured with --enable-pwdbased\n"); + #endif + + #ifdef NO_ASN + printf("wolfSSL not configured with --enable-asn support\n"); + #endif + + #ifdef NO_DES3 + printf("wolfSSL not configured with --enable-des3\n"); + #endif + + printf("Please re-configure and re-install wolfSSL before using\n" + "this example\n\n"); + #endif + return ret; /* Return reporting a success */ +} + diff --git a/tls/client-tls-writedup.c b/tls/client-tls-writedup.c index 126b3d9e..5b52bc74 100644 --- a/tls/client-tls-writedup.c +++ b/tls/client-tls-writedup.c @@ -38,11 +38,6 @@ #include #include -/* check for writedup */ -#ifndef HAVE_WRITE_DUP - #error "wolfSSL must be configured and installed with --enable-writedup" -#endif - /* threads */ #include @@ -51,7 +46,7 @@ #define CERT_FILE "../certs/ca-cert.pem" - +#ifdef HAVE_WRITE_DUP void* ReadHandler(void* args) { char buff[256]; @@ -92,11 +87,12 @@ void* WriteHandler(void* args) return NULL; } - +#endif int main(int argc, char** argv) { +#ifdef HAVE_WRITE_DUP int sockfd; struct sockaddr_in servAddr; @@ -214,5 +210,10 @@ int main(int argc, char** argv) wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */ close(sockfd); /* Close the connection to the server */ +#else + printf("wolfSSL not configured with --enable-writedup.\n" + "Please re-configure and re-install wolfSSL to try out" + "this example!\n"); +#endif return 0; /* Return reporting a success */ }