Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Commit

Permalink
Improve compliance with the PKCS #11 standard by testing interoperabi…
Browse files Browse the repository at this point in the history
  • Loading branch information
dcgaws committed Dec 19, 2018
1 parent 95ed74a commit 484663e
Show file tree
Hide file tree
Showing 20 changed files with 3,845 additions and 2,702 deletions.
558 changes: 352 additions & 206 deletions demos/common/devmode_key_provisioning/aws_dev_mode_key_provisioning.c

Large diffs are not rendered by default.

57 changes: 49 additions & 8 deletions lib/include/aws_pkcs11.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,6 @@
*/
#define pcks11SHA256_DIGEST_LENGTH 32

/**
* @brief Certificate type definitions.
*/
#define pkcs11CERTIFICATE_TYPE_USER 1
#define pkcs11CERTIFICATE_TYPE_ROOT 2

/**
* @brief Elliptic-curve object identifiers.
* From https://tools.ietf.org/html/rfc6637#section-11.
Expand All @@ -82,13 +76,43 @@ typedef struct PKCS11_KeyTemplate
CK_ATTRIBUTE xValue;
} PKCS11_KeyTemplate_t, * PKCS11_KeyTemplatePtr_t;

/* Elliptic Curve Private Key Template
* The object class must be the first attribute in the array.
* https://www.cryptsoft.com/pkcs11doc/v220/group__SEC__12__3__4__ELLIPTIC__CURVE__PRIVATE__KEY__OBJECTS.html */
typedef struct PKCS11_PrivateEcKeyTemplate
{
CK_ATTRIBUTE xObjectClass;
CK_ATTRIBUTE xKeyType;
CK_ATTRIBUTE xLabel;
CK_ATTRIBUTE xEcParams;
CK_ATTRIBUTE xEcPoint;
CK_ATTRIBUTE xTokenObject;
} PKCS11_PrivateEcKeyTemplate_t, * PKCS11_PrivateEcKeyTemplatePtr_t;

/* RSA Private Key Template
* The object class must be the first attribute in the array.
* https://www.cryptsoft.com/pkcs11doc/v220/group__SEC__12__1__3__RSA__PRIVATE__KEY__OBJECTS.html */
typedef struct PKCS11_PrivateRsaKeyTemplate
{
CK_ATTRIBUTE xObjectClass;
CK_ATTRIBUTE xKeyType;
CK_ATTRIBUTE xLabel;
CK_ATTRIBUTE xModulus;
CK_ATTRIBUTE xPrivateExponent;
CK_ATTRIBUTE xPublicExponent;
CK_ATTRIBUTE xTokenObject;
} PKCS11_PrivateRsaKeyTemplate_t, * PKCS11_PrivateRsaKeyTemplatePtr_t;

/* Certificate Template */
/* The object class must be the first attribute in the array. */
typedef struct PKCS11_CertificateTemplate
{
CK_ATTRIBUTE xObjectClass;
CK_ATTRIBUTE xObjectClass; /* required certificate attribute. */
CK_ATTRIBUTE xSubject; /* required certificate attribute. */
CK_ATTRIBUTE xCertificateType; /* required certificate attribute. */
CK_ATTRIBUTE xValue; /* required certificate attribute. */
CK_ATTRIBUTE xLabel;
CK_ATTRIBUTE xValue;
CK_ATTRIBUTE xTokenObject;
} PKCS11_CertificateTemplate_t, * PKCS11_CertificateTemplatePtr_t;


Expand All @@ -113,4 +137,21 @@ typedef struct PKCS11_GenerateKeyPrivateTemplate

#define pkcs11INVALID_OBJECT_HANDLE 0


/* \brief Initializes the PKCS #11 module and opens a session.
*
* \param[out] pxSession Pointer to the PKCS #11 session handle
* that is created by this function.
*
* \return CKR_OK upon success. PKCS #11 error code on failure.
* Note that PKCS #11 error codes are positive.
*/
CK_RV xInitializePkcs11Session( CK_SESSION_HANDLE * pxSession );


