Open
Bug 433108
Opened 16 years ago
Updated 6 months ago
Can't delete nssCertificate without calling fill_CERTCertificateFields
Categories
(NSS :: Libraries, defect, P5)
NSS
Libraries
Tracking
(Not tracked)
NEW
People
(Reporter: nelson, Unassigned)
Details
There needs to be a way to destroy the nssCertificate and the corresponding CERTCertificate, even if one or both are not completely filled in, without completely filling them in, just to destroy them. This is a HUGE waste of cycles. We do this for every cert that we pull out of the cert DB in the course of validating a cert chain. In Stan functions nssCertificateArray_Destroy() and cert_destroyObject(), both of which try to destroy certificate objects, we see code like this: NSSCertificate *c = (NSSCertificate *)o; if (c->decoding) { CERTCertificate *cc = STAN_GetCERTCertificate(c); if (cc) { CERT_DestroyCertificate(cc); return; } /* else destroy it as NSSCertificate below */ } nssCertificate_Destroy(c); STAN_GetCERTCertificate() checks to see that c->decoding is non-NULL, and if so, it returns cc = (CERTCertificate *)c->decoding->data; But before returning, it checks cc->nssCertificate, and if that is NULL the code calls fill_CERTCertificateFields() to fill in all sorts of fields in the nssCertificate. This includes such things as looking through all the tokens for a matching private key, which in turn involves searching through all the private keys in the token, because of bug 433105. So, we go through all this enormous waste of CPU cycles, to completely fill in the nssCertificate, WHICH WILL BE IMMEDIATELY DESTROYED. I am conducting some experiments to see if there is an easier way to do this destruction without all that waste.
Reporter | ||
Updated•16 years ago
|
Summary: Can't delete nssCertificate without calling → Can't delete nssCertificate without calling fill_CERTCertificateFields
Reporter | ||
Comment 1•16 years ago
|
||
There are more functions that do this same thing. The list now includes nssCertificateArray_Destroy() cert_destroyObject(), CERT_CertChainFromCert(), STAN_GetCERTCertificateOrRelease(),
Reporter | ||
Comment 2•16 years ago
|
||
The issue is seen when the nssCertificate and its corresponding CERTCertificate have the following relationship: nssCertificate .object.refCount == 2 ->decoding->data == & CertCertificate CERTCertificate .referenceCount == 1 .nssCertificate == NULL; I don't know how they get into that state, nor what code leaves them in that state. I think we should have a name for this state (besides "broken" :). The code shown in comment 0 has the effect of increasing the referenceCOunt in the CERTCertificate, and changing its nssCertificate pointer to point at the corresponding nssCertificate. By itself, that would be OK, I think, but the problem is all the other huge amount of time spent filling in all sorts of fields in the two structures that is entirely wasted effort, and that can have unexpected side effects, such as setting the error code.
Reporter | ||
Comment 3•16 years ago
|
||
Two corrections to previous comments. a) In comment 2, I wrote: > The code shown in comment 0 has the effect of increasing the referenceCount > in the CERTCertificate, and changing its nssCertificate pointer to point at > the corresponding nssCertificate. That is untrue. It does NOT increase the CERTCertificate's referenceCount. It makes no changes to the reference count in either the CERTCertificate nor the nssCertificate. It DOES change CERTCertificate's nssCertificate pointer to point at the corresponding nssCertificate, among other changes. b) in comment 1, I stated there are 4 functions that are candidates to be changed. That is untrue. STAN_GetCERTCertificateOrRelease() is not a candidate. The correct list of functions that should stop filling in cert fields just to destroy the cert is: nssCertificateArray_Destroy() cert_destroyObject(), CERT_CertChainFromCert() I have been trying to build a new function to replace the common body of code shown in comment 0. Nothing I have tried so far has had acceptable results. Bob, you're our Stan code expert. If you understand how/why the certs get into this imbalanced state, where nssCertificate points at CERTCertificate, but CERTCertificate does not point to nssCertificate, and understand how to destroy such an nssCertificate without having to fill in all the fields first, please take this bug, or at least share your thoughts. Thanks.
Target Milestone: --- → 3.12.1
Reporter | ||
Comment 4•16 years ago
|
||
I have found something that seems to work, partially. It avoids the calls
that attempt to fill in all the cert fields just before the certs are
destroyed. But it doesn't solve the problem of CERT_VerifyCert reporting
SEC_ERROR_BAD_DATABASE when using an error log. :(
The thing that seems to work is this:
>- if (c->decoding) {
>+ if (c->decoding && (!c->decoding->data ||
>+ ((CERTCertificate*)(c->decoding->data))->nssCertificate != 0)) {
This has the effect that, when c->decoding is non-NULL, and
c->decoding->data (which is really the CERTCertificate address) is non-NULL,
but that CERTCertificate's nssCertificate pointer IS NULL, then just fall
through to the line that calls nssCertificate_Destroy(c).
Of course, this is not a good patch. For one thing, accesses to parts of
c->decoding should be protected by the c object lock. But I can see writing
a function named STAN_GetCERTCertificateToDestroy that does the right thing.
I'd write that patch, but I still haven't solved the problem of the bogus
SEC_ERROR_BAD_DATABASE errors, and that's what I really want to solve.
I can't help but wonder if this is a new problem in 3.12. Perhaps it is a
consequence of having libNSS3 and libsoftokn3 both use a common underlying
libutil shared library?
Reporter | ||
Comment 5•15 years ago
|
||
Unsetting target milestone in unresolved bugs whose targets have passed.
Target Milestone: 3.12.1 → ---
Updated•2 years ago
|
Severity: normal → S3
Updated•6 months ago
|
Severity: S3 → S4
Priority: -- → P5
You need to log in
before you can comment on or make changes to this bug.
Description
•