From c18ce585dab7d3f13c42297798673266e2ca8fc2 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 25 Feb 2019 11:16:39 +1000 Subject: [PATCH] Add PKCS #11 server sample using ECDSA --- pkcs11/README.md | 25 ++- pkcs11/server-tls-pkcs11-ecc | Bin 0 -> 18232 bytes pkcs11/server-tls-pkcs11-ecc.c | 283 +++++++++++++++++++++++++++++++++ 3 files changed, 307 insertions(+), 1 deletion(-) create mode 100755 pkcs11/server-tls-pkcs11-ecc create mode 100644 pkcs11/server-tls-pkcs11-ecc.c diff --git a/pkcs11/README.md b/pkcs11/README.md index a2b2240c..752af330 100644 --- a/pkcs11/README.md +++ b/pkcs11/README.md @@ -135,7 +135,7 @@ See [PKCS11.md](./PKCS11.md) in this folder. `./opencryptoki.sh` -## TLS Server Example with PKCS #11 +## TLS Server Example with PKCS #11 (RSA) The example `server-tls-pkcs11` is a server that uses a private key that has been stored on the PKCS #11 device. @@ -154,7 +154,30 @@ Change this to be the id that you set when importing the key. 2. Run server and client `./server-tls-pkcs11 /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki` + + From wolfssl root: + `./examples/client/client` + +## TLS Server Example with PKCS #11 (ECC) + +The example `server-tls-pkcs11-ecc` is a server that uses a private key that has been stored on the PKCS #11 device. + +The id of the private key is two hex bytes: `0x00, 0x01` + +Change this to be the id that you set when importing the key. + +1. SoftHSM version 2 + + Import private key: + `softhsm2-util --import ../certs/ecc-keyPkcs8.pem --slot $SOFTHSM2_SLOTID --id 0001 --label ecp256` + + Enter PIN: cryptoki + +2. Run server and client + + `./server-tls-pkcs11-ecc /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki` + From wolfssl root: `./examples/client/client` diff --git a/pkcs11/server-tls-pkcs11-ecc b/pkcs11/server-tls-pkcs11-ecc new file mode 100755 index 0000000000000000000000000000000000000000..3e49a486c23df5150c6bbae6214feebd34f74f99 GIT binary patch literal 18232 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 literal 0 HcmV?d00001 diff --git a/pkcs11/server-tls-pkcs11-ecc.c b/pkcs11/server-tls-pkcs11-ecc.c new file mode 100644 index 00000000..fbebcf10 --- /dev/null +++ b/pkcs11/server-tls-pkcs11-ecc.c @@ -0,0 +1,283 @@ +/* server-tls.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 + */ + +/* the usual suspects */ +#include +#include +#include + +/* socket includes */ +#include +#include +#include +#include + +/* wolfSSL */ +#include +#include +#include + +#define DEFAULT_PORT 11111 + +#define CERT_FILE "../certs/server-ecc.pem" +#define PRIV_KEY_ID {0x00, 0x01} + +#ifndef WOLFCRYPT_ONLY +int server_tls(int devId, Pkcs11Token* token) +{ + int sockfd; + int connd; + struct sockaddr_in servAddr; + struct sockaddr_in clientAddr; + socklen_t size = sizeof(clientAddr); + char buff[256]; + size_t len; + int shutdown = 0; + int ret; + unsigned char privKeyId[] = PRIV_KEY_ID; + + /* declare wolfSSL objects */ + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + + + + /* Initialize wolfSSL */ + wolfSSL_Init(); + + + + /* 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; + } + + + + /* Create and initialize WOLFSSL_CTX */ + if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method())) == NULL) { + fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); + return -1; + } + + if (wolfSSL_CTX_SetDevId(ctx, devId) != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); + return -1; + } + + /* Load server certificates into WOLFSSL_CTX */ + if (wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM) + != SSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + CERT_FILE); + return -1; + } + + /* Load server key into WOLFSSL_CTX */ + if (wolfSSL_CTX_use_PrivateKey_id(ctx, privKeyId, sizeof(privKeyId), devId, + 2048/8) != SSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to set id.\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 */ + servAddr.sin_addr.s_addr = INADDR_ANY; /* from anywhere */ + + + + /* Bind the server socket to our port */ + if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { + fprintf(stderr, "ERROR: failed to bind\n"); + return -1; + } + + /* Listen for a new connection, allow 5 pending connections */ + if (listen(sockfd, 5) == -1) { + fprintf(stderr, "ERROR: failed to listen\n"); + return -1; + } + + + + /* Continue to accept clients until shutdown is issued */ + while (!shutdown) { + printf("Waiting for a connection...\n"); + + /* Accept client connections */ + if ((connd = accept(sockfd, (struct sockaddr*)&clientAddr, &size)) + == -1) { + fprintf(stderr, "ERROR: failed to accept the connection\n\n"); + return -1; + } + + /* Create a WOLFSSL object */ + if ((ret = wc_Pkcs11Token_Open(token, 1)) != 0) { + fprintf(stderr, "ERROR: failed to open session on token (%d)\n", + ret); + return -1; + } + + /* Create a WOLFSSL object */ + if ((ssl = wolfSSL_new(ctx)) == NULL) { + fprintf(stderr, "ERROR: failed to create WOLFSSL object\n"); + return -1; + } + + /* Attach wolfSSL to the socket */ + wolfSSL_set_fd(ssl, connd); + + /* Establish TLS connection */ + ret = wolfSSL_accept(ssl); + if (ret != SSL_SUCCESS) { + fprintf(stderr, "wolfSSL_accept error = %d\n", + wolfSSL_get_error(ssl, ret)); + return -1; + } + + + printf("Client connected successfully\n"); + + + + /* Read the client 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"); + return -1; + } + + /* Print to stdout any data the client sends */ + printf("Client: %s\n", buff); + + /* Check for server shutdown command */ + if (strncmp(buff, "shutdown", 8) == 0) { + printf("Shutdown command issued!\n"); + shutdown = 1; + } + + + + /* Write our reply into buff */ + memset(buff, 0, sizeof(buff)); + memcpy(buff, "I hear ya fa shizzle!\n", sizeof(buff)); + len = strnlen(buff, sizeof(buff)); + + /* Reply back to the client */ + if (wolfSSL_write(ssl, buff, len) != len) { + fprintf(stderr, "ERROR: failed to write\n"); + return -1; + } + + + + /* Cleanup after this connection */ + wolfSSL_free(ssl); /* Free the wolfSSL object */ + wc_Pkcs11Token_Close(token); + close(connd); /* Close the connection to the client */ + } + + printf("Shutdown complete\n"); + + + + /* Cleanup and return */ + wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ + wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */ + close(sockfd); /* Close the socket listening for clients */ + return 0; /* Return reporting a success */ +} +#endif + +int main(int argc, char* argv[]) +{ + int ret; + const char* library; + const char* slot; + const char* tokenName; + const char* userPin; + Pkcs11Dev dev; + Pkcs11Token token; + int slotId; + int devId = 1; + + if (argc != 5) { + fprintf(stderr, + "Usage: server_tls_pkcs11 \n"); + return 1; + } + + library = argv[1]; + slot = argv[2]; + tokenName = argv[3]; + userPin = argv[4]; + slotId = atoi(slot); + +#if defined(DEBUG_WOLFSSL) + wolfSSL_Debugging_ON(); +#endif + wolfCrypt_Init(); + + ret = wc_Pkcs11_Initialize(&dev, library, NULL); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 library\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_Pkcs11Token_Init(&token, &dev, slotId, tokenName, + (byte*)userPin, strlen(userPin)); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb, + &token); + if (ret != 0) { + fprintf(stderr, "Failed to register PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + #if !defined(WOLFCRYPT_ONLY) + ret = server_tls(devId, &token); + if (ret != 0) + ret = 1; + #endif + } + wc_Pkcs11Token_Final(&token); + } + wc_Pkcs11_Finalize(&dev); + } + + wolfCrypt_Cleanup(); + + return ret; +} +