Closed
Bug 357197
Opened 18 years ago
Closed 18 years ago
OCSP response code fails to match CERTIds
Categories
(NSS :: Libraries, defect)
Tracking
(Not tracked)
RESOLVED
FIXED
3.11.5
People
(Reporter: stevepnscp, Assigned: wtc)
References
Details
(Whiteboard: [hot fix in 3.11.4])
Attachments
(3 files, 4 obsolete files)
1.11 KB,
patch
|
wtc
:
review+
nelson
:
review+
|
Details | Diff | Splinter Review |
1.32 KB,
patch
|
nelson
:
review+
rrelyea
:
superreview+
|
Details | Diff | Splinter Review |
4.07 KB,
patch
|
nelson
:
review+
rrelyea
:
superreview+
|
Details | Diff | Splinter Review |
A customer is running into interop problems with their OCSP responders. Their OCSP responder is setting the 'parameters' field of the algorithm ID to an empty array. This is what they send: (gdb) print *certID2 $34 = {hashAlgorithm = {algorithm = {type = siBuffer, data = 0x92e081d "+\016\003\002\032\004\024�q��\021\n��\t�1A�&�`\004<�\001\004\024��)\214�w�\034(\bNwO��\023\021cA3\002\003\020�\220\200", len = 5}, parameters = {type = siBuffer, data = 0x0, len = 0}}, Our code in is calling SECOID_CompareAlgorithmID(), and expecting to match this against what we have calculated: (gdb) print *certID1 $33 = {hashAlgorithm = {algorithm = {type = siDEROID, data = 0x92d1290 "+\016\003\002\032���", len = 5}, parameters = { type = siBuffer, data = 0x92d12a0 "\005", len = 2}}, As you can see, we set 'parameters' to a 2-byte field. The code then falls through to the switch statement below. But the function exits early because foundHash is never set: ocsp.c: ocsp_CertIDsMatch() SECItem *foundHash = NULL; ... if (foundHash == NULL) { goto done; } ..
Reporter | ||
Comment 1•18 years ago
|
||
The upshot of all this is that the CERT_VerifyCertificate fails with SEC_ERROR_OCSP_UNKNOWN_CERT
Comment 2•18 years ago
|
||
Steve, is this a duplicate of bug 234129 ? In comment 0, you wrote: > Our code in [invalid character] is calling SECOID_CompareAlgorithmID() Please add comments to this bug (or to bug 234129, it this is a duplicate) showing the call stack for the affected call to SECOID_CompareAlgorithmID.
Reporter | ||
Comment 3•18 years ago
|
||
Yes, this bug is related to bug 234129. I have attached a patch which addresses the fall-through case. I have tested it against a responder which does not include the algorithm parameters. The fallthrough code does correctly match the certID, and the function returns properly.
Reporter | ||
Comment 4•18 years ago
|
||
Stack trace as requested: #0 SECOID_CompareAlgorithmID (a=0x908b208, b=0x909b7c0) at secalgid.c:171 #1 0x08060bf9 in ocsp_CertIDsMatch (handle=0x9077b88, certID1=0x908b208, certID2=0x909b7c0) at ocsp.c:2650 #2 0x08060da7 in ocsp_GetSingleResponseForCertID (responses=0x909b198, handle=0x9077b88, certID=0x908b208) at ocsp.c:2718 #3 0x080619c5 in CERT_GetOCSPStatusForCertID (handle=0x9077b88, response=0x9092a98, certID=0x908b208, signerCert=0x909e228, time=1161280433498756) at ocsp.c:3457 #4 0x080618b8 in CERT_CheckOCSPStatus (handle=0x9077b88, cert=0x9084108, time=1161280433498756, pwArg=0x0) at ocsp.c:3406 #5 0x08065f25 in CERT_VerifyCert (handle=0x9077b88, cert=0x9084108, checkSig=1, certUsage=certUsageSSLClient, t=1161280433498756, wincx=0x0, log=0x0) at certvfy.c:1635 #6 0x0804f23b in verify_cert (out_file=0x5625c0, handle=0x9077b88, cert_name=0xbff90960 "testcert", cert_usage=certUsageSSLClient, verify_time=1161280433498756) at ocspclnt.c:453 #7 0x08050887 in main (argc=7, argv=0xbff20d74) at ocspclnt.c:1197
Reporter | ||
Comment 5•18 years ago
|
||
One last thing - the mystery algorithm parameters that we're setting is a SEC_ASN1_NULL put in by this function: SECOID_SetAlgorithmID() I think this was put in to work around various bugs in other libraries which crash if this optional param is missing.
Comment 6•18 years ago
|
||
We should check the RFC. It may say that SHA1 must have an explicit NULL parameter value for backward compatibility. If it does then we should also notify the vendor. In any case there should be no security issue in ignoring the parameters for those hash functions we have explicitly in the switch table. bob
Comment 7•18 years ago
|
||
Comment on attachment 242780 [details] [diff] [review] fixes fallthrough case Since I suggested the fix, I think others should review it. bob
Attachment #242780 -
Flags: superreview?(nelson)
Attachment #242780 -
Flags: review?(wtchang)
Comment 8•18 years ago
|
||
Comment on attachment 242780 [details] [diff] [review] fixes fallthrough case > SECOidTag hashAlg; > SECItem *keyHash = NULL; > SECItem *nameHash = NULL; >@@ -2684,11 +2683,12 @@ ocsp_CertIDsMatch(CERTCertDBHandle *hand > nameHash = &certID1->issuerMD2NameHash; > break; > default: >- foundHash = NULL; >+ keyHash = NULL; >+ nameHash = NULL; keyHash and nameHash are already NULL here, so I see no reason to set them to NULL again. Why not just return PR_FALSE Here? > break; > } > >- if (foundHash == NULL) { >+ if (keyHash == NULL || nameHash == NULL) { In the above switch cases, the values assignd to keyHash and nameHash CANNOT be NULL, except in the default case where both will be null. For example, Even if certID1 is NULL, &certID1->issuerMD2NameHash is not. So testing both for NULL seems pointless. Testing one is sufficient. But why not goto done, or return PR_FALSE in the default case above? > goto done; > } > PORT_Assert(keyHash && nameHash); This old assert is silly now and should go. Final question. Do we care about other hashes, such as "SHA 2" hashes?
Reporter | ||
Comment 9•18 years ago
|
||
Thanks for your comments. This new patch gets rid of default case and the assertion.
Assignee | ||
Updated•18 years ago
|
Attachment #242780 -
Attachment is obsolete: true
Attachment #242780 -
Flags: superreview?(nelson)
Attachment #242780 -
Flags: review?(wtchang)
Assignee | ||
Comment 10•18 years ago
|
||
Comment on attachment 242890 [details] [diff] [review] New patch addressing Nelson's comments Steve, in NSS it's okay to use goto statements for error exits. Therefore, I suggest that you just change if (foundHash == NULL) { goto done; } to if (keyHash == NULL) { goto done; } You can keep a default case that does nothing but a break statement. (Some coding styles require every switch statement to have a default case.) Please ask Julien "Mr. OCSP" to review new patches. Someone should also look into the NULL parameters issue. The switch statement doesn't need to handle the SHA-2 algorithms because struct CERTOCSPCertIDStr doesn't have any members for those hash algorithms.
Attachment #242890 -
Flags: review+
Assignee | ||
Comment 11•18 years ago
|
||
*** This bug has been marked as a duplicate of 234129 ***
Status: NEW → RESOLVED
Closed: 18 years ago
Resolution: --- → DUPLICATE
Target Milestone: --- → 3.12
Comment 12•18 years ago
|
||
Since the patch and the action are in this bug, Let's close the old one as a dup. Also the target for this should be 3.11.4
Status: RESOLVED → REOPENED
Resolution: DUPLICATE → ---
Target Milestone: 3.12 → 3.11.4
Updated•18 years ago
|
Blocks: ocspdefault
Comment 13•18 years ago
|
||
*** Bug 234129 has been marked as a duplicate of this bug. ***
Comment 14•18 years ago
|
||
Bug 234129 should not be BOTH a duplicate of this bug, and a dependent of this bug. So I'm remving the dependency. Hopefully, as a result, bugzilla will stop sending me so many duplicate emails. :)
No longer blocks: 234129
Reporter | ||
Comment 15•18 years ago
|
||
In reference to wtc's comment 10, I think my patch is cleaner than having the goto: in there, so I would rather keep it as-is. I did incorporate another of wtc's suggestions - adding parens to match the style of the rest of the expression.
Attachment #242890 -
Attachment is obsolete: true
Attachment #242928 -
Flags: superreview?(nelson)
Attachment #242928 -
Flags: review?(julien.pierre.bugs)
Comment 16•18 years ago
|
||
Comment on attachment 242928 [details] [diff] [review] Additional parens around expression r=nelson
Attachment #242928 -
Flags: superreview?(nelson) → review+
Comment 17•18 years ago
|
||
RFC2560 doesn't specify the format of the parameters for AlgorithmIdentifier. It refers to RFC2459 which was superceded by RFC3280. RFC3280 defines AlgorithmIdentifier as : AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL } -- contains a value of the type -- registered for use with the -- algorithm object identifier value Unfortunately, RFC3280 doesn't go into more specifics about the parameters value either. It refers to RFC3279 for that . It speaks about hash functions MD2, MD5 and SHA-1 only. But it doesn't speak about the format of the parameters at all for these; whether it should be left out or a NULL value. My reading is that nothing should be encoded because the RFC is completely silent about the value, and the component is optional. It's possible someone else made a different reading and decided to encode a NULL. But I couldn't find anything that supported encoding a NULL value here. RFC3279 speaks at length about signature algorithms (hash with encryption) and the format of the parameters for those algorithms. But that's not what we are concerned with here. So, IMO, the responder is in error in encoding a NULL, and it's a bug on their part to encode it, not a bug on NSS' part to reject the OCSP response.
Reporter | ||
Comment 18•18 years ago
|
||
Julien - you got it backwards, NSS is encoding a NULL (in SECOID_SetAlgorithmID). The responder is not. Another fix for this would be to change SECOID_SetAlgorithmID to not encode the parameters, but that will have ramifications throughout every protocol NSS supports. We'd be trading the interop problem mentioned in this bug for potentially many more. If you feel strongly about that, I would suggest opening a different bug, because it affects so much more than just OCSP. Can we treat this bug about being more flexible with what NSS accepts, for OCSP only?
Comment 19•18 years ago
|
||
So just to be clear, the responder encoding NULL is the only one that currently works. I know that SHA-1 has some weirdness where the natural reading would lead one to believe that the parameters should not exist, but many implementations has an explicit NULL (I believe we had lots of problems with signatures going back to when I first joined the group). So the upshot, I think, is that there is nothing wrong with the empty parameters, and there is nothing else to do beyond fixing the NSS bug where it doesn't accept empty parameters for SHA1.
Comment 20•18 years ago
|
||
Steve, I think we should continue to encode the NULL on sending. That has become the defacto standard for the best compatibility. bob
Comment 21•18 years ago
|
||
The whole NULL-vs-empty debate was going on just before I joined Netscape in September '96. I wish I had some document(s) to cite for the decisions, but I've never seen any (to my knowledge).
Assignee | ||
Comment 22•18 years ago
|
||
We can handle the algorithm parameters similar to the way the callers of SGN_DecodeDigestInfo handle that field. http://lxr.mozilla.org/security/ident?i=SGN_DecodeDigestInfo Replace the SECOID_CompareAlgorithmID(...) == SECEqual test by (SECITEM_CompareItem(&certID1->hashAlgorithm.algorithm, &certID2->hashAlgorithm.algorithm) == SECEqual) && (certID2->hashAlgorithm.algorithm.parameters.len <= 2) You can also specifically test for a zero-length or NULL (SEC_ASN1_NULL) 'parameters'.
Comment 23•18 years ago
|
||
The latest patch was tested with an otherwise vanilla NSS 3.11.3 and mod_nss (tip) on Solaris 9 and the back OCSP behavior went away.
Assignee | ||
Comment 24•18 years ago
|
||
Steve, Rob, could you please test this patch, *without* Steve's patch (attachment 242928 [details] [diff] [review])? Thanks.
Comment 25•18 years ago
|
||
The hash algorithm patch works as well.
Assignee | ||
Comment 26•18 years ago
|
||
Comment on attachment 242928 [details] [diff] [review] Additional parens around expression I checked in Steve's patch on the NSS trunk (NSS 3.12) and the NSS_3_11_BRANCH (NSS 3.11.4). Checking in ocsp.c; /cvsroot/mozilla/security/nss/lib/certhigh/ocsp.c,v <-- ocsp.c new revision: 1.30; previous revision: 1.29 done Checking in ocsp.c; /cvsroot/mozilla/security/nss/lib/certhigh/ocsp.c,v <-- ocsp.c new revision: 1.21.2.8; previous revision: 1.21.2.7 done
Attachment #242928 -
Flags: review?(bugzilla) → review+
Assignee | ||
Comment 27•18 years ago
|
||
Comment on attachment 243708 [details] [diff] [review] Fix hash algorithm identifier comparison Let me know if you want me to not test certID1->hashAlgorithm.parameters, which comes from NSS and therefore is known to be NULL (two bytes 0x05 0x00). I can also define a macro for the certID2->hashAlgorithm.parameters.len <= 2 test so that we can use it in lib/softoken/pkcs11c.c and lib/cryptohi/secvfy.c as well (search for "> 2" in those two files). Something like this: /* * For all the supported hash algorithms, 'parameters' is NULL (two * bytes 0x05 0x00), but we allow it to be missing (zero length). */ #define IS_VALID_HASH_ALG_PARAMS(params) ((params)->len <= 2)
Attachment #243708 -
Flags: review?(nelson)
Assignee | ||
Updated•18 years ago
|
Assignee: nobody → wtchang
Status: REOPENED → NEW
Whiteboard: [hot fix in 3.11.4]
Comment 28•18 years ago
|
||
Comment on attachment 243708 [details] [diff] [review] Fix hash algorithm identifier comparison r=nelson
Attachment #243708 -
Flags: review?(nelson) → review+
Assignee | ||
Updated•18 years ago
|
Attachment #243708 -
Flags: superreview?(rrelyea)
Assignee | ||
Comment 29•18 years ago
|
||
I found that we never examine certID2->hashAlgorithm.parameters, other than comparing it with certID1->hashAlgorithm.parameters. It seems that we should reject certID2 if certID2->hashAlgorithm.parameters is bogus. This more strict patch does that. Please let me know if you prefer this patch to the previous patch (attachment 243708 [details] [diff] [review]). With the previous patch, certID2 with a bogus hashAlgorithm.parameters still gets a second chance in the fallthrough code (the switch statement).
Attachment #245603 -
Flags: review?(nelson)
Comment 30•18 years ago
|
||
Comment on attachment 243708 [details] [diff] [review] Fix hash algorithm identifier comparison r+=relyea
Attachment #243708 -
Flags: superreview?(rrelyea) → superreview+
Assignee | ||
Comment 31•18 years ago
|
||
Comment on attachment 243708 [details] [diff] [review] Fix hash algorithm identifier comparison I checked in this patch "fix hash algorithm identifier comparison" on the NSS trunk (NSS 3.12) and the NSS_3_11_BRANCH (NSS 3.11.5). Checking in ocsp.c; /cvsroot/mozilla/security/nss/lib/certhigh/ocsp.c,v <-- ocsp.c new revision: 1.31; previous revision: 1.30 done Checking in ocsp.c; /cvsroot/mozilla/security/nss/lib/certhigh/ocsp.c,v <-- ocsp.c new revision: 1.21.2.9; previous revision: 1.21.2.8 done
Assignee | ||
Comment 32•18 years ago
|
||
I explained this patch in comment 29. I think we should reject a hash algorithm identifier that contains a bogus 'parameters', not allowing it to fall through to the switch statement below. Agree? Recall that the switch statement didn't work before. Now that Steve's patch fixed it, we should also check in this patch to match the previous behavior (hash algid with bogus parameters didn't work before).
Attachment #245603 -
Attachment is obsolete: true
Attachment #247616 -
Flags: superreview?(rrelyea)
Attachment #247616 -
Flags: review?(nelson)
Attachment #245603 -
Flags: review?(nelson)
Comment 33•18 years ago
|
||
Comment on attachment 247616 [details] [diff] [review] Reject hash algorithm identifier with bogus 'parameters' On its surface, function ocsp_CertIDsMatch appears to take two similar objects and compare them. The names of the two CertID arguments do not suggest that one is fundamentally different from the other, and the block comment also does not suggest it. But the code treats the two CertID argument values asymmetrically. The code "knows" that certID1 is a value on which we have previously computed 3 different hashes, and that certID2 is a value returned in an OCSP response, and contains only one remotely computed hash value. So, it finds the locally computed hash value for certID1 that was computed using the same hash used in certID2, and compares those two values. This patch further increases the asymmetry. It performs a validity check only on certID2, that it does not also perform on certID1. This is apparently due to a (probably reasonable) assumption that we properly encoded the hash parameter in certID1. I think that, at a minimum, there should be a block comment explaining this, so that future readers of this code are given some explanation for the asymmetric treatment. I would go further and suggest that the two pointers be renamed from certID1 and certID2 to "local" and "remote" or "request" and "response", (or "reference" and "suspected" :) to further clarify this difference. I am a little concerned that this patch will cause failures to occur in cases where they previously were not occuring, and may be seen as a failure of backwards binary compatibility. If some broken OCSP responder is sending out bad parameters, we might have been blissfully ignoring them before, and now we will fail. We will have to explain to customers that our product doesn't work any more because of a problem that some other product has had all along, and the question will be why did we break backwards compatibility. I am weary of those questions. Unless we can show that there is a vulnerability being actively thwarted by this change, I am reluctant to approve it.
Assignee | ||
Comment 34•18 years ago
|
||
Nelson, I improved the comment and renamed the certID1 and certID2 parameters as you suggested to make the asymmetry between the two parameters clear. The longer parameter names required me to reformat some code to wrap long lines. This patch does not break backward compatibility because a response certID with bogus hash algorithm parameters never worked before. Let me explain this subtle point. In NSS releases <= 3.11.3, such a response certID - fails the binary comparison with the request certID - falls through to the broken switch statement, and fails again Steve's hot fix fixed the broken switch statement, so in NSS 3.11.4, it - fails the binary comparison with the request certID - falls through to the switch statement, and succeeds This patch will make it fail again. It will - fail the "parameters" test - NOT fall through to the switch statement So this patch only breaks backward compatibility with NSS 3.11.4. It is backward compatible with all NSS releases <= 3.11.3.
Attachment #247616 -
Attachment is obsolete: true
Attachment #247920 -
Flags: superreview?(rrelyea)
Attachment #247920 -
Flags: review?(nelson)
Attachment #247616 -
Flags: superreview?(rrelyea)
Attachment #247616 -
Flags: review?(nelson)
Assignee | ||
Comment 35•18 years ago
|
||
Just to make one point clear -- Steve's hot fix allows a response certID with *missing* hash algorithm parameters, but it has the subtle, unintended side effect of also allowing a response certID with *bogus* hash algorithm parameters. Since this side effect is unintended, we should remove it. I shouldn't need to show it's a vulnerability.
Comment 36•18 years ago
|
||
Comment on attachment 247920 [details] [diff] [review] Reject hash algorithm identifier with bogus 'parameters' v2 r=nelson Thanks, Wan-Teh. This is a big improvement!
Attachment #247920 -
Flags: review?(nelson) → review+
Assignee | ||
Comment 37•18 years ago
|
||
Comment on attachment 247920 [details] [diff] [review] Reject hash algorithm identifier with bogus 'parameters' v2 I checked in the patch "reject hash algorithm identifier with bogus 'parameters' v2" on the NSS trunk (NSS 3.12). Checking in ocsp.c; /cvsroot/mozilla/security/nss/lib/certhigh/ocsp.c,v <-- ocsp.c new revision: 1.32; previous revision: 1.31 done
Assignee | ||
Updated•18 years ago
|
Status: NEW → ASSIGNED
Target Milestone: 3.11.4 → 3.11.5
Comment 38•18 years ago
|
||
Comment on attachment 247920 [details] [diff] [review] Reject hash algorithm identifier with bogus 'parameters' v2 r+ = relyea. I'm a little worried about the hardcoded param > 2. It's fine for all existing hash algorithms, but future ones could include valid parameters which are greater than 2 (I can't conceive of one right now, though). The patch is OK, though because a) it's no worse than the existing code it corrects, and b) we would need to rework this section of OCSP if we need to support hashes otther than MD5, MD2 or SHA1 (supporting SHA256 and SHA512 would require changes to the OSCP code, even though NSS already supports these hashes, for example). bob
Attachment #247920 -
Flags: superreview?(rrelyea) → superreview+
Assignee | ||
Comment 39•18 years ago
|
||
The hardcoded param > 2 was copied from existing code in lib/cryptohi/secvfy.c and lib/softoken/pkcs11c.c. I checked in the patch "reject hash algorithm identifier with bogus 'parameters' v2" on the NSS_3_11_BRANCH (NSS 3.11.5). Checking in ocsp.c; /cvsroot/mozilla/security/nss/lib/certhigh/ocsp.c,v <-- ocsp.c new revision: 1.21.2.10; previous revision: 1.21.2.9 done
Status: ASSIGNED → RESOLVED
Closed: 18 years ago → 18 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•