static int prvInitializeClientCredential()

in amazon-freertos/lib/tls/aws_tls.c [330:524]


static int prvInitializeClientCredential( TLSContext_t * pxCtx )
{
    BaseType_t xResult = 0;
    CK_SLOT_ID xSlotId = 0;
    CK_ULONG xCount = 1;
    CK_ATTRIBUTE xTemplate = { 0 };
    CK_OBJECT_HANDLE xCertObj = 0;
    CK_BYTE * pxCertificate = NULL;
    mbedtls_pk_type_t xKeyAlgo = ( mbedtls_pk_type_t ) ~0;
    CK_KEY_TYPE xKeyType = ( CK_KEY_TYPE ) ~0;

    /* Initialize the mbed contexts. */
    mbedtls_x509_crt_init( &pxCtx->xMbedX509Cli );

    /* Get the default private key storage ID. */
    if( CKR_OK == xResult )
    {
        xResult = ( BaseType_t ) pxCtx->xP11FunctionList->C_GetSlotList( CK_TRUE,
                                                                         &xSlotId,
                                                                         &xCount );
    }

    /* Start a private session with the P#11 module. */
    if( 0 == xResult )
    {
        xResult = ( BaseType_t ) pxCtx->xP11FunctionList->C_OpenSession( xSlotId,
                                                                         CKF_SERIAL_SESSION,
                                                                         NULL,
                                                                         NULL,
                                                                         &pxCtx->xP11Session );
    }

    /* Get the handle of the device private key. */
    if( 0 == xResult )
    {
        xTemplate.type = CKA_LABEL;
        xTemplate.ulValueLen = sizeof( pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS );
        xTemplate.pValue = &pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS;
        xResult = ( BaseType_t ) pxCtx->xP11FunctionList->C_FindObjectsInit( pxCtx->xP11Session,
                                                                             &xTemplate,
                                                                             1 );
    }

    if( 0 == xResult )
    {
        xResult = ( BaseType_t ) pxCtx->xP11FunctionList->C_FindObjects( pxCtx->xP11Session,
                                                                         &pxCtx->xP11PrivateKey,
                                                                         1,
                                                                         &xCount );
    }

    if( 0 == xResult )
    {
        xResult = ( BaseType_t ) pxCtx->xP11FunctionList->C_FindObjectsFinal( pxCtx->xP11Session );
    }

    if( xResult == CKR_OK )
    {
        xTemplate.type = CKA_KEY_TYPE;
        xTemplate.pValue = &xKeyType;
        xTemplate.ulValueLen = sizeof( CK_KEY_TYPE );
        xResult = pxCtx->xP11FunctionList->C_GetAttributeValue( pxCtx->xP11Session,
                                                                pxCtx->xP11PrivateKey,
                                                                &xTemplate,
                                                                1 );
    }

    if( xResult == CKR_OK )
    {
        switch( xKeyType )
        {
            case CKK_RSA:
                xKeyAlgo = MBEDTLS_PK_RSA;
                break;

            case CKK_EC:
                xKeyAlgo = MBEDTLS_PK_ECKEY;
                break;

            default:
                xResult = CKR_ATTRIBUTE_VALUE_INVALID;
                break;
        }
    }

    if( xResult == CKR_OK )
    {
        memcpy( &pxCtx->xMbedPkInfo, mbedtls_pk_info_from_type( xKeyAlgo ), sizeof( mbedtls_pk_info_t ) );

        pxCtx->xMbedPkInfo.sign_func = prvPrivateKeySigningCallback;
        pxCtx->xMbedPkCtx.pk_info = &pxCtx->xMbedPkInfo;
        pxCtx->xMbedPkCtx.pk_ctx = pxCtx;
    }

    if( 0 == xResult )
    {
        /* Enumerate the first client certificate. */
        xTemplate.type = CKA_LABEL;
        xTemplate.ulValueLen = sizeof( pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS );
        xTemplate.pValue = &pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS;
        xResult = ( BaseType_t ) pxCtx->xP11FunctionList->C_FindObjectsInit( pxCtx->xP11Session,
                                                                             &xTemplate,
                                                                             1 );
    }

    if( 0 == xResult )
    {
        xResult = ( BaseType_t ) pxCtx->xP11FunctionList->C_FindObjects( pxCtx->xP11Session,
                                                                         &xCertObj,
                                                                         1,
                                                                         &xCount );
    }

    if( 0 == xResult )
    {
        xResult = ( BaseType_t ) pxCtx->xP11FunctionList->C_FindObjectsFinal( pxCtx->xP11Session );
    }

    if( 0 == xResult )
    {
        /* Query the device certificate size. */
        xTemplate.type = CKA_VALUE;
        xTemplate.ulValueLen = 0;
        xTemplate.pValue = NULL;
        xResult = ( BaseType_t ) pxCtx->xP11FunctionList->C_GetAttributeValue( pxCtx->xP11Session,
                                                                               xCertObj,
                                                                               &xTemplate,
                                                                               1 );
    }

    if( 0 == xResult )
    {
        /* Create a buffer for the certificate. */
        pxCertificate = ( CK_BYTE_PTR ) pvPortMalloc( xTemplate.ulValueLen ); /*lint !e9079 Allow casting void* to other types. */

        if( NULL == pxCertificate )
        {
            xResult = ( BaseType_t ) CKR_HOST_MEMORY;
        }
    }

    if( 0 == xResult )
    {
        /* Export the certificate. */
        xTemplate.pValue = pxCertificate;
        xResult = ( BaseType_t ) pxCtx->xP11FunctionList->C_GetAttributeValue( pxCtx->xP11Session,
                                                                               xCertObj,
                                                                               &xTemplate,
                                                                               1 );
    }

    /* Decode the client certificate. */
    if( 0 == xResult )
    {
        xResult = mbedtls_x509_crt_parse( &pxCtx->xMbedX509Cli,
                                          ( const unsigned char * ) pxCertificate,
                                          xTemplate.ulValueLen );
    }

    /*
     * Add a JITR device issuer certificate, if present.
     */
    if( ( 0 == xResult ) &&
        ( NULL != clientcredentialJITR_DEVICE_CERTIFICATE_AUTHORITY_PEM ) )
    {
        /* Decode the JITR issuer. The device client certificate will get
         * inserted as the first certificate in this chain below. */
        xResult = mbedtls_x509_crt_parse(
            &pxCtx->xMbedX509Cli,
            ( const unsigned char * ) clientcredentialJITR_DEVICE_CERTIFICATE_AUTHORITY_PEM,
            1 + strlen( clientcredentialJITR_DEVICE_CERTIFICATE_AUTHORITY_PEM ) );
    }

    /*
     * Attach the client certificate and private key to the TLS configuration.
     */
    if( 0 == xResult )
    {
        xResult = mbedtls_ssl_conf_own_cert( &pxCtx->xMbedSslConfig,
                                             &pxCtx->xMbedX509Cli,
                                             &pxCtx->xMbedPkCtx );
    }

    if( NULL != pxCertificate )
    {
        vPortFree( pxCertificate );
    }

    if( CKR_OK != xResult )
    {
        TLS_PRINT( ( "ERROR: Loading credentials from flash into TLS context failed with error %d.\r\n", xResult ) );
    }

    return xResult;
}