/* tls_client_notpm.c * * Copyright (C) 2006-2022 wolfSSL Inc. * * This file is part of wolfTPM. * * wolfTPM 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. * * wolfTPM 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-1335, USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) && \ !defined(NO_WOLFSSL_CLIENT) && !defined(WOLFCRYPT_ONLY) #include #include #include #include #include #include #undef USE_CERT_BUFFERS_2048 #define USE_CERT_BUFFERS_2048 #undef USE_CERT_BUFFERS_256 #define USE_CERT_BUFFERS_256 #include #ifdef TLS_BENCH_MODE double benchStart; #endif /* * This example client connects to localhost on on port 11111 by default. * These can be overriden using `TLS_HOST` and `TLS_PORT`. * * You can validate using the wolfSSL example server this like: * ./examples/server/server -b -p 11111 -g * * If using an ECDSA cipher suite add: * "-l ECDHE-ECDSA-AES128-SHA -c ./certs/server-ecc.pem -k ./certs/ecc-key.pem" */ /******************************************************************************/ /* --- BEGIN TLS Client Example -- */ /******************************************************************************/ int TLS_Client(void) { return TLS_ClientArgs(0, NULL); } int TLS_ClientArgs(int argc, char *argv[]) { int rc = 0; SockIoCbCtx sockIoCtx; WOLFSSL_CTX* ctx = NULL; WOLFSSL* ssl = NULL; #ifndef TLS_BENCH_MODE const char webServerMsg[] = "GET /index.html HTTP/1.0\r\n\r\n"; #endif char msg[MAX_MSG_SZ]; int msgSz = 0; #ifdef TLS_BENCH_MODE int total_size; int i; #endif int useECC = 0; (void)argc; (void)argv; /* initialize variables */ XMEMSET(&sockIoCtx, 0, sizeof(sockIoCtx)); sockIoCtx.fd = -1; printf("TLS Client Example\n"); if (argc > 1) { if (XSTRCMP(argv[1], "ECC") == 0) { useECC = 1; } } /* TODO make use of useECC */ (void)useECC; wolfSSL_Debugging_ON(); wolfSSL_Init(); /* Setup the WOLFSSL context (factory) * Use highest version, allow downgrade */ if ((ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())) == NULL) { rc = MEMORY_E; goto exit; } /* Setup IO Callbacks */ wolfSSL_CTX_SetIORecv(ctx, SockIORecv); wolfSSL_CTX_SetIOSend(ctx, SockIOSend); /* Server certificate validation */ #if 0 /* skip server cert validation for this test */ wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, myVerify); #else wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify); /* Load CA Certificates from Buffer */ #if !defined(NO_RSA) && !defined(TLS_USE_ECC) if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048, sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { printf("Error loading ca_cert_der_2048 DER cert\n"); goto exit; } #elif defined(HAVE_ECC) if (wolfSSL_CTX_load_verify_buffer(ctx, ca_ecc_cert_der_256, sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { printf("Error loading ca_ecc_cert_der_256 DER cert\n"); goto exit; } #endif #endif #ifndef NO_TLS_MUTUAL_AUTH /* Client Certificate and Key using buffer */ #if !defined(NO_RSA) && !defined(TLS_USE_ECC) if (wolfSSL_CTX_use_certificate_buffer(ctx, client_cert_der_2048, sizeof_client_cert_der_2048, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { goto exit; } if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, client_key_der_2048, sizeof_client_key_der_2048, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { goto exit; } #elif defined(HAVE_ECC) if (wolfSSL_CTX_use_certificate_buffer(ctx, cliecc_cert_der_256, sizeof_cliecc_cert_der_256, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { goto exit; } if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, ecc_clikey_der_256, sizeof_ecc_clikey_der_256, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { goto exit; } #endif #endif /* !NO_TLS_MUTUAL_AUTH */ #ifdef TLS_CIPHER_SUITE /* Optionally choose the cipher suite */ rc = wolfSSL_CTX_set_cipher_list(ctx, TLS_CIPHER_SUITE); if (rc != WOLFSSL_SUCCESS) { goto exit; } #endif /* Create wolfSSL object/session */ if ((ssl = wolfSSL_new(ctx)) == NULL) { rc = wolfSSL_get_error(ssl, 0); goto exit; } /* Setup socket and connection */ rc = SetupSocketAndConnect(&sockIoCtx, TLS_HOST, TLS_PORT); if (rc != 0) goto exit; /* Setup read/write callback contexts */ wolfSSL_SetIOReadCtx(ssl, &sockIoCtx); wolfSSL_SetIOWriteCtx(ssl, &sockIoCtx); /* perform connect */ #ifdef TLS_BENCH_MODE benchStart = gettime_secs(1); #endif do { rc = wolfSSL_connect(ssl); if (rc != WOLFSSL_SUCCESS) { rc = wolfSSL_get_error(ssl, 0); } } while (rc == WOLFSSL_ERROR_WANT_READ || rc == WOLFSSL_ERROR_WANT_WRITE); if (rc != WOLFSSL_SUCCESS) { goto exit; } #ifdef TLS_BENCH_MODE benchStart = gettime_secs(0) - benchStart; printf("Connect: %9.3f sec (%9.3f CPS)\n", benchStart, 1/benchStart); #endif printf("Cipher Suite: %s\n", wolfSSL_get_cipher(ssl)); #ifdef TLS_BENCH_MODE rc = 0; total_size = 0; while (rc == 0 && total_size < TOTAL_MSG_SZ) #endif { /* initialize write */ #ifdef TLS_BENCH_MODE msgSz = sizeof(msg); /* sequence */ for (i=0; i= 0) { msgSz = rc; #ifdef TLS_BENCH_MODE benchStart = gettime_secs(0) - benchStart; printf("Write: %d bytes in %9.3f sec (%9.3f KB/sec)\n", msgSz, benchStart, msgSz / benchStart / 1024); #else printf("Write (%d): %s\n", msgSz, msg); #endif rc = 0; /* success */ } if (rc != 0) goto exit; /* perform read */ #ifdef TLS_BENCH_MODE benchStart = 0; /* use the read callback to trigger timing */ #endif do { /* attempt to fill msg buffer */ rc = wolfSSL_read(ssl, msg, sizeof(msg)); if (rc < 0) { rc = wolfSSL_get_error(ssl, 0); } } while (rc == WOLFSSL_ERROR_WANT_READ); if (rc >= 0) { msgSz = rc; #ifdef TLS_BENCH_MODE benchStart = gettime_secs(0) - benchStart; printf("Read: %d bytes in %9.3f sec (%9.3f KB/sec)\n", msgSz, benchStart, msgSz / benchStart / 1024); #else /* null terminate */ if (msgSz >= (int)sizeof(msg)) msgSz = (int)sizeof(msg) - 1; msg[msgSz] = '\0'; printf("Read (%d): %s\n", msgSz, msg); #endif rc = 0; /* success */ } } exit: if (rc != 0) { printf("Failure %d (0x%x): %s\n", rc, rc, wolfSSL_ERR_reason_error_string(rc)); } wolfSSL_shutdown(ssl); CloseAndCleanupSocket(&sockIoCtx); wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); wolfSSL_Cleanup(); return rc; } /******************************************************************************/ /* --- END TLS Client Example -- */ /******************************************************************************/ #endif /* !WOLFTPM2_NO_WRAPPER && !WOLFTPM2_NO_WOLFCRYPT && !NO_WOLFSSL_CLIENT */ #ifndef NO_MAIN_DRIVER int main(int argc, char *argv[]) { int rc = -1; #if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) && \ !defined(NO_WOLFSSL_CLIENT) && !defined(WOLFCRYPT_ONLY) rc = TLS_ClientArgs(argc, argv); #else printf("WolfSSL Client code not compiled in\n"); (void)argc; (void)argv; #endif return rc; } #endif /* !NO_MAIN_DRIVER */