Obtains an attribute value of an object.
CK_OBJECT_HANDLE hObject,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount )
{
CK_BBOOL xIsPrivate = ( CK_BBOOL ) CK_TRUE;
CK_ULONG iAttrib;
mbedtls_pk_context xKeyContext = { 0 };
mbedtls_x509_crt xMbedX509Context = { 0 };
mbedtls_pk_type_t xKeyType;
const mbedtls_ecp_keypair * pxKeyPair;
CK_KEY_TYPE xPkcsKeyType = ( CK_KEY_TYPE ) ~0UL;
CK_OBJECT_CLASS xClass = ~0UL;
CK_BYTE_PTR pxObjectValue = NULL;
CK_ULONG ulLength = 0;
int32_t lMbedTLSResult = 0;
CK_OBJECT_HANDLE xPalHandle = CK_INVALID_HANDLE;
CK_ULONG xSize = 0;
size_t xMbedSize = 0;
CK_BYTE_PTR pcLabel = NULL;
if( ( CKR_OK == xResult ) && ( ( ( NULL == pTemplate ) ) || ( 0UL == ulCount ) ) )
{
LogError( (
"Failed to get attribute. The template was a NULL pointer "
"or the attribute count was 0." ) );
xResult = CKR_ARGUMENTS_BAD;
}
if( ( CKR_OK == xResult ) && ( CK_INVALID_HANDLE == hObject ) )
{
LogError( (
"Failed to get attribute. The object handle was invalid." ) );
xResult = CKR_OBJECT_HANDLE_INVALID;
}
if( xResult == CKR_OK )
{
if( xPalHandle != CK_INVALID_HANDLE )
{
}
else
{
LogError( (
"Failed to get attribute. Could not find a valid "
"PKCS #11 PAL handle." ) );
xResult = CKR_OBJECT_HANDLE_INVALID;
}
}
if( xResult == CKR_OK )
{
mbedtls_pk_init( &xKeyContext );
mbedtls_x509_crt_init( &xMbedX509Context );
#if MBEDTLS_VERSION_NUMBER < 0x03000000
lMbedTLSResult = mbedtls_pk_parse_key( &xKeyContext,
pxObjectValue, ulLength,
NULL, 0 );
#else
lMbedTLSResult = mbedtls_pk_parse_key( &xKeyContext,
pxObjectValue, ulLength,
NULL, 0,
#endif
if( lMbedTLSResult == 0 )
{
if( xIsPrivate == ( CK_BBOOL ) CK_TRUE )
{
LogDebug( (
"Object was a private key." ) );
xClass = CKO_PRIVATE_KEY;
}
else
{
LogDebug( (
"Object was a public key." ) );
xClass = CKO_PUBLIC_KEY;
}
}
else if( 0 == mbedtls_pk_parse_public_key( &xKeyContext, pxObjectValue, ulLength ) )
{
LogDebug( (
"Object was a public key." ) );
xClass = CKO_PUBLIC_KEY;
}
else if( 0 == mbedtls_x509_crt_parse( &xMbedX509Context, pxObjectValue, ulLength ) )
{
LogDebug( (
"Object was a certificate." ) );
xClass = CKO_CERTIFICATE;
}
else
{
LogDebug( (
"Object handle was invalid." ) );
xResult = CKR_OBJECT_HANDLE_INVALID;
}
}
if( xResult == CKR_OK )
{
for( iAttrib = 0; iAttrib < ulCount; iAttrib++ )
{
if( xResult != CKR_OK )
{
break;
}
switch( pTemplate[ iAttrib ].type )
{
case CKA_CLASS:
if( pTemplate[ iAttrib ].pValue == NULL )
{
pTemplate[ iAttrib ].ulValueLen = sizeof( CK_OBJECT_CLASS );
}
else
{
if( pTemplate[ iAttrib ].ulValueLen == sizeof( CK_OBJECT_CLASS ) )
{
( void ) memcpy( pTemplate[ iAttrib ].pValue, &xClass, sizeof( CK_OBJECT_CLASS ) );
}
else
{
LogError( (
"Failed to parse attribute template. "
"Received a buffer smaller than CK_OBJECT_CLASS." ) );
xResult = CKR_BUFFER_TOO_SMALL;
}
}
break;
case CKA_PUBLIC_KEY_INFO:
case CKA_VALUE:
if( xIsPrivate == ( CK_BBOOL ) CK_TRUE )
{
pTemplate[ iAttrib ].ulValueLen = CK_UNAVAILABLE_INFORMATION;
LogError( (
"Failed to parse attribute. This data is "
"sensitive and the value will not be returned." ) );
xResult = CKR_ATTRIBUTE_SENSITIVE;
}
else
{
if( pTemplate[ iAttrib ].pValue == NULL )
{
pTemplate[ iAttrib ].ulValueLen = ulLength;
}
else if( pTemplate[ iAttrib ].ulValueLen < ulLength )
{
LogError( (
"Failed to parse attribute. Buffer was "
"too small to contain data. Expected %lu "
"but got %lu.",
( unsigned long int ) ulLength,
( unsigned long int ) pTemplate[ iAttrib ].ulValueLen ) );
xResult = CKR_BUFFER_TOO_SMALL;
}
else
{
( void ) memcpy( pTemplate[ iAttrib ].pValue, pxObjectValue, ulLength );
}
}
break;
case CKA_KEY_TYPE:
if( pTemplate[ iAttrib ].pValue == NULL )
{
pTemplate[ iAttrib ].ulValueLen = sizeof( CK_KEY_TYPE );
}
else if( pTemplate[ iAttrib ].ulValueLen < sizeof( CK_KEY_TYPE ) )
{
LogError( (
"Failed to parse attribute. Expected buffer "
"of size CK_KEY_TYPE." ) );
xResult = CKR_BUFFER_TOO_SMALL;
}
else
{
xKeyType = mbedtls_pk_get_type( &xKeyContext );
switch( xKeyType )
{
case MBEDTLS_PK_RSA:
case MBEDTLS_PK_RSA_ALT:
case MBEDTLS_PK_RSASSA_PSS:
xPkcsKeyType = CKK_RSA;
break;
case MBEDTLS_PK_ECKEY:
case MBEDTLS_PK_ECKEY_DH:
xPkcsKeyType = CKK_EC;
break;
case MBEDTLS_PK_ECDSA:
xPkcsKeyType = CKK_ECDSA;
break;
default:
LogError( (
"Failed to parse attribute. "
"Could not parse key type." ) );
xResult = CKR_ATTRIBUTE_VALUE_INVALID;
break;
}
( void ) memcpy( pTemplate[ iAttrib ].pValue, &xPkcsKeyType, sizeof( CK_KEY_TYPE ) );
}
break;
case CKA_PRIVATE_EXPONENT:
LogError( (
"Failed to parse attribute. "
"CKA_PRIVATE_EXPONENT is private data." ) );
xResult = CKR_ATTRIBUTE_SENSITIVE;
break;
case CKA_EC_PARAMS:
if( pTemplate[ iAttrib ].pValue == NULL )
{
pTemplate[ iAttrib ].ulValueLen = sizeof( ucP256Oid );
}
else
{
if( pTemplate[ iAttrib ].ulValueLen < sizeof( ucP256Oid ) )
{
LogError( (
"Failed to parse attribute. "
"CKA_EC_PARAMS buffer too small." ) );
xResult = CKR_BUFFER_TOO_SMALL;
}
else
{
( void ) memcpy( pTemplate[ iAttrib ].pValue, ucP256Oid, sizeof( ucP256Oid ) );
}
}
break;
case CKA_EC_POINT:
if( pTemplate[ iAttrib ].pValue == NULL )
{
}
else
{
{
pxKeyPair = ( mbedtls_ecp_keypair * ) xKeyContext.pk_ctx;
*( ( uint8_t * ) pTemplate[ iAttrib ].pValue ) = 0x04;
xMbedSize = xSize;
lMbedTLSResult = mbedtls_ecp_tls_write_point( &pxKeyPair->grp,
&pxKeyPair->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&xMbedSize,
( uint8_t * ) pTemplate[ iAttrib ].pValue + 1,
pTemplate[ iAttrib ].ulValueLen - 1UL );
xSize = xMbedSize;
}
else
{
xResult = CKR_BUFFER_TOO_SMALL;
}
if( ( xResult == CKR_OK ) && ( lMbedTLSResult < 0 ) )
{
if( lMbedTLSResult == MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL )
{
LogError( (
"Failed to extract EC point. "
"CKA_EC_POINT buffer was too small." ) );
xResult = CKR_BUFFER_TOO_SMALL;
}
else
{
LogError( (
"Failed to extract EC point. "
"mbedtls_ecp_tls_write_point failed: "
"mbed TLS error = %s : %s.",
xResult = CKR_FUNCTION_FAILED;
}
}
else
{
pTemplate[ iAttrib ].ulValueLen = xSize + 1UL;
}
}
break;
default:
LogError( (
"Failed to parse attribute. Received unknown "
"attribute type." ) );
xResult = CKR_ATTRIBUTE_TYPE_INVALID;
break;
}
}
mbedtls_pk_free( &xKeyContext );
mbedtls_x509_crt_free( &xMbedX509Context );
}
return xResult;
}
#define CK_DECLARE_FUNCTION(returnType, name)
Macro for defining a PKCS #11 functions.
Definition: core_pkcs11.h:77
#define pkcs11DER_ENCODED_OID_P256
OID for curve P-256.
Definition: core_pkcs11.h:164
#define LogError(message)
Macro that is called in the corePKCS11 library for logging "Error" level messages.
Definition: core_pkcs11_config_defaults.h:317
#define LogDebug(message)
Macro that is called in the corePKCS11 library for logging "Debug" level messages.
Definition: core_pkcs11_config_defaults.h:377
#define mbedtlsLowLevelCodeOrDefault(mbedTlsCode)
Utility for converting the level-level code in an mbedTLS error to string, if the code-contains a lev...
Definition: core_pkcs11_mbedtls.c:96
static P11Struct_t xP11Context
The global PKCS #11 module object. Entropy/randomness and object lists are shared across PKCS #11 ses...
Definition: core_pkcs11_mbedtls.c:326
static P11Session_t * prvSessionPointerFromHandle(CK_SESSION_HANDLE xSession)
Maps an opaque caller session handle into its internal state structure.
Definition: core_pkcs11_mbedtls.c:382
#define mbedtlsHighLevelCodeOrDefault(mbedTlsCode)
Utility for converting the high-level code in an mbedTLS error to string, if the code-contains a high...
Definition: core_pkcs11_mbedtls.c:88
CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
Obtains an attribute value of an object.
Definition: core_pkcs11_mbedtls.c:3031
static void prvFindObjectInListByHandle(CK_OBJECT_HANDLE xAppHandle, CK_OBJECT_HANDLE_PTR pxPalHandle, CK_BYTE_PTR *ppcLabel, CK_ULONG_PTR pxLabelLength)
Looks up a PKCS #11 object's label and PAL handle given an application handle.
Definition: core_pkcs11_mbedtls.c:1112
static CK_RV prvCheckValidSessionAndModule(const P11Session_t *pxSession)
Helper to check if the current session is initialized and valid.
Definition: core_pkcs11_mbedtls.c:336
CK_RV PKCS11_PAL_GetObjectValue(CK_OBJECT_HANDLE xHandle, CK_BYTE_PTR *ppucData, CK_ULONG_PTR pulDataSize, CK_BBOOL *pIsPrivate)
Gets the value of an object in storage, by handle.
void PKCS11_PAL_GetObjectValueCleanup(CK_BYTE_PTR pucData, CK_ULONG ulDataSize)
Cleanup after PKCS11_GetObjectValue().
#define pkcs11EC_POINT_LENGTH
Length of bytes to contain an EC point.
Definition: core_pkcs11_mbedtls.c:171
Session structure.
Definition: core_pkcs11_mbedtls.c:299
mbedtls_ctr_drbg_context xMbedDrbgCtx
CTR-DRBG context for PKCS #11 module - used to generate pseudo-random numbers.
Definition: core_pkcs11_mbedtls.c:286