Update corePKCS11 demo code and auto-format

This commit is contained in:
Paul Bartell
2022-10-25 11:25:49 -07:00
parent 593f06d3db
commit a3f8fa7a0d
8 changed files with 163 additions and 154 deletions

View File

@@ -0,0 +1,2 @@
corePKCS11_*.dat

View File

@@ -44,7 +44,7 @@
#include "demo_helpers.h"
void vStart( CK_SESSION_HANDLE * pxSession,
CK_SLOT_ID ** ppxSlotId )
CK_SLOT_ID ** ppxSlotId )
{
CK_RV xResult = CKR_OK;
@@ -101,7 +101,7 @@ void vStart( CK_SESSION_HANDLE * pxSession,
/*-----------------------------------------------------------*/
void vEnd( CK_SESSION_HANDLE xSession,
CK_SLOT_ID * pxSlotId )
CK_SLOT_ID * pxSlotId )
{
C_CloseSession( xSession );
C_Finalize( NULL );

View File

@@ -40,10 +40,10 @@
#include "pkcs11_demos.h"
/**
* This function details how to use the PKCS #11 "Management" functions to
* This function details how to use the PKCS #11 "Management" functions to
* manage the internal state machine of the PKCS #11 implementation. These
* functions are all defined in
* http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html
* functions are all defined in
* http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html
* please consult the standard for more information regarding these functions.
*
* The standard has grouped the functions presented in this demo as:
@@ -54,19 +54,19 @@
*/
void vPKCS11ManagementAndRNGDemo( void )
{
/* We will use the terminology as defined in the standard, Cryptoki is in
* reference to the Cryptographic Token Interface defined in the PKCS #11
* standard. An implementation of Cryptoki is referred to as a
/* We will use the terminology as defined in the standard, Cryptoki is in
* reference to the Cryptographic Token Interface defined in the PKCS #11
* standard. An implementation of Cryptoki is referred to as a
* "Cryptoki library". */
configPRINTF( ( "\r\nStarting PKCS #11 Management and Random Number Generation" \
" Demo.\r\n" ) );
" Demo.\r\n" ) );
/* CK_RV is the return type for a Cryptoki function. Generally the underlying
* type is a CK_ULONG, it can also be a CKR_VENDOR_DEFINED type. */
CK_RV xResult = CKR_OK;
/* The CK_FUNCTION_LIST is a structure that contains the Cryptoki version
* and a function pointer to each function in the Cryptoki API. If the
* and a function pointer to each function in the Cryptoki API. If the
* function pointer is NULL it is unimplemented. */
CK_FUNCTION_LIST_PTR pxFunctionList = NULL;
@@ -75,22 +75,22 @@ void vPKCS11ManagementAndRNGDemo( void )
* function pointers for mutex operations. */
CK_C_INITIALIZE_ARGS xInitArgs = { 0 };
/* A slot ID is an integer that defines a slot. The Cryptoki definition of
* a slot is "A logical reader that potentially contains a token."
/* A slot ID is an integer that defines a slot. The Cryptoki definition of
* a slot is "A logical reader that potentially contains a token."
*
* Essentially it is an abstraction for accessing the token. The reason for
* this is Some tokens are a physical "card' that needs to be inserted into
* a slot for the device to read.
* Essentially it is an abstraction for accessing the token. The reason for
* this is Some tokens are a physical "card' that needs to be inserted into
* a slot for the device to read.
*
* A concrete example of a slot could be a USB Hardware Security Module (HSM),
* which generally appears as a singular slot, and abstracts it's internal "token".
* A concrete example of a slot could be a USB Hardware Security Module (HSM),
* which generally appears as a singular slot, and abstracts it's internal "token".
*
* Some implementations have multiple slots mapped to a single token, or maps
* a slot per token. */
CK_SLOT_ID * pxSlotId = NULL;
/* A session is defined to be "The logical connection between an application
* and a token."
* and a token."
*
* The session can either be private or public, and differentiates
* your application from the other users of the token. */
@@ -102,7 +102,7 @@ void vPKCS11ManagementAndRNGDemo( void )
CK_ULONG xSlotCount = 0;
/* We use the function list returned by C_GetFunctionList to see what functions
* the Cryptoki library supports. We use asserts to ensure that all the
* the Cryptoki library supports. We use asserts to ensure that all the
* functionality needed in this demo is available. */
xResult = C_GetFunctionList( &pxFunctionList );
configASSERT( xResult == CKR_OK );
@@ -115,20 +115,20 @@ void vPKCS11ManagementAndRNGDemo( void )
configASSERT( pxFunctionList->C_CloseSession != NULL );
configASSERT( pxFunctionList->C_Finalize != NULL );
configPRINTF( ( "Cryptoki Major Version: %lu Minor Version %lu\r\n",
pxFunctionList->version.major,
configPRINTF( ( "Cryptoki Major Version: %lu Minor Version %lu\r\n",
pxFunctionList->version.major,
pxFunctionList->version.minor ) );
/* C_Initialize will initialize the Cryptoki library and the hardware it
/* C_Initialize will initialize the Cryptoki library and the hardware it
* abstracts. */
xResult = pxFunctionList->C_Initialize( &xInitArgs );
configASSERT( xResult == CKR_OK );
/* C_GetSlotList will retrieve an array of CK_SLOT_IDs.
* This Cryptoki library does not implement slots, but it is important to
/* C_GetSlotList will retrieve an array of CK_SLOT_IDs.
* This Cryptoki library does not implement slots, but it is important to
* highlight how Cryptoki can be used to interface with real hardware.
*
* By setting the first argument "tokenPresent" to true, we only retrieve
* By setting the first argument "tokenPresent" to true, we only retrieve
* slots that have a token. If the second argument "pSlotList" is NULL, the
* third argument "pulCount" will be modified to contain the total slots. */
xResult = pxFunctionList->C_GetSlotList( CK_TRUE,
@@ -136,13 +136,13 @@ void vPKCS11ManagementAndRNGDemo( void )
&xSlotCount );
configASSERT( xResult == CKR_OK );
/* Since C_GetSlotList does not allocate the memory itself for getting a list
* of CK_SLOT_ID, we allocate one for it to populate with the list of
/* Since C_GetSlotList does not allocate the memory itself for getting a list
* of CK_SLOT_ID, we allocate one for it to populate with the list of
* slot ids. */
pxSlotId = pvPortMalloc( sizeof( CK_SLOT_ID ) * ( xSlotCount ) );
configASSERT( pxSlotId != NULL );
/* Now since pSlotList is not NULL, C_GetSlotList will populate it with the
/* Now since pSlotList is not NULL, C_GetSlotList will populate it with the
* available slots. */
xResult = pxFunctionList->C_GetSlotList( CK_TRUE,
pxSlotId,
@@ -154,12 +154,12 @@ void vPKCS11ManagementAndRNGDemo( void )
* Cryptoki.
*
* C_OpenSession will establish a session between the application and
* the token and we can then use the returned CK_SESSION_HANDLE for
* cryptographic operations with the token.
* the token and we can then use the returned CK_SESSION_HANDLE for
* cryptographic operations with the token.
*
* For legacy reasons, Cryptoki demands that the CKF_SERIAL_SESSION bit
* For legacy reasons, Cryptoki demands that the CKF_SERIAL_SESSION bit
* is always set. */
xResult = pxFunctionList->C_OpenSession( pxSlotId[0],
xResult = pxFunctionList->C_OpenSession( pxSlotId[ 0 ],
CKF_SERIAL_SESSION | CKF_RW_SESSION,
NULL, /* Application defined pointer. */
NULL, /* Callback function. */
@@ -167,11 +167,11 @@ void vPKCS11ManagementAndRNGDemo( void )
configASSERT( xResult == CKR_OK );
/* C_Login is called to log the user in to the token. The login status is
/* C_Login is called to log the user in to the token. The login status is
* shared between sessions, so logging in once is sufficient for all the sessions
* tied to the token. Most of the behavior for C_Login is defined by the token
* so it may be necessary to modify calls to C_Login when switching to a different
* Cryptoki library or token.
* Cryptoki library or token.
*
* This Cryptoki library does not implement C_Login, and only defines the function
* for compatibility reasons.
@@ -183,7 +183,7 @@ void vPKCS11ManagementAndRNGDemo( void )
configASSERT( xResult == CKR_OK );
/* C_GenerateRandom generates random or pseudo random data. As arguments it
* takes the application session, and a pointer to a byte buffer, as well as
* takes the application session, and a pointer to a byte buffer, as well as
* the length of the byte buffer. Then it will fill this buffer with random
* bytes. */
xResult = pxFunctionList->C_GenerateRandom( hSession,
@@ -196,7 +196,6 @@ void vPKCS11ManagementAndRNGDemo( void )
configPRINTF( ( "Generated random number: %x\r\n", xRandomData[ ulIndex ] ) );
}
/* C_CloseSession closes the session that was established between the
* application and the token. This will clean up the resources that maintained
* the link between the application and the token. If the application wishes
@@ -207,15 +206,15 @@ void vPKCS11ManagementAndRNGDemo( void )
/* C_Finalize signals to the Cryptoki library that the application is done
* using it. It should always be the last call to the Cryptoki library.
* NULL should always be passed as the argument, as the parameter is currently
* just reserved for future revisions.
*
* Calling this function in a multi threaded environment can lead to undefined
* just reserved for future revisions.
*
* Calling this function in a multi threaded environment can lead to undefined
* behavior if other threads are accessing the Cryptoki library. */
xResult = pxFunctionList->C_Finalize( NULL );
configASSERT( xResult == CKR_OK );
configPRINTF( ( "Finished PKCS #11 Management and Random Number Generation" \
" Demo.\r\n" ) );
" Demo.\r\n" ) );
vPortFree( pxSlotId );
}

View File

@@ -78,7 +78,7 @@ void vPKCS11MechanismsAndDigestDemo( void )
CK_MECHANISM_TYPE xMechanismType = 0;
/* This variable is not directly used, but is instantiated for demonstration
* purposes.
* purposes.
*/
( void ) xMechanismType;
@@ -252,9 +252,9 @@ void vPKCS11MechanismsAndDigestDemo( void )
{
configPRINTF( ( "%x", xDigestResult[ ulIndex ] ) );
}
configPRINTF( ( "\r\n" ) );
configPRINTF( ( "Finished PKCS #11 Mechanisms and Digest Demo.\r\n" ) );
vEnd( hSession, pxSlotId );
}

View File

@@ -50,7 +50,7 @@
*/
#define pkcs11demo_RSA_CERTIFICATE \
"" \
"-----BEGIN CERTIFICATE-----\n" \
"-----BEGIN CERTIFICATE-----\n" \
"MIIFgTCCA2mgAwIBAgIUPsOLvI1VI8EtdIZi1s2vp7sGhy8wDQYJKoZIhvcNAQEL\n" \
"BQAwTzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxl\n" \
"MSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwIBcNMjAwNzEzMTY0\n" \
@@ -80,12 +80,12 @@
"97LLfATEYy5ajjlWoJ8qF/in8jzsYxq9OZ2/ObchZsU9ybzLRuE1Cv7v4Mx1sgH3\n" \
"EoWYZK1j3WytKmbaWYDR6INYklT/d+14OyIflUfBGiSXNKMITWVRZYjTHKUeAPdb\n" \
"1bsyMu+g4y1PVOrp/d9AyZTZrDW81zuYpO5Ah0DgF4EYiz2fWnz2ITVUmq35znIQ\n" \
"xg07nhvDeydwB48xXrPQ1KutrRyh\n" \
"xg07nhvDeydwB48xXrPQ1KutrRyh\n" \
"-----END CERTIFICATE-----"
/* This function can be found in
/* This function can be found in
* FreeRTOS/FreeRTOS-Plus/Source/FreeRTOS-Plus-PKCS11/3rdparty/mbedtls_utils/mbedtls_utils.c.
* It will be used to convert the RSA certificate from PEM format
* It will be used to convert the RSA certificate from PEM format
* to DER format. */
extern int convert_pem_to_der( const unsigned char * pucInput,
size_t xLen,
@@ -160,11 +160,11 @@ static void prvObjectImporting( void )
PKCS11_CertificateTemplate_t xCertificateTemplate;
/* The object class is specified as a certificate to help the Cryptoki library
* parse the arguments.
* parse the arguments.
*/
CK_OBJECT_CLASS xCertificateClass = CKO_CERTIFICATE;
/* The certificate type is an x509 certificate, which is the only type
/* The certificate type is an x509 certificate, which is the only type
* supported by this stack. To read more about x509 certificates one can
* read the following:
*
@@ -174,7 +174,7 @@ static void prvObjectImporting( void )
*/
CK_CERTIFICATE_TYPE xCertificateType = CKC_X_509;
/* The label will help the application identify which object it would like
/* The label will help the application identify which object it would like
* to access.
*/
CK_BYTE pucLabel[] = pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS;
@@ -193,12 +193,12 @@ static void prvObjectImporting( void )
xCertificateTemplate.xValue.type = CKA_VALUE;
xCertificateTemplate.xValue.pValue = ( CK_VOID_PTR ) pkcs11demo_RSA_CERTIFICATE;
xCertificateTemplate.xValue.ulValueLen = ( CK_ULONG ) sizeof( pkcs11demo_RSA_CERTIFICATE ) - 1UL;
/* Specify certificate label. */
xCertificateTemplate.xLabel.type = CKA_LABEL;
xCertificateTemplate.xLabel.pValue = ( CK_VOID_PTR ) pucLabel;
xCertificateTemplate.xLabel.ulValueLen = sizeof( pucLabel ) - 1UL;
/* Specify certificate type as x509. */
xCertificateTemplate.xCertificateType.type = CKA_CERTIFICATE_TYPE;
xCertificateTemplate.xCertificateType.pValue = &xCertificateType;
@@ -236,7 +236,7 @@ static void prvObjectImporting( void )
/* Create an object using the encoded client certificate. */
configPRINTF( ( "Creating x509 certificate with label: %s \r\n",
pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS ) );
pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS ) );
/* Once the Cryptoki library has finished importing the new x509 certificate
* a CK_OBJECT_HANDLE is associated with it. The application can now use this
@@ -332,10 +332,10 @@ static void prvObjectGeneration( void )
*/
CK_ATTRIBUTE xPublicKeyTemplate[] =
{
{ CKA_KEY_TYPE, &xKeyType, sizeof( xKeyType ) },
{ CKA_VERIFY, &xTrue, sizeof( xTrue ) },
{ CKA_EC_PARAMS, xEcParams, sizeof( xEcParams ) },
{ CKA_LABEL, pucPublicKeyLabel, sizeof( pucPublicKeyLabel ) - 1 }
{ CKA_KEY_TYPE, &xKeyType, sizeof( xKeyType ) },
{ CKA_VERIFY, &xTrue, sizeof( xTrue ) },
{ CKA_EC_PARAMS, xEcParams, sizeof( xEcParams ) },
{ CKA_LABEL, pucPublicKeyLabel, sizeof( pucPublicKeyLabel ) - 1 }
};
/* In the below template we are creating a private key:

View File

@@ -42,22 +42,22 @@
#include "pkcs11_demos.h"
/**
* This function details how to use the PKCS #11 "Sign and Verify" functions to
* This function details how to use the PKCS #11 "Sign and Verify" functions to
* create and interact with digital signatures.
* The functions described are all defined in
* http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html
* The functions described are all defined in
* http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html
* please consult the standard for more information regarding these functions.
*
* The standard has grouped the functions presented in this demo as:
* Object Management Functions
* Signing and MACing Functions
* Signing and MACing Functions
*/
void vPKCS11SignVerifyDemo( void )
{
/* This demo will use the generated private and public key from the
* "objects.c" demo and use them to sign and verify the integrity of a
/* This demo will use the generated private and public key from the
* "objects.c" demo and use them to sign and verify the integrity of a
* message digest. This demo will use concepts from all the other demos,
* and is recommended be done last.
* and is recommended be done last.
*
* The intention of this demo is how to use PKCS #11's Crypotki API to do
* these signature operations, not to explain when and why they should be
@@ -90,11 +90,12 @@ void vPKCS11SignVerifyDemo( void )
/* The ECDSA mechanism will be used to sign the message digest. */
CK_MECHANISM xMechanism = { CKM_ECDSA, NULL, 0 };
/* This signature buffer will be used to store the signature created by the
/* This signature buffer will be used to store the signature created by the
* private key. (64 bytes). We pad it with an extra 8 bytes so it can be
* converted to an ASN.1 encoding. */
CK_BYTE xSignature[ pkcs11ECDSA_P256_SIGNATURE_LENGTH + 8 ] = { 0 };
CK_ULONG xSignatureLength = sizeof( xSignature );
CK_ULONG ulSignatureLength = sizeof( xSignature );
size_t xSignatureLength = 0U;
/* Ensure the Cryptoki library has the necessary functions implemented. */
xResult = C_GetFunctionList( &pxFunctionList );
@@ -108,32 +109,32 @@ void vPKCS11SignVerifyDemo( void )
configASSERT( pxFunctionList->C_InitToken != NULL );
configASSERT( pxFunctionList->C_GetTokenInfo != NULL );
/* Instead of using the vStart helper, we will use the "core_pkcs11.h"
* functions that help wrap around some common PKCS #11 use cases.
/* Instead of using the vStart helper, we will use the "core_pkcs11.h"
* functions that help wrap around some common PKCS #11 use cases.
*
* This function will:
* Initialize the PKCS #11 module if it is not already.
* Initialize a PKCS #11 session.
* Initialize a PKCS #11 session.
*/
xResult = xInitializePkcs11Session( &hSession );
xResult = xInitializePkcs11Session( &hSession );
configASSERT( xResult == CKR_OK );
configASSERT( hSession != CK_INVALID_HANDLE );
/* This function will:
* Initialize the PKCS #11 module if it is not already.
* Initialize the token to be used.
* Initialize the token to be used.
*
* Note: By default this function will always initialize the token in the
* Note: By default this function will always initialize the token in the
* first slot in the slot list. If it desired to use a different slot, it
* is necessary to modify the implementation of this function to use a
* is necessary to modify the implementation of this function to use a
* different slot. */
xResult = xInitializePkcs11Token();
xResult = xInitializePkcs11Token();
configASSERT( xResult == CKR_OK );
/* This function will:
* Query the Cryptoki library for the total number of slots. Malloc an array
* of slots. Then the pxSlotId and ulSlotCount variables will be updated to
* point to the slot array, and the total slot count.
* of slots. Then the pxSlotId and ulSlotCount variables will be updated to
* point to the slot array, and the total slot count.
*/
xResult = xGetSlotList( &pxSlotId, &ulSlotCount );
configASSERT( xResult == CKR_OK );
@@ -151,21 +152,21 @@ void vPKCS11SignVerifyDemo( void )
* This will acquire the object handle for the private key created in the
* "objects.c" demo.
*/
xResult = xFindObjectWithLabelAndClass( hSession,
pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS,
sizeof( pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS ) - 1UL,
CKO_PRIVATE_KEY,
&xPrivateKeyHandle );
xResult = xFindObjectWithLabelAndClass( hSession,
pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS,
sizeof( pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS ) - 1UL,
CKO_PRIVATE_KEY,
&xPrivateKeyHandle );
configASSERT( xResult == CKR_OK );
configASSERT( xPrivateKeyHandle != CK_INVALID_HANDLE );
/* Acquire the object handle for the public key created in the "objects.c"
/* Acquire the object handle for the public key created in the "objects.c"
* demo. */
xResult = xFindObjectWithLabelAndClass( hSession,
pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS,
sizeof( pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS ) - 1UL,
CKO_PUBLIC_KEY,
&xPublicKeyHandle );
xResult = xFindObjectWithLabelAndClass( hSession,
pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS,
sizeof( pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS ) - 1UL,
CKO_PUBLIC_KEY,
&xPublicKeyHandle );
configASSERT( xResult == CKR_OK );
configASSERT( xPublicKeyHandle != CK_INVALID_HANDLE );
@@ -185,21 +186,22 @@ void vPKCS11SignVerifyDemo( void )
sizeof( pxKnownMessage ) - 1 );
configASSERT( CKR_OK == xResult );
/* Retrieve the digest buffer length. When passing in a NULL pointer as the
/* Retrieve the digest buffer length. When passing in a NULL pointer as the
* second argument, instead of a point to a buffer, this will signal the
* Cryptoki library to fill the third parameter with the required amount of
* Cryptoki library to fill the third parameter with the required amount of
* bytes to store the resulting digest.
*/
xResult = pxFunctionList->C_DigestFinal( hSession,
NULL,
&ulDigestLength );
configASSERT( CKR_OK == xResult );
/* Since the length of a SHA-256 digest is known, we made an assumption and
* allocated the buffer originally with the known length. Assert to make sure
* we queried the length we expected. */
configASSERT( pkcs11SHA256_DIGEST_LENGTH == ulDigestLength );
/* Now that ulDigestLength contains the required byte length, retrieve the
/* Now that ulDigestLength contains the required byte length, retrieve the
* digest buffer.
*/
xResult = pxFunctionList->C_DigestFinal( hSession,
@@ -209,73 +211,74 @@ void vPKCS11SignVerifyDemo( void )
/********************************* Sign **********************************/
configPRINTF( ( "Signing known message:\r\n %s\r\n",
( char * ) pxKnownMessage ) );
configPRINTF( ( "Signing known message:\r\n %s\r\n",
( char * ) pxKnownMessage ) );
/* Initializes the sign operation and sets what mechanism will be used
* for signing the message digest. Specify what object handle to use for this
* operation, in this case the private key object handle. */
xResult = pxFunctionList->C_SignInit( hSession,
&xMechanism,
xPrivateKeyHandle );
xResult = pxFunctionList->C_SignInit( hSession,
&xMechanism,
xPrivateKeyHandle );
configASSERT( xResult == CKR_OK );
/* Sign the message digest that was created with the C_Digest series of
/* Sign the message digest that was created with the C_Digest series of
* functions. A signature will be created using the private key specified in
* C_SignInit and put in the byte buffer xSignature. */
xResult = pxFunctionList->C_Sign( hSession,
xDigestResult,
pkcs11SHA256_DIGEST_LENGTH,
xSignature,
&xSignatureLength );
xResult = pxFunctionList->C_Sign( hSession,
xDigestResult,
pkcs11SHA256_DIGEST_LENGTH,
xSignature,
&ulSignatureLength );
configASSERT( xResult == CKR_OK );
configASSERT( xSignatureLength == pkcs11ECDSA_P256_SIGNATURE_LENGTH );
configASSERT( ulSignatureLength == pkcs11ECDSA_P256_SIGNATURE_LENGTH );
/********************************* Verify **********************************/
/* Verify the signature created by C_Sign. First we will verify that the
/* Verify the signature created by C_Sign. First we will verify that the
* same Cryptoki library was able to trust itself.
*
* C_VerifyInit will begin the verify operation, by specifying what mechanism
* to use (CKM_ECDSA, the same as the sign operation) and then specifying
* which public key handle to use.
*/
xResult = pxFunctionList->C_VerifyInit( hSession,
&xMechanism,
xPublicKeyHandle );
xResult = pxFunctionList->C_VerifyInit( hSession,
&xMechanism,
xPublicKeyHandle );
configASSERT( xResult == CKR_OK );
/* Given the signature and it's length, the Cryptoki will use the public key
* to verify that the signature was created by the corresponding private key.
* If C_Verify returns CKR_OK, it means that the sender of the message has
* the same private key as the private key that was used to generate the
* public key, and we can trust that the message we received was from that
* to verify that the signature was created by the corresponding private key.
* If C_Verify returns CKR_OK, it means that the sender of the message has
* the same private key as the private key that was used to generate the
* public key, and we can trust that the message we received was from that
* sender.
*
* Note that we are not using the actual message, but the digest that we
* Note that we are not using the actual message, but the digest that we
* created earlier of the message, for the verification.
*/
xResult = pxFunctionList->C_Verify( hSession,
xDigestResult,
pkcs11SHA256_DIGEST_LENGTH,
xSignature,
xSignatureLength );
xResult = pxFunctionList->C_Verify( hSession,
xDigestResult,
pkcs11SHA256_DIGEST_LENGTH,
xSignature,
ulSignatureLength );
if( xResult == CKR_OK )
{
configPRINTF( ( "The signature of the digest was verified with the" \
" public key and can be trusted.\r\n" ) );
" public key and can be trusted.\r\n" ) );
}
else
{
configPRINTF( ( "Unable to verify the signature with the given public" \
" key, the message cannot be trusted.\r\n" ) );
" key, the message cannot be trusted.\r\n" ) );
}
/* Export public key as hex bytes and print the hex representation of the
* public key.
* public key.
*
* We need to export the public key so that it can be used by a different
* We need to export the public key so that it can be used by a different
* device to verify messages signed by the private key of the device that
* generated the key pair.
*
@@ -292,15 +295,15 @@ void vPKCS11SignVerifyDemo( void )
* Copy the below command into the terminal.
* "$ xxd -r -ps DevicePublicKeyAsciiHex.txt DevicePublicKeyDer.bin"
*
* Now that we have the binary encoding of the public key, we will convert
* it to PEM using OpenSSL.
* Now that we have the binary encoding of the public key, we will convert
* it to PEM using OpenSSL.
*
* The following command will create a PEM file of the public key called
* The following command will create a PEM file of the public key called
* "public_key.pem"
*
* "$ openssl ec -inform der -in DevicePublicKeyDer.bin -pubin -pubout -outform pem -out public_key.pem"
*
* Now we can use the extracted public key to verify the signature of the
*
* Now we can use the extracted public key to verify the signature of the
* device's private key.
*
* WARNING: Running the object generation demo will create a new key pair,
@@ -316,21 +319,22 @@ void vPKCS11SignVerifyDemo( void )
pxDerPublicKey,
ulDerPublicKeyLength );
/* This utility function converts the PKCS #11 signature into an ASN.1
* encoded binary der signature. This is necessary so we can export the
/* This utility function converts the PKCS #11 signature into an ASN.1
* encoded binary der signature. This is necessary so we can export the
* signature and verify it with OpenSSL, otherwise OpenSSL will not be able
* to parse the buffer.
*
* See https://en.wikipedia.org/wiki/ASN.1 for more information about the
* See https://en.wikipedia.org/wiki/ASN.1 for more information about the
* ASN.1 encoding format.
*/
PKI_pkcs11SignatureTombedTLSSignature( xSignature, ( size_t * ) &xSignatureLength );
xSignatureLength = ulSignatureLength;
PKI_pkcs11SignatureTombedTLSSignature( xSignature, &xSignatureLength );
/* The following loop will output the signature in hex.
/* The following loop will output the signature in hex.
*
* In order to get the signature exported in binary form copy the output
* of the loop, and paste it to an empty text file.
* of the loop, and paste it to an empty text file.
*
* Then we will need to convert the text file to binary using the xxd tool.
*
@@ -342,29 +346,31 @@ void vPKCS11SignVerifyDemo( void )
* Copy the below command into the terminal.
* "$ xxd -r -ps signature.txt signature.bin"
*
* Next, we need to copy the original message that the Cryptoki library
* signed, the following shell command will create the message without any
* newlines, so the messages are similar.
* Next, we need to copy the original message that the Cryptoki library
* signed, the following shell command will create the message without any
* newlines, so the messages are similar.
*
* The contents of the echo command can be replaced with whatever data was
* The contents of the echo command can be replaced with whatever data was
* in the known message, but the example uses "Hello world" to make it easier
* for copy and pasting.
*
* "$ echo -n "Hello world" > msg.txt"
*
* Now we will use OpenSSL to verify that the signature we created can be
* trusted by another device using the public key we created and then
* Now we will use OpenSSL to verify that the signature we created can be
* trusted by another device using the public key we created and then
* extracted earlier.
*
* "$ openssl dgst -sha256 -verify public_key.pem -signature signature.bin msg.txt"
* This command should output "Verified OK" and we then know we can trust
* This command should output "Verified OK" and we then know we can trust
* the sender of the message!
*/
configPRINTF( ( "Created signature: \r\n" ) );
for( ulIndex = 0; ulIndex < xSignatureLength; ulIndex++ )
for( ulIndex = 0; ulIndex < ulSignatureLength; ulIndex++ )
{
configPRINTF( ( "%02x", xSignature[ ulIndex ] ) );
}
configPRINTF( ( "\r\n" ) );
configPRINTF( ( "Finished PKCS #11 Sign and Verify Demo.\r\n" ) );

