Merge pull request #476 from ColtonWilley/pkcs11_example_certs

Extend PKCS11 server example for certificate handling
pull/559/head
Andrew Hutchings 2026-02-16 09:39:45 +00:00 committed by GitHub
commit a469e04dbe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 421 additions and 138 deletions

View File

@ -16,46 +16,46 @@ See [PKCS11.md](./PKCS11.md) in this folder.
1. Change to source code directory of SoftHSM version 2
This tool can be found here: https://github.com/opendnssec/SoftHSMv2
This tool can be found here: https://github.com/opendnssec/SoftHSMv2
```
./autogen.sh
./configure --disable-gost
sudo make install
```
```
./autogen.sh
./configure --disable-gost
sudo make install
```
*Note: May need to install pkg-config and libssl-dev*
*Note: May need to install pkg-config and libssl-dev*
2. Change to wolfssl directory
```
./autogen.sh
./configure --enable-pkcs11
make
sudo make install
```
```
./autogen.sh
./configure --enable-pkcs11
make
sudo make install
```
3. Change to wolfssl-examples/pkcs11 directory
```
./mksofthsm2_conf.sh
export SOFTHSM2_CONF=$PWD/softhsm2.conf
```
```
./mksofthsm2_conf.sh
export SOFTHSM2_CONF=$PWD/softhsm2.conf
```
4. Running tests
`softhsm2-util --init-token --slot 0 --label SoftToken`
`softhsm2-util --init-token --slot 0 --label SoftToken`
* Use PIN: cryptoki
* Use User PIN: cryptoki
* Use PIN: cryptoki
* Use User PIN: cryptoki
Use the slot id from the output:
`export SOFTHSM2_SLOTID=<slotid>`
Use the slot id from the output:
Run the examples:
`export SOFTHSM2_SLOTID=<slotid>`
`./softhsm2.sh`
Run the examples:
`./softhsm2.sh`
## Setting up and testing openCryptoki
@ -63,79 +63,103 @@ See [PKCS11.md](./PKCS11.md) in this folder.
1. Change to source code directory of openCryptoki
This tool can be found here: https://github.com/opencryptoki/opencryptoki
This tool can be found here: https://github.com/opencryptoki/opencryptoki
```
./bootstrap.sh
./configure
make
```
```
./bootstrap.sh
./configure
make
```
*Note: May need to install flex, bison and openldap-devel [or libldap2-dev]*
*Note: May need to install flex, bison and openldap-devel [or libldap2-dev]*
2. Setup pkcs11 group and put current user into it
```
sudo groupadd pkcs11
sudo usermod -a -G pkcs11 $USER
```
```
sudo groupadd pkcs11
sudo usermod -a -G pkcs11 $USER
```
3. Install library
```
sudo make install
sudo ldconfig /usr/local/lib
```
```
sudo make install
sudo ldconfig /usr/local/lib
```
4. Start the daemon
`sudo /usr/local/sbin/pkcsslotd`
*Note: May need to logout and login to be able to use pkcsconf.*
`sudo /usr/local/sbin/pkcsslotd`
*Note: May need to logout and login to be able to use pkcsconf.*
5. Setup token
```
echo "87654321
SoftToken" | pkcsconf -I -c 3
```
```
echo "87654321
cryptoki
cryptoki" | pkcsconf -P -c 3
```
```
echo "cryptoki
cryptoki
cryptoki" | pkcsconf -u -c 3
```
```
echo "87654321
SoftToken" | pkcsconf -I -c 3
```
```
echo "87654321
cryptoki
cryptoki" | pkcsconf -P -c 3
```
```
echo "cryptoki
cryptoki
cryptoki" | pkcsconf -u -c 3
```
6. Start daemon if not running already:
`sudo /usr/local/sbin/pkcsslotd`
`sudo /usr/local/sbin/pkcsslotd`
7. Build and install wolfSSL
Change to wolfssl directory and run:
Change to wolfssl directory and run:
```
./autogen.sh
./configure --enable-pkcs11
make
sudo make install
```
```
./autogen.sh
./configure --enable-pkcs11
make
sudo make install
```
8. Running tests
Change to wolfssl-examples/pkcs11 directory:
`./opencryptoki.sh`
Change to wolfssl-examples/pkcs11 directory:
`./opencryptoki.sh`
## Setting up and testing wolfPKCS11
1. Change to source code directory of wolfPKCS11
This tool can be found here: https://github.com/wolfSSL/wolfPKCS11
```
./autogen.sh
./configure
make && sudo make install
./examples/init_token
export WOLFPKCS11_DIR=$(pwd)
```
2. Change to wolfssl directory
```
./autogen.sh
./configure --enable-aescfb --enable-cryptocb --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt --enable-pkcs11 --enable-debug 'C_EXTRA_FLAGS=-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DWOLFSSL_PKCS11_RW_TOKENS'
make
sudo make install
```
It should be noted WOLFSSL_PKCS11_RW_TOKENS is only needed for adding the keys and certs to the store. Once already in the store this is no longer needed.
## TLS Server Example with PKCS #11 (RSA)
## TLS Server Example with SoftHSM (RSA)
The example `server-tls-pkcs11` is a server that uses a private key that has been stored on the PKCS #11 device.
@ -145,41 +169,60 @@ Change this to be the id that you set when importing the key.
1. SoftHSM version 2
Import private key:
`softhsm2-util --import ../certs/server-keyPkcs8.pem --slot $SOFTHSM2_SLOTID --id 0001 --label rsa2048`
Import private key:
Enter PIN: cryptoki
`softhsm2-util --import ../certs/server-keyPkcs8.pem --slot $SOFTHSM2_SLOTID --id 0001 --label rsa2048`
Enter PIN: cryptoki
2. Run server and client
`./server-tls-pkcs11 /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki`
`./server-tls-pkcs11 -lib /usr/local/lib/softhsm/libsofthsm2.so -slot $SOFTHSM2_SLOTID -tokenName SoftToken -userPin cryptoki`
From wolfssl root:
`./examples/client/client`
From wolfssl root:
`./examples/client/client`
## TLS Server Example with PKCS #11 (ECC)
## TLS Server Example with SoftHSM (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`
The id of the private key is two hex bytes: `0x00, 0x02`
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 0002 --label ecp256`
Import private key:
Enter PIN: cryptoki
`softhsm2-util --import ../certs/ecc-keyPkcs8.pem --slot $SOFTHSM2_SLOTID --id 0002 --label ecp256`
Enter PIN: cryptoki
2. Run server and client
`./server-tls-pkcs11-ecc /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki`
`./server-tls-pkcs11-ecc -lib /usr/local/lib/softhsm/libsofthsm2.so -slot $SOFTHSM2_SLOTID -tokenName SoftToken -userPin cryptoki`
From wolfssl root:
`./examples/client/client -A ./certs/ca-ecc-cert.pem`
From wolfssl root:
`./examples/client/client -A ./certs/ca-ecc-cert.pem`
## TLS Server Example with wolfPKCS11 (RSA)
The example `server-tls-pkcs11` is a server that uses a private key and optionally a certificate that has been stored on the PKCS #11 device.
1. Import Private Key and Certificate
```
cd $WOLFPKCS11_DIR
./examples/add_rsa_key_file -privId "server-rsa2048" -rsa ../certs/server-key.der
./examples/add_cert_file -privId "server-rsa2048-id" -label "server-rsa2048-label" -cert ../certs/server-cert.der
```
2. Run server and client
`WOLFPKCS11_TOKEN_PATH=$WOLFPKCS11_DIR ./server-tls-pkcs11 -lib $WOLFPKCS11_DIR/src/.libs/libwolfpkcs11.so -tokenName wolfpkcs11 -userPin wolfpkcs11-test -privKeyId server-rsa2048 -certId server-rsa2048-id`
From wolfssl root:
`./examples/client/client`
## Support

View File

@ -41,7 +41,9 @@
#define PRIV_KEY_ID {0x00, 0x02}
#ifndef WOLFCRYPT_ONLY
int server_tls(int devId, Pkcs11Token* token)
int server_tls(int devId, Pkcs11Token* token, const char *certLabel,
const byte *certId, word32 certIdLen, const byte *privKeyId,
word32 privKeyIdLen)
{
int sockfd;
int connd;
@ -52,7 +54,6 @@ int server_tls(int devId, Pkcs11Token* token)
size_t len;
int shutdown = 0;
int ret;
unsigned char privKeyId[] = PRIV_KEY_ID;
const char* reply = "I hear ya fa shizzle!\n";
/* declare wolfSSL objects */
@ -88,22 +89,39 @@ int server_tls(int devId, Pkcs11Token* token)
}
/* 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;
if (certLabel != NULL) {
if (wolfSSL_CTX_use_certificate_label(ctx, certLabel, devId)
!= SSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load certificate by label: %s\n",
certLabel);
return -1;
}
}
else if (certId != NULL) {
if (wolfSSL_CTX_use_certificate_id(ctx, certId, certIdLen, devId)
!= SSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load certificate by id: %s\n",
certId);
return -1;
}
}
else {
if (wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_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,
if (wolfSSL_CTX_use_PrivateKey_id(ctx, privKeyId, privKeyIdLen, 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));
@ -217,29 +235,130 @@ int server_tls(int devId, Pkcs11Token* token)
}
#endif
static int string_matches(const char* arg, const char* str)
{
int len = (int)XSTRLEN(str) + 1;
return XSTRNCMP(arg, str, len) == 0;
}
static void Usage(void)
{
printf("server-tls-pkcs11\n");
printf("-? Help, print this usage\n");
printf("-lib <file> PKCS#11 library to test\n");
printf("-slot <num> Slot number to use\n");
printf("-tokenName <string> Token name\n");
printf("-userPin <string> User PIN\n");
printf("-privKeyId <string> Private key identifier\n");
printf("-certId <string> Certificate identifier\n");
printf("-certLabel <string> Certificate label\n");
}
int main(int argc, char* argv[])
{
int ret;
const char* library;
const char* slot;
const char* tokenName;
const char* userPin;
const char* library = NULL;
const char* tokenName = NULL;
const char* userPin = NULL;
const char* certLabel = NULL;
const byte* certId = NULL;
int certIdLen = 0;
Pkcs11Dev dev;
Pkcs11Token token;
int slotId;
int slotId = -1;
int devId = 1;
const unsigned char defaultPrivKeyId[] = PRIV_KEY_ID;
int privKeyIdLen = 2;
const byte *privKeyId = (const byte *)defaultPrivKeyId;
if (argc != 4 && argc != 5) {
fprintf(stderr,
"Usage: server_tls_pkcs11 <libname> <slot> <tokenname> [userpin]\n");
return 1;
argc--;
argv++;
while (argc > 0) {
if (string_matches(*argv, "-?")) {
Usage();
return 0;
}
else if (string_matches(*argv, "-lib")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Library name not supplied\n");
return 1;
}
library = *argv;
}
else if (string_matches(*argv, "-slot")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Slot number not supplied\n");
return 1;
}
slotId = atoi(*argv);
}
else if (string_matches(*argv, "-tokenName")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Token name not supplied\n");
return 1;
}
tokenName = *argv;
}
else if (string_matches(*argv, "-userPin")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "User PIN not supplied\n");
return 1;
}
userPin = *argv;
}
else if (string_matches(*argv, "-privKeyId")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Private key identifier not supplied\n");
return 1;
}
privKeyId = (byte*)*argv;
privKeyIdLen = (int)strlen(*argv);
}
else if (string_matches(*argv, "-certId")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Certificate identifier not supplied\n");
return 1;
}
certId = (byte*)*argv;
certIdLen = (int)strlen(*argv);
}
else if (string_matches(*argv, "-certLabel")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Certificate label not supplied\n");
return 1;
}
certLabel = (char*)*argv;
}
else {
fprintf(stderr, "Unrecognized command line argument\n %s\n",
argv[0]);
Usage();
return 1;
}
argc--;
argv++;
}
library = argv[1];
slot = argv[2];
tokenName = argv[3];
userPin = (argc == 4) ? NULL : argv[4];
slotId = atoi(slot);
if (library == NULL || tokenName == NULL) {
fprintf(stderr, "Error: missing arguments\n");
Usage();
return 1;
}
#if defined(DEBUG_WOLFSSL)
wolfSSL_Debugging_ON();
@ -267,7 +386,8 @@ int main(int argc, char* argv[])
}
if (ret == 0) {
#if !defined(WOLFCRYPT_ONLY)
ret = server_tls(devId, &token);
ret = server_tls(devId, &token, certLabel, certId, certIdLen,
privKeyId, (word32)privKeyIdLen);
if (ret != 0)
ret = 1;
#endif

View File

@ -41,7 +41,9 @@
#define PRIV_KEY_ID {0x00, 0x01}
#ifndef WOLFCRYPT_ONLY
int server_tls(int devId, Pkcs11Token* token)
int server_tls(int devId, Pkcs11Token* token, const char *certLabel,
const byte *certId, word32 certIdLen, const byte *privKeyId,
word32 privKeyIdLen)
{
int sockfd;
int connd;
@ -52,7 +54,6 @@ int server_tls(int devId, Pkcs11Token* token)
size_t len;
int shutdown = 0;
int ret;
unsigned char privKeyId[] = PRIV_KEY_ID;
const char* reply = "I hear ya fa shizzle!\n";
/* declare wolfSSL objects */
@ -88,22 +89,39 @@ int server_tls(int devId, Pkcs11Token* token)
}
/* 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;
if (certLabel != NULL) {
if (wolfSSL_CTX_use_certificate_label(ctx, certLabel, devId)
!= SSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load certificate by label: %s\n",
certLabel);
return -1;
}
}
else if (certId != NULL) {
if (wolfSSL_CTX_use_certificate_id(ctx, certId, certIdLen, devId)
!= SSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load certificate by id: %s\n",
certId);
return -1;
}
}
else {
if (wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_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,
if (wolfSSL_CTX_use_PrivateKey_id(ctx, privKeyId, privKeyIdLen, 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));
@ -217,29 +235,130 @@ int server_tls(int devId, Pkcs11Token* token)
}
#endif
static int string_matches(const char* arg, const char* str)
{
int len = (int)XSTRLEN(str) + 1;
return XSTRNCMP(arg, str, len) == 0;
}
static void Usage(void)
{
printf("server-tls-pkcs11\n");
printf("-? Help, print this usage\n");
printf("-lib <file> PKCS#11 library to test\n");
printf("-slot <num> Slot number to use\n");
printf("-tokenName <string> Token name\n");
printf("-userPin <string> User PIN\n");
printf("-privKeyId <string> Private key identifier\n");
printf("-certId <string> Certificate identifier\n");
printf("-certLabel <string> Certificate label\n");
}
int main(int argc, char* argv[])
{
int ret;
const char* library;
const char* slot;
const char* tokenName;
const char* userPin;
const char* library = NULL;
const char* tokenName = NULL;
const char* userPin = NULL;
const char* certLabel = NULL;
const byte* certId = NULL;
int certIdLen = 0;
Pkcs11Dev dev;
Pkcs11Token token;
int slotId;
int slotId = -1;
int devId = 1;
const unsigned char defaultPrivKeyId[] = PRIV_KEY_ID;
int privKeyIdLen = 2;
const byte *privKeyId = (const byte *)defaultPrivKeyId;
if (argc != 4 && argc != 5) {
fprintf(stderr,
"Usage: server_tls_pkcs11 <libname> <slot> <tokenname> [userpin]\n");
return 1;
argc--;
argv++;
while (argc > 0) {
if (string_matches(*argv, "-?")) {
Usage();
return 0;
}
else if (string_matches(*argv, "-lib")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Library name not supplied\n");
return 1;
}
library = *argv;
}
else if (string_matches(*argv, "-slot")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Slot number not supplied\n");
return 1;
}
slotId = atoi(*argv);
}
else if (string_matches(*argv, "-tokenName")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Token name not supplied\n");
return 1;
}
tokenName = *argv;
}
else if (string_matches(*argv, "-userPin")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "User PIN not supplied\n");
return 1;
}
userPin = *argv;
}
else if (string_matches(*argv, "-privKeyId")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Private key identifier not supplied\n");
return 1;
}
privKeyId = (byte*)*argv;
privKeyIdLen = (int)strlen(*argv);
}
else if (string_matches(*argv, "-certId")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Certificate identifier not supplied\n");
return 1;
}
certId = (byte*)*argv;
certIdLen = (int)strlen(*argv);
}
else if (string_matches(*argv, "-certLabel")) {
argc--;
argv++;
if (argc == 0) {
fprintf(stderr, "Certificate label not supplied\n");
return 1;
}
certLabel = (char*)*argv;
}
else {
fprintf(stderr, "Unrecognized command line argument\n %s\n",
argv[0]);
Usage();
return 1;
}
argc--;
argv++;
}
library = argv[1];
slot = argv[2];
tokenName = argv[3];
userPin = (argc == 4) ? NULL : argv[4];
slotId = atoi(slot);
if (library == NULL || tokenName == NULL) {
fprintf(stderr, "Error: missing arguments\n");
Usage();
return 1;
}
#if defined(DEBUG_WOLFSSL)
wolfSSL_Debugging_ON();
@ -267,7 +386,8 @@ int main(int argc, char* argv[])
}
if (ret == 0) {
#if !defined(WOLFCRYPT_ONLY)
ret = server_tls(devId, &token);
ret = server_tls(devId, &token, certLabel, certId, certIdLen,
privKeyId, (word32)privKeyIdLen);
if (ret != 0)
ret = 1;
#endif