mirror of
https://github.com/FreeRTOS/FreeRTOS.git
synced 2026-08-09 14:43:56 +00:00
Update corePKCS11 demo code and auto-format
This commit is contained in:
2
FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/.gitignore
vendored
Normal file
2
FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
corePKCS11_*.dat
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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" ) );
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
Reference in New Issue
Block a user