Closed
Bug 208649
Opened 22 years ago
Closed 22 years ago
CERT_CompareAVA compares improperly
Categories
(NSS :: Libraries, defect, P1)
Tracking
(Not tracked)
RESOLVED
FIXED
3.9
People
(Reporter: wtc, Assigned: nelson)
References
Details
Attachments
(2 files, 1 obsolete file)
|
4.69 KB,
patch
|
Details | Diff | Splinter Review | |
|
10.00 KB,
patch
|
Details | Diff | Splinter Review |
CERT_CompareAVA has an if statement with only
comments in its body. That if statement is
wrong. I believe that the comparison of the
AVAs' values should be inside the body of the
if statement.
| Reporter | ||
Comment 1•22 years ago
|
||
This is different from what I suggested earlier.
I thought 'rv' has the type SECStatus, but it
has the type SECComparison, so the meaning of
"if (rv)" is different.
| Assignee | ||
Comment 2•22 years ago
|
||
The logic of this function is certainly flawed.
The flaws go well beyond the fact that it ignores the attribute type.
There are actually 3 important characteristics of an AVA:
1. The attribute type (e.g. O, OU, L, ST, CN, etc.)
2. The encoding of the attribute value (e.g. IA5 string, T61 string,
printable string, UTF8 string, universal string, etc.)
3. The encoded value of the attribute.
It is true that if the attribute types do not match exactly, then the
function should indicate that they do not match.
If the types match but the encodings do not, then the two strings should
be converted to a common encoding for comparison. Further, for printable
encoding, RFC 3280 says:
(c) attribute values in PrintableString are not case sensitive
(d) attribute values in PrintableString are compared after
removing leading and trailing white space and converting internal
substrings of one or more consecutive white space characters to a
single space.
The function in question does not take value encoding into account, and
does not handle PrintableString any differently than the other encodings.
It's not immediately obvious how this function would determine what encoding
had been used in any particular AVA. The means by which that is done must
be determined before this can be fixed.
| Reporter | ||
Comment 3•22 years ago
|
||
Nelson, may I check in my patch first and leave the bug open
until the issue with encoding is also resolved?
| Assignee | ||
Comment 4•22 years ago
|
||
The logic change in the above patch seems fine.
Please remove the existing XXX comment and add one that reminds us that the
second SECITEM_CompareItem call neither does case insensitive comparison nor
whitespace canonicalization for the comparison of PrintableStrings.
| Assignee | ||
Comment 5•22 years ago
|
||
It appears that both of NSS's active ASN.1 decoders discard the information
about the encoding of the items. When a template specifies a particular
type of ASN.1 encoding, then the decoder checks that the actual encoding
matches the template. But when the template is an "ANY" template, the decoder
discards all information about the decoded object. The decoder tends to
set the "type" field of each decoded SECITEM to siBuffer (which is zero).
The template for an AVA is
static const SEC_ASN1Template cert_AVATemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAVA) },
{ SEC_ASN1_OBJECT_ID, offsetof(CERTAVA,type), },
{ SEC_ASN1_ANY, offsetof(CERTAVA,value), },
{ 0, }
};
Here are some ideas I have for changing the decoder and/or templates to
not lose the information about the encoding of the AVA values.
1. Stop using the SEC_ASN1_ANY type in the above template, and change
the template to use a SEC_ASN1_CHOICE of types that correspond to the
types expected in all known AVAs. Requires no change to the decoders,
and several changes to the templates. May or may not be possible to do
this and remain binary compatible with existing structures that correspond
to the existing templates. Might be possible if the decoder can store the
choice value in an unused secitem's type field.
2. Change the decoders to store the tag for a SEC_ASN1_ANY item into the
corresponding SECITEM's type field, which otherwise will contain siBuffer.
This should be fine for any code except code that expects/requires the
type field to contain siBuffer. It is doubtful that any existing code
cares about the value in item->type after the decoder finishes.
This option requires no change to any templates. or
3. Add another flag to the template, one that means "store the decoded tag
into the item's type field. Change the decoders to honor this flag.
The flag could work for types other than SEC_ASN1_ANY.
4. A variant of items 2-3 above. Change the declaration of SECITEM so
that the "type" field is just an unsigned short or unsigned char, and
use the remaining parts to store the decoded tag. Tag could conceivably
be store for ALL objects, not just ANYs, and without requirign a new flag.
Example: Change from
struct SECItemStr {
SECItemType type;
unsigned char *data;
unsigned int len;
};
to
struct SECItemStr {
unsigned short reserved;
unsigned char tag;
unsigned char type;
unsigned char *data;
unsigned int len;
};
5. another variant of 2-3. Store the tag in the type field shiften a few bits,
e.g. change the decoder from
item->type = siBuffer;
to
item->type = (SECItemType)(siBuffer | (tag << 8));
Note that GeneralNames have exactly the same problem as directoryName AVAs.
SO, of these choices, the options that store the tag in the item type
regardless of the template or tag type appeal to me the most because General
Names would benefit from this as well as directoryNames.
| Assignee | ||
Comment 6•22 years ago
|
||
Here's another point of information that may be relevant.
There's a function named CERT_DecodeAVAValue that takes as its argument the
address of the SECITEM corresponding to the ANY value. It clearly expects
that the "value" is still DER encoded, and has not had its DER encoding
removed. It expects that item->value[0] will be the tag. I'm not sure
that code is correct, but if it is then it will be pretty easy to fix
CERT_CompareAVA to pay proper attention to the encoding type.
But this may also mean that NSS needs different solutions for directoryNames
than for GeneralNames.
| Reporter | ||
Comment 7•22 years ago
|
||
Assigned the bug to Nelson.
I haven't checked in my patch. Please mark it obsolete
when you attach your patch.
Assignee: wtc → nelsonb
| Assignee | ||
Comment 8•22 years ago
|
||
Patch forthcoming
Status: NEW → ASSIGNED
Priority: -- → P1
Summary: CERT_CompareAVA has an incorrect if statement → CERT_CompareAVA compares improperly
Target Milestone: --- → 3.9
| Assignee | ||
Comment 9•22 years ago
|
||
Attachment #125246 -
Attachment is obsolete: true
| Assignee | ||
Comment 10•22 years ago
|
||
Checking in cert.h; new revision: 1.36; previous revision: 1.35
Checking in secname.c; new revision: 1.14; previous revision: 1.13
Status: ASSIGNED → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
| Assignee | ||
Comment 12•22 years ago
|
||
Since patch v1 above was deemed to contain unnecessary changes, when I produced
patch v2 above, I attempted to remove all the unnecessary changes. In the
process, I removed several NULL pointer tests that I had added in V1.
I decided to develop a series of smaller patches that could be applied
incrementally, that (together with patch v2) would add up to patch v1.
In the process of developing the first of these supplemental patches,
I discovered the null pointer tests that had been omitted from patch v2.
So, here is patch v3 which contains
a) the missing null pointer tests that I found
b) changes all PORT_*Alloc calls that allocate new structs or arrays of same
to use the PORT_*New* macros instead.
c) ifdefs out some dead functions that are rife with failure to detect
allocation failures.
You need to log in
before you can comment on or make changes to this bug.
Description
•