FreeRTOS: PKCS11
PKCS11 Cryptoki Library
Return to main page ↑
C_GetAttributeValue

Obtains an attribute value of an object.

CK_DECLARE_FUNCTION( CK_RV, C_GetAttributeValue )( CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount )
{
/* See explanation in prvCheckValidSessionAndModule for this exception. */
/* coverity[misra_c_2012_rule_10_5_violation] */
CK_BBOOL xIsPrivate = ( CK_BBOOL ) CK_TRUE;
CK_ULONG iAttrib;
mbedtls_pk_context xKeyContext = { 0 };
mbedtls_pk_type_t xKeyType;
const mbedtls_ecp_keypair * pxKeyPair;
CK_KEY_TYPE xPkcsKeyType = ( CK_KEY_TYPE ) ~0UL;
CK_OBJECT_CLASS xClass;
CK_BYTE_PTR pxObjectValue = NULL;
CK_ULONG ulLength = 0;
const CK_BYTE ucP256Oid[] = pkcs11DER_ENCODED_OID_P256;
int32_t lMbedTLSResult = 0;
CK_OBJECT_HANDLE xPalHandle = CK_INVALID_HANDLE;
CK_ULONG xSize = 0;
size_t xMbedSize = 0;
CK_BYTE_PTR pcLabel = NULL;
const P11Session_t * pxSession = prvSessionPointerFromHandle( hSession );
CK_RV xResult = prvCheckValidSessionAndModule( pxSession );
if( ( CKR_OK == xResult ) && ( ( ( NULL == pTemplate ) ) || ( 0UL == ulCount ) ) )
{
xResult = CKR_ARGUMENTS_BAD;
}
if( ( CKR_OK == xResult ) && ( CK_INVALID_HANDLE == hObject ) )
{
xResult = CKR_OBJECT_HANDLE_INVALID;
}
if( xResult == CKR_OK )
{
/*
* Copy the object into a buffer.
*/
prvFindObjectInListByHandle( hObject, &xPalHandle, &pcLabel, &xSize ); /*pcLabel and xSize are ignored. */
if( xPalHandle != CK_INVALID_HANDLE )
{
xResult = PKCS11_PAL_GetObjectValue( xPalHandle, &pxObjectValue, &ulLength, &xIsPrivate );
}
else
{
xResult = CKR_OBJECT_HANDLE_INVALID;
}
}
/* Determine what kind of object we are dealing with. */
if( xResult == CKR_OK )
{
/* Is it a key? */
mbedtls_pk_init( &xKeyContext );
if( 0 == mbedtls_pk_parse_key( &xKeyContext, pxObjectValue, ulLength, NULL, 0 ) )
{
/* See explanation in prvCheckValidSessionAndModule for this exception. */
/* coverity[misra_c_2012_rule_10_5_violation] */
if( xIsPrivate == ( CK_BBOOL ) CK_TRUE )
{
xClass = CKO_PRIVATE_KEY;
}
else
{
xClass = CKO_PUBLIC_KEY;
}
}
else if( 0 == mbedtls_pk_parse_public_key( &xKeyContext, pxObjectValue, ulLength ) )
{
xClass = CKO_PUBLIC_KEY;
}
else
{
/* TODO: Do we want to safety parse the cert?
* Assume certificate. */
xClass = CKO_CERTIFICATE;
}
}
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
{
xResult = CKR_BUFFER_TOO_SMALL;
}
}
break;
case CKA_VALUE:
/* See explanation in prvCheckValidSessionAndModule for this exception. */
/* coverity[misra_c_2012_rule_10_5_violation] */
if( xIsPrivate == ( CK_BBOOL ) CK_TRUE )
{
pTemplate[ iAttrib ].ulValueLen = CK_UNAVAILABLE_INFORMATION;
xResult = CKR_ATTRIBUTE_SENSITIVE;
}
else
{
if( pTemplate[ iAttrib ].pValue == NULL )
{
pTemplate[ iAttrib ].ulValueLen = ulLength;
}
else if( pTemplate[ iAttrib ].ulValueLen < ulLength )
{
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 ) )
{
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:
xResult = CKR_ATTRIBUTE_VALUE_INVALID;
break;
}
( void ) memcpy( pTemplate[ iAttrib ].pValue, &xPkcsKeyType, sizeof( CK_KEY_TYPE ) );
}
break;
case CKA_PRIVATE_EXPONENT:
xResult = CKR_ATTRIBUTE_SENSITIVE;
break;
case CKA_EC_PARAMS:
/* TODO: Add check that is key, is ec key. */
pTemplate[ iAttrib ].ulValueLen = sizeof( ucP256Oid );
if( pTemplate[ iAttrib ].pValue != NULL )
{
if( pTemplate[ iAttrib ].ulValueLen < sizeof( ucP256Oid ) )
{
xResult = CKR_BUFFER_TOO_SMALL;
}
else
{
( void ) memcpy( pTemplate[ iAttrib ].pValue, ucP256Oid, sizeof( ucP256Oid ) );
}
}
break;
case CKA_EC_POINT:
if( pTemplate[ iAttrib ].pValue == NULL )
{
pTemplate[ iAttrib ].ulValueLen = 67; /* TODO: Is this large enough?*/
}
else
{
pxKeyPair = ( mbedtls_ecp_keypair * ) xKeyContext.pk_ctx;
*( ( uint8_t * ) pTemplate[ iAttrib ].pValue ) = 0x04; /* Mark the point as uncompressed. */
/* Copy xSize value to avoid casting a CK_ULONG size pointer
* to a size_t sized pointer. */
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;
if( lMbedTLSResult < 0 )
{
if( lMbedTLSResult == MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL )
{
xResult = CKR_BUFFER_TOO_SMALL;
}
else
{
xResult = CKR_FUNCTION_FAILED;
}
}
else
{
pTemplate[ iAttrib ].ulValueLen = xSize + 1UL;
}
}
break;
default:
xResult = CKR_ATTRIBUTE_TYPE_INVALID;
break;
}
}
/* Free the buffer where object was stored. */
PKCS11_PAL_GetObjectValueCleanup( pxObjectValue, ulLength );
/* Free the mbedTLS structure used to parse the key. */
mbedtls_pk_free( &xKeyContext );
}
return xResult;
}
Parameters
[in]hSessionHandle of a valid PKCS #11 session.
[in]hObjectPKCS #11 object handle to be queried.
[in,out]pTemplateAttribute template. pxTemplate.pValue should be set to the attribute to be queried. pxTemplate.ulValueLen should be set to the length of the buffer allocated at pxTemplate.pValue, and will be updated to contain the actual length of the data copied. pxTemplate.pValue should be set to point to a buffer to receive the attribute value data. If parameter length is unknown, pxTemplate.pValue may be set to NULL, and this function will set the required buffer length in pxTemplate.ulValueLen.
[in]ulCountThe number of attributes in the template.
Object Type Queryable Attributes
CertificateCKA_CLASS
CKA_VALUE
EC Private KeyCKA_CLASS
CKA_KEY_TYPE
CKA_EC_PARAMS
EC Public KeyCKA_CLASS
CKA_KEY_TYPE
CKA_EC_PARAMS
CKA_EC_POINT
RSA Private KeyCKA_CLASS
CKA_KEY_TYPE
RSA Public KeyCKA_CLASS
CKA_KEY_TYPE
Returns
CKR_OK if successful. Else, see PKCS #11 specification for more information.
CK_DECLARE_FUNCTION
#define CK_DECLARE_FUNCTION(returnType, name)
Macro for defining a PKCS #11 functions.
Definition: iot_pkcs11.h:66
prvFindObjectInListByHandle
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: iot_pkcs11_mbedtls.c:956
prvSessionPointerFromHandle
static P11Session_t * prvSessionPointerFromHandle(CK_SESSION_HANDLE xSession)
Maps an opaque caller session handle into its internal state structure.
Definition: iot_pkcs11_mbedtls.c:287
PKCS11_PAL_GetObjectValueCleanup
void PKCS11_PAL_GetObjectValueCleanup(CK_BYTE_PTR pucData, CK_ULONG ulDataSize)
Cleanup after PKCS11_GetObjectValue().
prvCheckValidSessionAndModule
static CK_RV prvCheckValidSessionAndModule(const P11Session_t *pxSession)
Helper to check if the current session is initialized and valid.
Definition: iot_pkcs11_mbedtls.c:248
pkcs11DER_ENCODED_OID_P256
#define pkcs11DER_ENCODED_OID_P256
OID for curve P-256.
Definition: iot_pkcs11.h:135
PKCS11_PAL_GetObjectValue
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.
P11Session_t
Session structure.
Definition: iot_pkcs11_mbedtls.c:217
C_GetAttributeValue
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: iot_pkcs11_mbedtls.c:2566