static OtaPalMainStatus_t otaPal_CheckFileSignature()

in lib/AWS/ota-pal/Win32/ota_pal.c [252:333]


static OtaPalMainStatus_t otaPal_CheckFileSignature( OtaFileContext_t * const C )
{
    OtaPalMainStatus_t eResult = OtaPalSuccess;
    uint32_t ulBytesRead;
    uint32_t ulSignerCertSize;
    uint8_t * pucBuf, * pucSignerCert;
    void * pvSigVerifyContext;

    if( prvContextValidate( C ) == pdTRUE )
    {
        /* Verify an ECDSA-SHA256 signature. */
        if( pdFALSE == CRYPTO_SignatureVerificationStart( &pvSigVerifyContext, cryptoASYMMETRIC_ALGORITHM_ECDSA, cryptoHASH_ALGORITHM_SHA256 ) )
        {
            eResult = OtaPalSignatureCheckFailed;
        }
        else
        {
            LogInfo( ( "Started %s signature verification, file: %s\r\n",
                        OTA_JsonFileSignatureKey, ( const char * ) C->pCertFilepath ) );
            pucSignerCert = otaPal_ReadAndAssumeCertificate( ( const uint8_t * const ) C->pCertFilepath, &ulSignerCertSize );

            if( pucSignerCert != NULL )
            {
                pucBuf = pvPortMalloc( OTA_PAL_WIN_BUF_SIZE ); /*lint !e9079 Allow conversion. */

                if( pucBuf != NULL )
                {
                    /* Rewind the received file to the beginning. */
                    if( fseek( C->pFile, 0L, SEEK_SET ) == 0 ) /*lint !e586
                                                                  * C standard library call is being used for portability. */
                    {
                        do
                        {
                            ulBytesRead = fread( pucBuf, 1, OTA_PAL_WIN_BUF_SIZE, C->pFile ); /*lint !e586
                                                                                               * C standard library call is being used for portability. */
                            /* Include the file chunk in the signature validation. Zero size is OK. */
                            CRYPTO_SignatureVerificationUpdate( pvSigVerifyContext, pucBuf, ulBytesRead );
                        } while( ulBytesRead > 0UL );

                        if( pdFALSE == CRYPTO_SignatureVerificationFinal( pvSigVerifyContext,
                                                                          ( char * ) pucSignerCert,
                                                                          ( size_t ) ulSignerCertSize,
                                                                          C->pSignature->data,
                                                                          C->pSignature->size ) ) /*lint !e732 !e9034 Allow comparison in this context. */
                        {
                            eResult = OtaPalSignatureCheckFailed;
                        }
                        pvSigVerifyContext = NULL;    /* The context has been freed by CRYPTO_SignatureVerificationFinal(). */
                    }
                    else
                    {
                        /* Nothing special to do. */
                    }

                    /* Free the temporary file page buffer. */
                    vPortFree( pucBuf );
                }
                else
                {
                    LogError( ( "Failed to allocate buffer memory.\r\n" ) );
                    eResult = OtaPalOutOfMemory;
                }

                /* Free the signer certificate that we now own after prvReadAndAssumeCertificate(). */
                vPortFree( pucSignerCert );
            }
            else
            {
                eResult = OtaPalBadSignerCert;
            }
        }
    }
    else
    {
        /* FIXME: Invalid error code for a NULL file context. */
        LogError( ( "Invalid OTA file context.\r\n" ) );
        /* Invalid OTA context or file pointer. */
        eResult = OtaPalNullFileContext;
    }

    return eResult;
}