AzureMXChip/MXCHIPAZ3166/core/lib/netxduo/nx_secure/src/nx_secure_x509_crl_revocation_check.c
UINT _nx_secure_x509_crl_revocation_check(const UCHAR *crl_data, UINT crl_length,
                                          NX_SECURE_X509_CERTIFICATE_STORE *store,
                                          NX_SECURE_X509_CERT *certificate)
{
#ifndef NX_SECURE_X509_DISABLE_CRL
NX_SECURE_X509_CRL   crl;
UINT                 status;
UINT                 crl_bytes;
INT                  compare_value;
UINT                 bytes_processed;
UINT                 length;
const UCHAR         *current_buffer;
NX_SECURE_X509_CERT *issuer_certificate;
UINT                 issuer_location;
const UCHAR         *serial_number;
UINT                 serial_number_length;

    NX_SECURE_MEMSET(&crl, 0, sizeof(NX_SECURE_X509_CRL));

    /* First, parse the CRL. */
    status = _nx_secure_x509_certificate_revocation_list_parse(crl_data, crl_length, &crl_bytes, &crl);

    if (status != NX_SUCCESS)
    {
        return(status);
    }

    /* Check that the issuers match according to process in RFC 5280. */
    compare_value = _nx_secure_x509_distinguished_name_compare(&crl.nx_secure_x509_crl_issuer, &certificate -> nx_secure_x509_issuer, NX_SECURE_X509_NAME_ALL_FIELDS);

    if (compare_value)
    {
        /* The issuers did not match, return error. */
        return(NX_SECURE_X509_CRL_ISSUER_MISMATCH);
    }

    /* Now, check the signature of the CRL. */

    /* First, get the issuer certificate. If we have a valid store and CRL, the issuer should be available. */
    status = _nx_secure_x509_store_certificate_find(store, &crl.nx_secure_x509_crl_issuer, 0, &issuer_certificate, &issuer_location);

    if (status != NX_SUCCESS)
    {
        return(status);
    }

    /* Now, check that the issuer is valid. */
    status = _nx_secure_x509_certificate_chain_verify(store, issuer_certificate);

    if (status != NX_SUCCESS)
    {
        return(status);
    }

    /* Now, verify that the CRL itself is OK. */
    status = _nx_secure_x509_crl_verify(certificate, &crl, store, issuer_certificate);

    if (status != NX_SUCCESS)
    {
        return(status);
    }

    /* If we get here, then the CRL is OK and is issued by the same CA as the certificate in question.
       Finally, we parse the revocation list and see if the serial number of the certificate being
       validated is in the CRL revocation list. */

    /* Parse and search the revokedCertificates list that we obtained when we parsed the CRL.
     *       revokedCertificates     SEQUENCE OF SEQUENCE
     *       {
     *            userCertificate         CertificateSerialNumber,
     *            revocationDate          Time,
     *            crlEntryExtensions      Extensions OPTIONAL
     *                                     -- if present, version MUST be v2
     *       }  OPTIONAL,
     */
    current_buffer = crl.nx_secure_x509_crl_revoked_certs;
    length = crl.nx_secure_x509_crl_revoked_certs_length;
    /* Loop through all the entries in the sequence. */
    while (length > 0)
    {
        /* Parse an entry in the revokedCertificates list and get back the serial number. */
        status = _nx_secure_x509_crl_parse_entry(current_buffer, length, &bytes_processed, &serial_number, &serial_number_length);

        if (status != NX_SUCCESS)
        {
            return(status);
        }

        /* Make sure we don't run past the end of the sequence if one of the entries was too big. */
        if (length < bytes_processed)
        {
            return(NX_SECURE_X509_ASN1_LENGTH_TOO_LONG);
        }

        /* Compare the serial number we got from the list (if it exists) to the one in our certificate. */
        compare_value = NX_SECURE_MEMCMP(serial_number, certificate -> nx_secure_x509_serial_number,
                               certificate -> nx_secure_x509_serial_number_length);

        /* See if we have a match. */
        if (compare_value == 0)
        {
            /* This certificate has been revoked! */
            return(NX_SECURE_X509_CRL_CERTIFICATE_REVOKED);
        }

        /* No match, go to the next one. */
        length -= bytes_processed;
        current_buffer = current_buffer + bytes_processed;
    }

    /* If we get here, the CRL was good and the certificate has not been revoked. */
    return(NX_SUCCESS);
#else /* NX_SECURE_X509_DISABLE_CRL */
    NX_PARAMETER_NOT_USED(crl_data);
    NX_PARAMETER_NOT_USED(crl_length);
    NX_PARAMETER_NOT_USED(store);
    NX_PARAMETER_NOT_USED(certificate);
    return(NX_NOT_SUPPORTED);
#endif /* NX_SECURE_X509_DISABLE_CRL */
}
/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _nx_secure_x509_crl_revocation_check                PORTABLE C      */
/*                                                           6.1          */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Timothy Stapko, Microsoft Corporation                               */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function takes a DER-encoded Certificate Revocation List and   */
/*    searches for a specific certificate in that list. The issuer of the */
/*    CRL is validated against a supplied certificate store, the          */
/*    CRL issuer is validated to be the same as the one for the           */
/*    certificate being checked, and the serial number of the certificate */
/*    in question is used to search the revoked certificates list.        */
/*    If the issuers match, the signature checks out, and the certificate */
/*    is not present in the list, the call is successful. All other cases */
/*    cause an error to be returned.                                      */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    crl_data                              Pointer to DER-encoded CRL    */
/*    crl_length                            Length of CRL data in buffer  */
/*    store                                 Certificate store to be used  */
/*    certificate                           The certificate being checked */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    status                                Completion status             */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*    _nx_secure_x509_certificate_chain_verify                            */
/*                                          Verify cert against stores    */
/*    _nx_secure_x509_certificate_revocation_list_parse                   */
/*                                          Parse revocation list         */
/*    _nx_secure_x509_crl_parse_entry       Parse an entry in crl         */
/*    _nx_secure_x509_crl_verify            Verify revocation list        */
/*    _nx_secure_x509_distinguished_name_compare                          */
/*                                          Compare distinguished name    */
/*    _nx_secure_x509_store_certificate_find                              */
/*                                          Find a cert in a store        */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    Application Code                                                    */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
/*  09-30-2020     Timothy Stapko           Modified comment(s),          */
/*                                            resulting in version 6.1    */
/*                                                                        */
/**************************************************************************/
FUNCTION                                               RELEASE