CK_RV xFindObjectWithLabel( CK_SESSION_HANDLE xSession,
const char * pcLabelName,
CK_OBJECT_HANDLE_PTR pxHandle );


#endif /* ifndef _AWS_PKCS11_H_ */
38 changes: 38 additions & 0 deletions lib/include/aws_pki_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Amazon FreeRTOS
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://aws.amazon.com/freertos
* http://www.FreeRTOS.org
*/

#ifndef _AWS_PKI_UTILS_H_
#define _AWS_PKI_UTILS_H_

int PKI_ConvertPEMToDER( const unsigned char *input,
size_t ilen,
unsigned char *output,
size_t *olen );

int PKI_RSA_RSASSA_PKCS1_v15_Encode( const unsigned char *hash,
size_t dst_len,
unsigned char *dst );

#endif
181 changes: 181 additions & 0 deletions lib/pkcs11/aws_pkcs11.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
#include "aws_pkcs11.h"
#include "aws_pkcs11_config.h"
#include "FreeRTOS.h"

/* mbedTLS includes. */
#include "mbedtls/pk.h"

/* C runtime includes. */
#include <stdio.h>
#include <stdint.h>

/*-----------------------------------------------------------*/

/* @brief Get a list of available PKCS #11 slots.
*
* \note This function allocates memory for slots.
* Freeing this memory is the responsibility of the caller.
*
* \param[out] ppxSlotId Pointer to slot list. This slot list is
* malloc'ed by the function and must be
* freed by the caller.
* \param[out] pxSlotCount Pointer to the number of slots found.
*
* \return CKR_OK or PKCS #11 error code. (PKCS #11 error codes are positive).
*
*/
CK_RV prvGetSlotList( CK_SLOT_ID ** ppxSlotId,
CK_ULONG * pxSlotCount )
{
CK_RV xResult;
CK_FUNCTION_LIST_PTR pxFunctionList;
CK_SLOT_ID * pxSlotId;

xResult = C_GetFunctionList( &pxFunctionList );

if( xResult == CKR_OK )
{
xResult = pxFunctionList->C_GetSlotList( CK_TRUE, /* Token Present. */
NULL, /* We just want to know how many slots there are. */
pxSlotCount );
}

if( xResult == CKR_OK )
{
/* Allocate memory for the slot list. */
pxSlotId = pvPortMalloc( sizeof( CK_SLOT_ID ) * ( *pxSlotCount ) );
*ppxSlotId = pxSlotId;

if( *ppxSlotId == NULL )
{
xResult = CKR_HOST_MEMORY;
}
}

if( xResult == CKR_OK )
{
xResult = pxFunctionList->C_GetSlotList( CK_TRUE, pxSlotId, pxSlotCount );
}

if( xResult != CKR_OK )
{
vPortFree( pxSlotId );
}

return xResult;
}

/*-----------------------------------------------------------*/

/* @brief Open a PKCS #11 Session.
*
* \param[out] pxSession Pointer to the session handle to be created.
* \param[out] xSlotId Slot ID to be used for the session.
*
* \return CKR_OK or PKCS #11 error code. (PKCS #11 error codes are positive).
*/
CK_RV prvOpenSession( CK_SESSION_HANDLE * pxSession,
CK_SLOT_ID xSlotId )
{
CK_RV xResult;
CK_FUNCTION_LIST_PTR pxFunctionList;

xResult = C_GetFunctionList( &pxFunctionList );

if( xResult == CKR_OK )
{
xResult = pxFunctionList->C_OpenSession( xSlotId,
CKF_SERIAL_SESSION | CKF_RW_SESSION,
NULL, /* Application defined pointer. */
NULL, /* Callback function. */
pxSession );
}

return xResult;
}

/*-----------------------------------------------------------*/

