API Reference | developer.brewmp.com API Reference | developer.brewmp.com


API Reference


Brew Release
Brew MP 1.0.2
See Also
Complete and verify the certificate chain.
void ICertChain_Verify(ICertChain *pif, CertDataTrustResult *pTrustResults, AEECallback *pVerifyCB, ...);
void ICertChain_VerifyV(ICertChain *pif, CertDataTrustResult *pTrustResults, AEECallback *pVerifyCB, const xOpt *awozList);
Instance of ICertChain
Place to put trust results.
Called back when verification is complete.
awozList or ...: A set of xOpts to use while doing Verify. May include certificates.
  • None.
    When pVerifyCB is invoked, pTrustResult contains the result:
    AEE_ENOMEMORY: Couldn't allocate memory
    AEE_EITEMBUSY: a verify is in progress already
Side Effect
  • Causes cert chain to be formed so that certs, cert fields, and cert field parts can be fetched in cert chain order using CERTDATAOPT_CHAIN_CERT.
This function does the heavy crypto to actually verify the signatures on the certs up to a root in the set of roots. Depending on key length, key modulus, processor speed and cert chain length, the time for this operation can vary. For most cert chains it should be less than a second. Only one verify may be in progress at a time. First this builds the cert chain. It does this by finding the leaf cert and searching for a cert that has a subject matching its issuer. The search is conducted over the options tree, first through the options passed into the ICertChain_VerifyV() operation as parameters, second through the options stored by the instance itself, and on to any default options sets. The search is always first for root certs, then branch certs. Certs added earlier in the options tree are matched first. When forming the certificate chain there are comparisons of issuer and subject. The comparison of issuer distinguished name (DN) to subject DN complies with RFC 2459 / 3280 section 6.1 and X.509 section 9. It ignores leading/ trailing space and case for attribute values (AVs) that are of type PrintableString and does a binary compare for all other AVs. It is sensitive to the structure/order of the relative distinguished names (RDNs) that make up the DN, but not to the order of the AVs within a DN. So the following are equal:
  • (1) (O=fish-tacos, OU=fish, OU=halibut), (CO=mexico,ST=baja)
  • (2) (OU=halibut,O=fish-tacos, OU=fish) (ST=baja,CO=mexico)
but these are not to each other or those above:
  • (3) (CO=mexico), (ST=baja), (OU=halibut), (O=fish-tacos, OU=fish)
  • (4) (O=fish-tacos, OU=fish), (OU=halibut), (CO=mexico), (ST=baja)
Note there is a limit of 16 to the number of parts in a DN that will be matched. If a DN being match has more than 16 parts the chain computation will fail with a CERTDATA_CERT_TRUST error. Once the chain is formed, any certs that are part of the chain, but not stored in the instance of ICertChain, are copied. This is so the chain is retained after the verify operation is completed so that it can be displayed or such. These certs can be retrieved using CERTDATAOPT_CHAIN_CERT. Next the chain is verified. Firstly, this involves checking the leaf cert to match the host name. Regular expressions in the common name (CN) are catered for as per the following rules defined by Netscape:
  • * matches anything
  • ? matches one character
  • \ escapes a special character
  • $ matches the end of the string
  • [abc] matches one occurrence of a, b, or c. The only character that needs
  • to be escaped in this is ], all others are not special.
  • [a-z] matches any character between a and z. [^az] matches any character
  • except a or z. ~ followed by another shell expression removes any
  • pattern matching the shell expression from the match list
  • (foo|bar) matches either the substring foo, or the substring bar. These
  • can be shell expressions as well.