_nx_secure_x509_crl_revocation_check                PORTABLE C
6.1
AUTHOR

Timothy Stapko, Microsoft Corporation

DESCRIPTION

This function takes a DER-encoded Certificate Revocation List and
searches for a specific certificate in that list. The issuer of the
CRL is validated against a supplied certificate store, the
CRL issuer is validated to be the same as the one for the
certificate being checked, and the serial number of the certificate
in question is used to search the revoked certificates list.
If the issuers match, the signature checks out, and the certificate
is not present in the list, the call is successful. All other cases
cause an error to be returned.

INPUT

crl_data                              Pointer to DER-encoded CRL
crl_length                            Length of CRL data in buffer
store                                 Certificate store to be used
certificate                           The certificate being checked

OUTPUT

status                                Completion status

CALLS

_nx_secure_x509_certificate_chain_verify
Verify cert against stores
_nx_secure_x509_certificate_revocation_list_parse
Parse revocation list
_nx_secure_x509_crl_parse_entry       Parse an entry in crl
_nx_secure_x509_crl_verify            Verify revocation list
_nx_secure_x509_distinguished_name_compare
Compare distinguished name
_nx_secure_x509_store_certificate_find
Find a cert in a store

CALLED BY

Application Code

RELEASE HISTORY

DATE              NAME                      DESCRIPTION

