is_bad.c

来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 499 行 · 第 1/2 页

C
499
字号
 * serialNumber             CertificateSerialNumber,
 * signature                AlgorithmIdentifier,
 * issuer                   Name,
 * validity                 Validity,
 * subject                  Name,
 * subjectPublicKeyInfo     SubjectPublicKeyInfo,
 * issuerUniqueIdentifier   [1]	IMPLICIT UniqueIdentifier OPTIONAL,
 *                              -- if present, version must be v2or v3
 * subjectUniqueIdentifier  [2]	IMPLICIT UniqueIdentifier OPTIONAL
 *                              -- if present, version must be v2 or v3
 * extensions               [3]	Extensions OPTIONAL
 *                              -- if present, version must be v3}
 *
 * Version                  ::= INTEGER { v1(0), v2(1), v3(2) }
 * CertificateSerialNumber  ::= INTEGER
 * AlgorithmIdentifier      ::= SEQUENCE 
 * Name                     ::= SEQUENCE OF RelativeDistinguishedName
 * Validity                 ::= SEQUENCE {
 *     notBefore        UTCTime,
 *     notAfter	        UTCTime }
 * SubjectPublicKeyInfo     ::= SEQUENCE {
 *     algorithm        AlgorithmIdentifier,
 *     subjectPublicKey BIT STRING }
 * Extensions               ::= SEQUENCE  of Extension
 *     Extension        ::=	SEQUENCE {
 *         extnId           EXTENSION.&id({Extension Set}),
 *         critical         BOOLEAN DEFAULT FALSE,
 *         extnValue        OCTET STRING 
 *
 * Parameters: 
 * ParentNode (input) : The top node in the parse tree to be checked
 *
 * Return value:
 * A TRUE/FALSE indicator of whether this is a valid TbsCert parse tree
 * 
 * Error Codes:
 * None
 *---------------------------------------------------------------------------*/
CSSM_BOOL cl_IsBadTbsCertParseTree (DER_NODE_PTR ParentNode)
{
                  /* The order of these tags is determined by */
                  /* the X.509 structure shown above */
    const uint8   field_tags[NUM_TBSCERT_FIELDS] = {
                  BER_CONSTRUCTED_SEQUENCE, /* Version as EXPLICIT */
                  BER_INTEGER,              /* SerialNumber */
                  BER_CONSTRUCTED_SEQUENCE, /* SigningAlg */
                  BER_CONSTRUCTED_SEQUENCE, /* IssuerName */
                  BER_CONSTRUCTED_SEQUENCE, /* Validity */
                  BER_CONSTRUCTED_SEQUENCE, /* SubjectName */
                  BER_CONSTRUCTED_SEQUENCE, /* SPKI */
                  BER_BIT_STRING,           /* IssuerUID */
                  BER_BIT_STRING,           /* SubjectUID */
                  BER_CONSTRUCTED_SEQUENCE  /* Extensions */
                  };
    CSSM_BOOL     existence[NUM_TBSCERT_FIELDS];
    DER_NODE_PTR  tree_version, tree_validity, tree_key_info,                  
                  tree_expl_extns, tree_extensions, current_extn;
    sint32        i;

    /* Verify that the parse tree has 10 children, */
    /* one for each field in the TbsCert structure */
    if (ParentNode->Count != NUM_TBSCERT_FIELDS)
        return CSSM_TRUE;

    /* Verify that the Tag is correct for each field */
    cl_DetermineOptionalFieldExistence(ParentNode->Child, existence);
    for (i=0; i < NUM_TBSCERT_FIELDS; i++)
    {
        if (existence[i])
            if (cl_IsBadDerNodeChild(&ParentNode->Child[i], field_tags[i]))
                return CSSM_TRUE;
    }

    /* Error checking on the version subtree */
    if (existence[TBSCERT_VERSION])
    {
        /* Version should have a single child, the version itself */
        tree_version = ParentNode->Child[TBSCERT_VERSION].X.Node;
        if (tree_version->Count != NUM_TBSCERT_VERSION_FIELDS) 
            return CSSM_TRUE;

        /* The Version child should be an integer of length = 1 */
        if (cl_IsBadDerNodeChild(&tree_version->Child[0], BER_INTEGER) ||
            tree_version->Child->X.Input.ContentLength != TBSCERT_VERSION_LENGTH)
            return CSSM_TRUE;
    }

    /* Error checking on the signature algorithm subtree */
    if (cl_IsBadOidValueParseTree(ParentNode->Child[TBSCERT_SIG_ALG].X.Node))
        return CSSM_TRUE;

    /* Error checking on the issuer and subject subtrees */
    if (cl_IsBadNameParseTree(ParentNode->Child[TBSCERT_ISSUER].X.Node) ||
        cl_IsBadNameParseTree(ParentNode->Child[TBSCERT_SUBJECT].X.Node))
        return CSSM_TRUE;

    /* Error checking on the validity subtree */
    /* The Validity subtree should have 2 children */
    tree_validity = ParentNode->Child[TBSCERT_VALIDITY].X.Node;
    if (tree_validity->Count != NUM_TBSCERT_VALIDITY_FIELDS)
        return CSSM_TRUE;

    /* The Validity's children should be UTCTime or GeneralizedTime */
    for (i=0; i < tree_validity->Count; i++)
    {
        if (!tree_validity->Child[i].IsLeaf ||
            BER_LengthOfTag(
                tree_validity->Child[i].X.Input.Tag) != BER_UNIVERSAL_TAG_LENGTH)
            return CSSM_TRUE;

        if (*tree_validity->Child[i].X.Input.Tag == BER_UTCTIME)
        {
            /* Verify that this is a valid UTCTime string */
            if (cl_IsBadUtc (tree_validity->Child[i].X.Input.Content, 
                             tree_validity->Child[i].X.Input.ContentLength))
                return CSSM_TRUE;
        }
        else if (*tree_validity->Child[i].X.Input.Tag == BER_GENTIME)
        {
            /* Verify that this is a valid Generalized Time string */
            if (cl_IsBadGeneralizedTime (tree_validity->Child[i].X.Input.Content,
                                  tree_validity->Child[i].X.Input.ContentLength))
                return CSSM_TRUE;
        }
        else /* This is an invalid Tag for a validity date. */
            return CSSM_TRUE;
    }

    /* Error checking on SPKI subtree */
    /* SPKI should have 2 children */
    tree_key_info = ParentNode->Child[TBSCERT_SPKI].X.Node;
    if (tree_key_info->Count != NUM_TBSCERT_SPKI_FIELDS) 
        return CSSM_TRUE;

    /* The first child should be an AlgId structure */
    if (cl_IsBadDerNodeChild(
            &tree_key_info->Child[SPKI_ALGID], BER_CONSTRUCTED_SEQUENCE) ||
        cl_IsBadOidValueParseTree(tree_key_info->Child[SPKI_ALGID].X.Node))
        return CSSM_TRUE;

    /* The second child should be a bit string */
    if (cl_IsBadDerNodeChild(&tree_key_info->Child[SPKI_SPK], BER_BIT_STRING))
        return CSSM_TRUE;

    /* Error checking on extensions subtree */
    if (existence[TBSCERT_EXTENSIONS])
    {
        /* Verify that extensions is a SEQUENCE */
        tree_expl_extns = ParentNode->Child[TBSCERT_EXTENSIONS].X.Node;
        if (tree_expl_extns->Count != 1 ||
            cl_IsBadDerNodeChild(&tree_expl_extns->Child[0], 
                                 BER_CONSTRUCTED_SEQUENCE))
                return CSSM_TRUE;

        tree_extensions = tree_expl_extns->Child[0].X.Node;

        /* For each extension */
        for (i=0; i < tree_extensions->Count; i++)
        {
            /* Verify that the extension is a SEQUENCE */
            if (cl_IsBadDerNodeChild(&tree_extensions->Child[i], 
                                     BER_CONSTRUCTED_SEQUENCE))
                return CSSM_TRUE;

            /* Verify that the extension has either 2 or 3 children.         */
            /* It will have 2 if extension->critical was FALSE because,      */
            /* in DER-encoding, values that equal their default are removed. */
            /* (extension->critical is defined as BOOLEAN DEFAULT FALSE)     */
            current_extn = tree_extensions->Child[i].X.Node;
            if (current_extn->Count != 2 && current_extn->Count != 3)
                return CSSM_TRUE;

            /* Verify that the first field (extension->Id) is an OID */
            if (cl_IsBadDerNodeChild(&current_extn->Child[0],
                                     BER_OBJECT_IDENTIFIER))
                return CSSM_TRUE;

            /* If available, verify that the second field (extension->critical) */
            /* is a BOOLEAN of length 1 */
            if (current_extn->Count == 3)
                if (cl_IsBadDerNodeChild(&current_extn->Child[1], BER_BOOLEAN) ||
                    current_extn->Child[1].X.Input.ContentLength != 1)
                    return CSSM_TRUE;

            /* Verify that the last field (extension->value) is an OCTET STRING */
            if (cl_IsBadDerNodeChild(&current_extn->Child[current_extn->Count-1],
                                     BER_OCTET_STRING))
                return CSSM_TRUE;
        }
    }
    
    return CSSM_FALSE;
}


/*-----------------------------------------------------------------------------
 * Name: cl_IsBadCertificateParseTree
 *
 * Description:
 * This function checks whether this parse tree conforms
 * to the certificate structure defined by the X.509 specification.
 * Certificate ::= SIGNED{ tbsCert }
 *
 * Parameters: 
 * ParentNode (input) : The top node in the parse tree to be checked
 *
 * Return value:
 * A TRUE/FALSE indicator of whether this is a valid Cert parse tree
 * 
 * Error Codes:
 * None
 *---------------------------------------------------------------------------*/
CSSM_BOOL cl_IsBadCertificateParseTree(DER_NODE_PTR ParentNode)
{
    uint8  field_tags[NUM_CERT_FIELDS] = {
           BER_CONSTRUCTED_SEQUENCE, /* TbsCert */
           BER_CONSTRUCTED_SEQUENCE, /* SigningAlg */
           BER_BIT_STRING            /* Signature */
           };
    uint32 i;

    /* A certificate should be a SEQUENCE with 3 children: 
     * TbsCert, SigAlg, and signature */
    if (!ParentNode) 
        return CSSM_TRUE;
    if (BER_LengthOfTag(ParentNode->Tag) != BER_UNIVERSAL_TAG_LENGTH ||
        *ParentNode->Tag != BER_CONSTRUCTED_SEQUENCE)
        return CSSM_TRUE;
    if (ParentNode->Count != NUM_CERT_FIELDS) 
        return CSSM_TRUE;

    /* Verify that the Tag is correct for each field */
    for (i=0; i < NUM_CERT_FIELDS; i++)
    {
        if (cl_IsBadDerNodeChild(&ParentNode->Child[i], field_tags[i]))
            return CSSM_TRUE;
    }

    /* Verify that the TbsCert parse tree is valid */
    if (cl_IsBadTbsCertParseTree(ParentNode->Child[CERT_TBSCERT].X.Node)) 
        return CSSM_TRUE;

    /* Verify that the SigAlg parse tree is valid */
    if (cl_IsBadOidValueParseTree(ParentNode->Child[CERT_SIG_ALG].X.Node)) 
        return CSSM_TRUE;

    return CSSM_FALSE;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?