Closed
Bug 122909
Opened 23 years ago
Closed 4 months ago
NSS lacks sample code for CERT_VerifyCert's error log
Categories
(NSS :: Documentation, enhancement, P3)
Tracking
(Not tracked)
RESOLVED
INACTIVE
People
(Reporter: nelson, Unassigned)
Details
NSS's CERT_VerifyCert function has a valuable feature called the error log. There is no documentation on how to use (AFAIK), and none of the NSS command tools use it. At least one of them should show how to use it. I nominate tstclnt as the tool of choice for this purpose, but others might be good for this, too. Here's some documentation on how to use the feature that I wrote up recently. The "error log" is a feature of only one function in NSS, the function CERT_VerifyCert(). No other public NSS function has this feature, not even CERT_VerifyCertNow(). The last argument to CERT_VerifyCert is a pointer to a CERTVerifyLog , which is a structure declared in NSS in the header file certt.h. If this argument is null, CERT_VerifyCert stops at the first error it encounters while verifying a cert chain, and returns the first error code it encountered via the usual error mechanism. If the last argument is non-null, CERT_VerifyCert performs the cert chain verification until it is all done, or until it encounters some error that makes it unable to go any further. It does not stop at the first error it encounters. Each error it encounters is placed into the error log. After it returns, the caller can examine the error log structure to see if it contains any errors, and can then deal with them. The error log structure contains head and tail pointers to a doubly-linked list of CERTVerifyLogNode structures that are allocated from an ArenaPool. It also contains a count of the number of error log nodes in the list, and a pointer to the arena pool from which they have been allocated. struct CERTVerifyLogStr { PRArenaPool *arena; unsigned int count; struct CERTVerifyLogNodeStr *head; struct CERTVerifyLogNodeStr *tail; }; For each error, a Log node is created and added to the linked list. The log nodes look like this: struct CERTVerifyLogNodeStr { CERTCertificate *cert; /* what cert had the error */ long error; /* what error was it? */ unsigned int depth; /* how far up the chain are we */ void *arg; /* error specific argument */ struct CERTVerifyLogNodeStr *next; /* next in the list */ struct CERTVerifyLogNodeStr *prev; /* next in the list */ }; Each CERTVerifyLogNode struct contains the following things: 1. a reference to the CERTCertificate structure for the cert that failed the test. This reference must be released to avoid leaking the cert. 2. an error code indiciating the particular problem 3. the "depth" in the cert chain where the error occurred (depth is distance down the chain from the leaf). Errors on the leaf cert itself have depth of zero. 4. an "argument" whose meaning depends on the particular error code given 5. The pointers the in the chain. The error log is sorted by increasing "depth". Because of the sorting, the errors may not appear in the log in the same order in which they were generated. All the errors of a given depth __should__ refer to the same cert. If they don't, I think that's a bug. How to use it: Prior to calling CERT_VerifyCert, one allocates a CERTVerifyLog and initializes it, e.g. CERTVerifyLog log; log.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( log.arena == NULL ) { goto done; } log.head = NULL; log.tail = NULL; log.count = 0; Then one passes it to CERT_VerifyCert, like so: CERT_VerifyCert(cert->dbhandle, cert, PR_TRUE, certUsage, PR_GMT(), proto_win, &log); ^^^^ Afterwords, one checks for errors and handles them, as in this example: if ( log.count > 0 ) { CERTVerifyLogNode *node = log.head; while ( node ) { int error = node->error; /* deal with the error code */ /* free the reference to the cert */ CERT_DestroyCertificate(node->cert); node = node->next; } } /* end of log.count > 0 */ Finally, one frees the arena from which the error log nodes may have been allocated: if ( log.arena != NULL ) { PORT_FreeArena(log.arena, PR_FALSE); } The "arg" in the log node depends on the error code. Here is a list of the error codes that return non-null values for arg, and what the args mean: SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID arg is the path length limit (an int) that was exceeded SEC_ERROR_INADEQUATE_KEY_USAGE arg is the required key usage (an int) SEC_ERROR_EXPIRED_CERTIFICATE arg is a SECCertTimeValidity value (an enumerated type) SEC_ERROR_INADEQUATE_CERT_TYPE arg is the requiredCertType (an int) SEC_ERROR_UNTRUSTED_CERT arg is the trust flags (an int, bits have individual meaning) In no case is "arg" ever a pointer, even though it is declared as a void *.
Updated•23 years ago
|
Component: Tools → Documentation
Comment 1•22 years ago
|
||
Changed the QA contact to Bishakha.
QA Contact: sonja.mirtitsch → bishakhabanerjee
Reporter | ||
Comment 2•21 years ago
|
||
I think one or more NSS commands now use the error log feature, so maybe this bug is now resolved fixed.
Priority: -- → P3
Reporter | ||
Updated•19 years ago
|
QA Contact: bishakhabanerjee → jason.m.reid
Reporter | ||
Updated•18 years ago
|
Assignee: wtchang → nobody
QA Contact: jason.m.reid → documentation
Updated•2 years ago
|
Severity: normal → S3
Updated•4 months ago
|
Status: NEW → RESOLVED
Closed: 4 months ago
Resolution: --- → INACTIVE
You need to log in
before you can comment on or make changes to this bug.
Description
•