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(¤t_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(¤t_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(¤t_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 + -
显示快捷键?