Following this, the verification continues on each cert, checking the validity dates, constraints imposed by extensions, and the signature. The verification does not stop at on the first error. It continues over the whole computed cert chain. The errors are accumulated in the bit maps in the response structure. All these errors are "soft" trust errors that can be overridden. The hard errors are primarily out of memory or lack of a good leaf cert. The verifications can be turned off or overridden on a per certificate basis or for the whole chain verification with CertDataTrustOverride records. The host name, CertDataTrustOverride records, and other options are stored in xOpts that can either be stored in the instance itself by calling ICertChain_AddOpt, or be passed as a parameter to ICertChain_VerifyV. Note that by passing an instance of IxOpts as a new default (e.g. as ID XOPT_DEFAULTS), a whole tree of options can be passed in as a parameter. When the verify completes, the callback is called. You may cancel the verify operation by calling CALLBACK_Cancel() on the callback record passed to the verify operation. Note that releasing the ICertChain object does not cancel the callback. The object will persist and the callback will complete. Thus the callback should be canceled before releasing the ICertChain object (unless you want the callback to be called after the release). Note also that two verify operations on the same ICertChain object can not be started in parallel, if tried it will return an AEE_EITEMBUSY. The results are copied into the pTrustResult structure. You must check both nResult and uErrorSummary to get the complete results of the verify operation. Once Verify is complete you can fetch the certs in chain order using the CERTDATAOPT_CHAIN_CERT opt id. Index "0" = Leaf Cert, Index 1 = CA for Leaf Cert and so on. Index "Chain_Length-1" = root cert for this chain. Calling ICertChain_RemoveOpt() does not remove certs in this formed chain. If you call ICertChain_Verify() again this chain will be overwritten. Note that you can reuse this object for verifying multiple chains by replacing the certs added to CertChain object itself. Certs copied in the chain will be overwritten when Verify is called again. Best way to reuse the object is by passing in all the certs as parameter to Verify. The basic constraints extension is processed as follows. It is ignored on the leaf and root certificate and on all v1 certificates. On the intermediate certificates its presence is required, and the value of the CA boolean must be true. If not the error CERTDATA_BASIC_CONST will be given. Also, the pathLen is imposed. If the path is too long, CERTDATA_LONG_CHAIN is given. The criticality of the basic constraints has no affect on its processing. To turn off all basic constraints processing, set CERTDATA_BASIC_CONST as an override. The X509v3 Key Use extension is processed as follows. If the extension is not marked as critical, it is completely ignored. If it occurs in a branch or root (not the leaf) and is critical then it must contain ASNOID_KEYUSE_CERTSIGN or the trust error CERTDATA_KEY_USE is given. If it occurs in a leaf cert then there must be matching values in the extension for every usage bit set in the option CERTDATAOPT_KEY_USE or the trust error CERTDATA_KEY_USE is set. Extended key use processing is turned on if any xOpts with ID CERTDATAOPT_EXT_KEY_USE are set. If set then certificates in the chain with extendedKeyUse extensions are processed against it. No processing is done for certificates that don't have an extendedKeyUse as the implication is there is no restriction on their usage. By default only the leaf cert is processed. To have the extension processed in other than the leaf set the trust override bit CERTDATA_NON_LEAF_EXT_KEY_USE. It is not recommended that this be set for SSL. In processing, the extendedKeyUse section of each cert must include the OIDs for all of the usages given in the CERTDATAOPT_EXT_KEY_USE xOpts. If one is missing an error is returned. Certs without extendedKeyUse never generate an error. The error returned will be CERTDATA_EXT_KEY_USE if the extension is not critical and CERTDATA_CRIT_EXT_KEY_USE if it is. To avoid processing entirely, do not set any xOpts with ID CERTDATAOPT_EXT_KEY_USE. To process them only if they are critical, set the xOpts and the trust override CERTDATA_EXT_KEY_USE. Setting CERTDATA_CRIT_EXT_KEY_USE as a trust override is the same as not setting any xOpts with ID CERTDATAOPT_EXT_KEY_USE. There are many more types of extensions in certificates. They are all ignored. If you wish you may use the ICertParse_GetFieldPart() function to get and process them. If an extension is marked critical and not understood, then the CERTDATA_CRITICAL_EXTENSION is set. The following summarizes the xOpt IDs that affect chain verification. See also the xOpt IDs under ICertChain_AddOpt() for the certificate types. CERTDATAOPT_HOST: Set the hostname to compare with the hostname in the common name in the leaf cert in the chain. It must be a NULL terminated string though the host part that is actually compared. stops at the first ":", "/" or "," character. If this is unset, a pedantic but overridable trust error is set. CERTDATAOPT_TIME: Current Time against which expiration dates of the certificates will be verified. Time has to be specified in number of seconds(uint32) since epoch time(6 January 1980). Note that if this OPT is not set; CertChain will skip time validation and allow expired certs to pass Chain Verification. CERTDATAOPT_OVERRIDE: You can have several of these to override several trust errors. See above discussion of CertDataTrustOverride for details. CERTDATAOPT_MAX_CHAIN: Maximum length we'll chain. Won't chain past CERTDATA_MAX_CHAIN no matter how large this value is. This is NOT the maximum number of certs that can be held in ICertChain. That is limited only by memory. Setting greater than CERTDATA_MAX_CHAIN are ignored. CERTDATA_MAX_CHAIN is the hard upper limit on the chain length. CERTDATAOPT_EXT_KEY_USE: A set of ASN1OIDs (see AEEASN1OIDS) that indicate the intended purpose of the cert chain. There may be several values for this option, with one purpose given as a 32 bit integer in pVal per option. If unset, no checking of the extended key usage extension in the cert is performed. An example value would be ASNOID_EXTKEYUSE_SRVRAUTH (SSL server authentication). CERTDATAOPT_KEY_USE: A single bit map giving the intended use of the cert should be place in pVal of this opt. The bit values should be one of ASNOID_KEYUSE_*. CERTDATAOPT_INSECURE_HASH_ASNOID: Called to pass in an ASNOID of a hash that cannot be used to verify a signature since it is considered to be insecure. If a signature trys to use on of these insecure hashes the operation is failed with CERTDATA_HASH_INSECURE. The xOpt value should be set to a uint32 ASNOID value. You can add several of these to provide prohibit the use of different hash classes. It is recommended that this feature be used to block the use of MD2 hashes since it is clearly known to be too weak. CERTDATAOPT_ASNOID_MAP: Used to pass an ASN Prefixes to ASNOIDs map to be used when passing new hash OIDs. The xOpt value parameter should contain an ASNOIDMap struct with the member pointers pcPrefixes and puASNOIDS set to arrays which will remain valid for the duration of the ICertChain_VerifyV() call. Example arrays: const uint8 pcOIDPrefixes[] = { '\x06','\x09','\x2a','\x86','\x48','\x86', '\xf7','\x0d','\x01','\x01', '\x06','\x05','\x2b','\x0e','\x03','\x02', '\x00','\x00'}; const uint32 puASNOIDs[] = { ASNOID_PKCS1, ASNOID_SECSIG, }; CERTDATAOPT_UNKNOWN_EXT_CB: Set the address of the user specified extension parsing callback routine. This routine is called if extension(s) matching the criteria specified by the client are encountered. See the definition of the PFNCERTCHAINEXT callback signature, as well as the description and example usage. CERTDATAOPT_UNKNOWN_EXT_CTX: Set a pointer to the data that the client callback routine will be invoked with. Typically this is the client context. See the definition of the PFNCERTCHAINEXT callback signature, as well as the description and example usage. CERTDATAOPT_UNKNOWN_EXT_ASN1OID: Enables the caller to specify a callback that can handle an unknown extension based on a match of the supplied ASN1OID. The caller may specify a value of ASNOID_ANY for the ASN1OID if he wishes to receive a callback for *all* unknown extensions. See the definition of the PFNCERTCHAINEXT callback signature, as well as the description and example usage. CERTDATAOPT_UNKNOWN_EXT_RAWOID: Enables the caller to specify a callback that can handle an unknown extension based on a match of the supplied raw OID. The caller may specify a NULL value of the OID itself if he wishes to receive a callback for *all* unknown extensions. See the definition of the PFNCERTCHAINEXT callback signature , as well as the description and example usage. CERTDATAOPT_PUBKEYENGINE: An interface to the public key crypto engine. By default the RSA software engine is used. Here the caller can substitute another, perhaps one that is faster or one that does something other than RSA. CERTDATAOPT_PUBKEYUTILS: Pass an interface to the public key parser here if you want a different one than the default. For example if you want to handle ECC keys, you can pass an interface that knows how to parse them. Here you can also adjust how signature algorithm identifiers map to hash function implementations. That is, you can substitute hash function implementations. CERTDATAOPT_ERROR_ON_BIG_RSA_EXP: This is not currently implemented. When non-zero RSA signature verification errors out when the RSA exponent is large (not 3, 17, or 65535). Signatures with these small exponents verify in much less than one second on most processors, where as larger exponents can take many seconds. It is recommended that this option be set when possible and particularly when verification is performed synchronously with the call back set to NULL. If the callback is NULL, keypress and other events are ignored during the time the RSA operation is being performed. CERTDATAOPT_CERTCHAIN_VERSION: Integer version number of this implementation. CERTDATAOPT_CERTCHAIN_FEATURES: Features bitmap. No special features are currently defined.