05-19-2020     Timothy Stapko           Initial Version 6.0
09-30-2020     Timothy Stapko           Modified comment(s),
resulting in version 6.1
FUNCTION RELEASE _nx_secure_x509_crl_revocation_check PORTABLE C 6 . 1 AUTHOR Timothy Stapko Microsoft Corporation DESCRIPTION This function takes a DER - encoded Certificate Revocation List and searches for a specific certificate in that list . The issuer of the CRL is validated against a supplied certificate store the CRL issuer is validated to be the same as the one for the certificate being checked and the serial number of the certificate in question is used to search the revoked certificates list . If the issuers match the signature checks out and the certificate is not present in the list the call is successful . All other cases cause an error to be returned . INPUT crl_data Pointer to DER - encoded CRL crl_length Length of CRL data in buffer store Certificate store to be used certificate The certificate being checked OUTPUT status Completion status CALLS _nx_secure_x509_certificate_chain_verify Verify cert against stores _nx_secure_x509_certificate_revocation_list_parse Parse revocation list _nx_secure_x509_crl_parse_entry Parse an entry in crl _nx_secure_x509_crl_verify Verify revocation list _nx_secure_x509_distinguished_name_compare Compare distinguished name _nx_secure_x509_store_certificate_find Find a cert in a store CALLED BY Application Code RELEASE HISTORY DATE NAME DESCRIPTION 05 - 19 - 2020 Timothy Stapko Initial Version 6 . 0 09 - 30 - 2020 Timothy Stapko Modified comment ( s ) resulting in version 6 . 1
UINT _nx_secure_x509_crl_revocation_check(const UCHAR *crl_data, UINT crl_length,
                                          NX_SECURE_X509_CERTIFICATE_STORE *store,
                                          NX_SECURE_X509_CERT *certificate)
{
#ifndef NX_SECURE_X509_DISABLE_CRL
NX_SECURE_X509_CRL   crl;
UINT                 status;
UINT                 crl_bytes;
INT                  compare_value;
UINT                 bytes_processed;
UINT                 length;
const UCHAR         *current_buffer;
NX_SECURE_X509_CERT *issuer_certificate;
UINT                 issuer_location;
const UCHAR         *serial_number;
UINT                 serial_number_length;
    NX_SECURE_MEMSET(&crl, 0, sizeof(NX_SECURE_X509_CRL));
    status = _nx_secure_x509_certificate_revocation_list_parse(crl_data, crl_length, &crl_bytes, &crl);
    if (status != NX_SUCCESS)
    {
        return(status);
    }
    compare_value = _nx_secure_x509_distinguished_name_compare(&crl.nx_secure_x509_crl_issuer, &certificate -> nx_secure_x509_issuer, NX_SECURE_X509_NAME_ALL_FIELDS);
    if (compare_value)
    {
        return(NX_SECURE_X509_CRL_ISSUER_MISMATCH);
    }
    status = _nx_secure_x509_store_certificate_find(store, &crl.nx_secure_x509_crl_issuer, 0, &issuer_certificate, &issuer_location);
    if (status != NX_SUCCESS)
    {
        return(status);
    }
    status = _nx_secure_x509_certificate_chain_verify(store, issuer_certificate);
    if (status != NX_SUCCESS)
    {
        return(status);
    }
    status = _nx_secure_x509_crl_verify(certificate, &crl, store, issuer_certificate);
    if (status != NX_SUCCESS)
    {
        return(status);
    }
    current_buffer = crl.nx_secure_x509_crl_revoked_certs;
    length = crl.nx_secure_x509_crl_revoked_certs_length;
    while (length > 0)
    {
        status = _nx_secure_x509_crl_parse_entry(current_buffer, length, &bytes_processed, &serial_number, &serial_number_length);
        if (status != NX_SUCCESS)
        {
            return(status);
        }
        if (length < bytes_processed)
        {
            return(NX_SECURE_X509_ASN1_LENGTH_TOO_LONG);
        }
        compare_value = NX_SECURE_MEMCMP(serial_number, certificate -> nx_secure_x509_serial_number,
                               certificate -> nx_secure_x509_serial_number_length);
        if (compare_value == 0)
        {
            return(NX_SECURE_X509_CRL_CERTIFICATE_REVOKED);
        }
        length -= bytes_processed;
        current_buffer = current_buffer + bytes_processed;
    }
    return(NX_SUCCESS);
#else 
    NX_PARAMETER_NOT_USED(crl_data);
    NX_PARAMETER_NOT_USED(crl_length);
    NX_PARAMETER_NOT_USED(store);
    NX_PARAMETER_NOT_USED(certificate);
    return(NX_NOT_SUPPORTED);
#endif 
}
UINT _nx_secure_x509_crl_revocation_check ( const UCHAR * crl_data , UINT crl_length , NX_SECURE_X509_CERTIFICATE_STORE * store , NX_SECURE_X509_CERT * certificate ) { #ifndef NX_SECURE_X509_DISABLE_CRL NX_SECURE_X509_CRL crl ; UINT status ; UINT crl_bytes ; INT compare_value ; UINT bytes_processed ; UINT length ; const UCHAR * current_buffer ; NX_SECURE_X509_CERT * issuer_certificate ; UINT issuer_location ; const UCHAR * serial_number ; UINT serial_number_length ; NX_SECURE_MEMSET ( & crl , 0 , sizeof ( NX_SECURE_X509_CRL ) ) ; status = _nx_secure_x509_certificate_revocation_list_parse ( crl_data , crl_length , & crl_bytes , & crl ) ; if ( status != NX_SUCCESS ) { return ( status ) ; } compare_value = _nx_secure_x509_distinguished_name_compare ( & crl . nx_secure_x509_crl_issuer , & certificate -> nx_secure_x509_issuer , NX_SECURE_X509_NAME_ALL_FIELDS ) ; if ( compare_value ) { return ( NX_SECURE_X509_CRL_ISSUER_MISMATCH ) ; } status = _nx_secure_x509_store_certificate_find ( store , & crl . nx_secure_x509_crl_issuer , 0 , & issuer_certificate , & issuer_location ) ; if ( status != NX_SUCCESS ) { return ( status ) ; } status = _nx_secure_x509_certificate_chain_verify ( store , issuer_certificate ) ; if ( status != NX_SUCCESS ) { return ( status ) ; } status = _nx_secure_x509_crl_verify ( certificate , & crl , store , issuer_certificate ) ; if ( status != NX_SUCCESS ) { return ( status ) ; } current_buffer = crl . nx_secure_x509_crl_revoked_certs ; length = crl . nx_secure_x509_crl_revoked_certs_length ; while ( length > 0 ) { status = _nx_secure_x509_crl_parse_entry ( current_buffer , length , & bytes_processed , & serial_number , & serial_number_length ) ; if ( status != NX_SUCCESS ) { return ( status ) ; } if ( length < bytes_processed ) { return ( NX_SECURE_X509_ASN1_LENGTH_TOO_LONG ) ; } compare_value = NX_SECURE_MEMCMP ( serial_number , certificate -> nx_secure_x509_serial_number , certificate -> nx_secure_x509_serial_number_length ) ; if ( compare_value == 0 ) { return ( NX_SECURE_X509_CRL_CERTIFICATE_REVOKED ) ; } length -= bytes_processed ; current_buffer = current_buffer + bytes_processed ; } return ( NX_SUCCESS ) ; #else NX_PARAMETER_NOT_USED ( crl_data ) ; NX_PARAMETER_NOT_USED ( crl_length ) ; NX_PARAMETER_NOT_USED ( store ) ; NX_PARAMETER_NOT_USED ( certificate ) ; return ( NX_NOT_SUPPORTED ) ; #endif }
FUNCTION                                               RELEASE
FUNCTION RELEASE
/* First, parse the CRL. */ /* Check that the issuers match according to process in RFC 5280. */ /* The issuers did not match, return error. */ /* Now, check the signature of the CRL. */ /* First, get the issuer certificate. If we have a valid store and CRL, the issuer should be available. */ /* Now, check that the issuer is valid. */ /* Now, verify that the CRL itself is OK. */ /* If we get here, then the CRL is OK and is issued by the same CA as the certificate in question.
       Finally, we parse the revocation list and see if the serial number of the certificate being
       validated is in the CRL revocation list. */ /* Parse and search the revokedCertificates list that we obtained when we parsed the CRL.
     *       revokedCertificates     SEQUENCE OF SEQUENCE
     *       {
     *            userCertificate         CertificateSerialNumber,
     *            revocationDate          Time,
     *            crlEntryExtensions      Extensions OPTIONAL
     *                                     -- if present, version MUST be v2
     *       }  OPTIONAL,
     */ /* Loop through all the entries in the sequence. */ /* Parse an entry in the revokedCertificates list and get back the serial number. */ /* Make sure we don't run past the end of the sequence if one of the entries was too big. */ /* Compare the serial number we got from the list (if it exists) to the one in our certificate. */ /* See if we have a match. */ /* This certificate has been revoked! */ /* No match, go to the next one. */ /* If we get here, the CRL was good and the certificate has not been revoked. */ /* NX_SECURE_X509_DISABLE_CRL */ /* NX_SECURE_X509_DISABLE_CRL */