CK_RV xInitializePkcs11Session( CK_SESSION_HANDLE * pxSession )
{
CK_RV xResult;
CK_SLOT_ID * pxSlotId;
CK_FUNCTION_LIST_PTR pxFunctionList;
CK_ULONG xSlotCount;

xResult = C_GetFunctionList( &pxFunctionList );

/* Initialize the PKCS #11 module. */
if( xResult == CKR_OK )
{
xResult = pxFunctionList->C_Initialize( NULL );
}

/* Get a list of slots available. */
if( ( xResult == CKR_OK ) || ( xResult == CKR_CRYPTOKI_ALREADY_INITIALIZED ) )
{
xResult = prvGetSlotList( &pxSlotId, &xSlotCount );
}

/* Open a PKCS #11 session. */
if( xResult == CKR_OK )
{
/* We will take the first slot available.
* If your application has multiple slots, insert logic
* for selecting an appropriate slot here.
*/
xResult = prvOpenSession( pxSession, pxSlotId[ 0 ] );

/* Free the memory allocated by prvGetSlotList. */
vPortFree( pxSlotId );
}

xResult = pxFunctionList->C_Login( *pxSession,
CKU_USER,
configPKCS11_DEFAULT_USER_PIN,
sizeof( configPKCS11_DEFAULT_USER_PIN ) - 1 );

return xResult;
}

/*-----------------------------------------------------------*/

CK_RV xFindObjectWithLabel( CK_SESSION_HANDLE xSession,
const char * pcLabelName,
CK_OBJECT_HANDLE_PTR pxHandle )
{
CK_ATTRIBUTE xTemplate;
CK_RV xResult = CKR_OK;
CK_ULONG ulCount = 0;
CK_BBOOL xFindInit = CK_FALSE;
CK_FUNCTION_LIST_PTR pxFunctionList;

xResult = C_GetFunctionList( &pxFunctionList );

/* Get the certificate handle. */
if( 0 == xResult )
{
xTemplate.type = CKA_LABEL;
xTemplate.ulValueLen = strlen( pcLabelName ) + 1;
xTemplate.pValue = ( char * ) pcLabelName;
xResult = pxFunctionList->C_FindObjectsInit( xSession, &xTemplate, 1 );
}

if( 0 == xResult )
{
xFindInit = CK_TRUE;
xResult = pxFunctionList->C_FindObjects( xSession,
pxHandle,
1,
&ulCount );
}

if( CK_TRUE == xFindInit )
{
xResult = pxFunctionList->C_FindObjectsFinal( xSession );
}

return xResult;
}

/*-----------------------------------------------------------*/
14 changes: 14 additions & 0 deletions lib/pkcs11/mbedtls/aws_pkcs11_mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,13 @@ CK_DEFINE_FUNCTION( CK_RV, C_SignInit )( CK_SESSION_HANDLE xSession,

if( xResult == CKR_OK )
{
/* Free the private key context if it exists.
* TODO: Check if the key is the same as was used previously. */
if( NULL != pxSession->xSignKey.pk_ctx )
{
mbedtls_pk_free( &pxSession->xSignKey );
}

mbedtls_pk_init( &pxSession->xSignKey );

if( 0 == mbedtls_pk_parse_key( &pxSession->xSignKey, keyData, ulKeyDataLength, NULL, 0 ) )
Expand Down Expand Up @@ -1341,6 +1348,13 @@ CK_DEFINE_FUNCTION( CK_RV, C_VerifyInit )( CK_SESSION_HANDLE xSession,

if( xResult == CKR_OK )
{
/* Free the public key context if it exists.
* TODO: Check if the key is the same as used by last verify operation. */
if( NULL != pxSession->xVerifyKey.pk_ctx )
{
mbedtls_pk_free( &pxSession->xVerifyKey );
}

mbedtls_pk_init( &pxSession->xVerifyKey );

if( 0 != mbedtls_pk_parse_public_key( &pxSession->xVerifyKey, keyData, ulKeyDataLength ) )
Expand Down
Loading

0 comments on commit 484663e

Please sign in to comment.