View File

@@ -69,6 +69,8 @@ static void prvStartPKCS11Demo( void )
vPKCS11SignVerifyDemo();
#endif
configPRINTF( ( "---------Finished DEMO---------\r\n" ) );
exit( 0 );
}
/*-----------------------------------------------------------*/
@@ -105,14 +107,14 @@ int main( void )
}
/*-----------------------------------------------------------*/
void vLoggingPrintf( const char *pcFormat,
... )
void vLoggingPrintf( const char * pcFormat,
... )
{
va_list arg;
va_list arg;
va_start( arg, pcFormat );
vprintf( pcFormat, arg );
va_end( arg );
va_start( arg, pcFormat );
vprintf( pcFormat, arg );
va_end( arg );
}
/*-----------------------------------------------------------*/

View File

@@ -30,7 +30,7 @@
/*
* @brief this macro defines the stack size for the PKCS #11 demo task.
*/
#define configPKCS11_DEMO_STACK_SIZE 200
#define configPKCS11_DEMO_STACK_SIZE 256
/*
* @brief set this macro to "1" in order to run the PKCS #11 management and
@@ -42,19 +42,19 @@
* @brief set this macro to "1" in order to run the PKCS #11 mechanisms and
* digest demo.
*/
#define configPKCS11_MECHANISMS_AND_DIGESTS_DEMO 0
#define configPKCS11_MECHANISMS_AND_DIGESTS_DEMO 1
/*
* @brief set this macro to "1" in order to run the PKCS #11 object demo.
*/
#define configPKCS11_OBJECT_DEMO 0
#define configPKCS11_OBJECT_DEMO 1
/*
* @brief set this macro to "1" in order to run the PKCS #11 sign and verify
* @brief set this macro to "1" in order to run the PKCS #11 sign and verify
* demo.
*
* @warning This demo relies on the objects created in the object demo.
*/
#define configPKCS11_SIGN_AND_VERIFY_DEMO 0
#define configPKCS11_SIGN_AND_VERIFY_DEMO 1
#endif
#endif /* ifndef _PKCS11_DEMO_CONFIG_ */