Index: nss/mozilla/security/nss/lib/util/quickder.c |
=================================================================== |
--- nss/mozilla/security/nss/lib/util/quickder.c (revision 142244) |
+++ nss/mozilla/security/nss/lib/util/quickder.c (working copy) |
@@ -815,40 +815,57 @@ |
SECItem newtemp = temp; |
rv = GetItem(&newtemp, &temp, PR_FALSE); |
save = PR_TRUE; |
- if ((SECSuccess == rv) && SEC_ASN1_UNIVERSAL == (kind & SEC_ASN1_CLASS_MASK)) |
- switch (kind & SEC_ASN1_TAGNUM_MASK) |
+ if ((SECSuccess == rv) && |
+ SEC_ASN1_UNIVERSAL == (kind & SEC_ASN1_CLASS_MASK)) |
{ |
- /* special cases of primitive types */ |
- case SEC_ASN1_INTEGER: |
+ unsigned long tagnum = kind & SEC_ASN1_TAGNUM_MASK; |
+ if ( temp.len == 0 && (tagnum == SEC_ASN1_BOOLEAN || |
+ tagnum == SEC_ASN1_INTEGER || |
+ tagnum == SEC_ASN1_BIT_STRING || |
+ tagnum == SEC_ASN1_OBJECT_ID || |
+ tagnum == SEC_ASN1_ENUMERATED || |
+ tagnum == SEC_ASN1_UTC_TIME || |
+ tagnum == SEC_ASN1_GENERALIZED_TIME) ) |
{ |
- /* remove leading zeroes if the caller requested siUnsignedInteger |
- This is to allow RSA key operations to work */ |
- SECItem* destItem = (SECItem*) ((char*)dest + templateEntry->offset); |
- if (destItem && (siUnsignedInteger == destItem->type)) |
+ /* these types MUST have at least one content octet */ |
+ PORT_SetError(SEC_ERROR_BAD_DER); |
+ rv = SECFailure; |
+ } |
+ else |
+ switch (tagnum) |
+ { |
+ /* special cases of primitive types */ |
+ case SEC_ASN1_INTEGER: |
{ |
- while (temp.len > 1 && temp.data[0] == 0) |
- { /* leading 0 */ |
- temp.data++; |
- temp.len--; |
+ /* remove leading zeroes if the caller requested |
+ siUnsignedInteger |
+ This is to allow RSA key operations to work */ |
+ SECItem* destItem = (SECItem*) ((char*)dest + |
+ templateEntry->offset); |
+ if (destItem && (siUnsignedInteger == destItem->type)) |
+ { |
+ while (temp.len > 1 && temp.data[0] == 0) |
+ { /* leading 0 */ |
+ temp.data++; |
+ temp.len--; |
+ } |
} |
+ break; |
} |
- break; |
- } |
- case SEC_ASN1_BIT_STRING: |
- { |
- /* change the length in the SECItem to be the number of bits */ |
- if (temp.len && temp.data) |
+ case SEC_ASN1_BIT_STRING: |
{ |
- temp.len = (temp.len-1)*8 - ((*(unsigned char*)temp.data) & 0x7); |
- temp.data = (unsigned char*)(temp.data+1); |
+ /* change the length in the SECItem to be the number |
+ of bits */ |
+ temp.len = (temp.len-1)*8 - (temp.data[0] & 0x7); |
+ temp.data++; |
+ break; |
} |
- break; |
- } |
- default: |
- { |
- break; |
+ default: |
+ { |
+ break; |
+ } |
} |
} |
} |
@@ -863,7 +880,7 @@ |
If part of the destination was allocated by the decoder, in |
cases of POINTER, SET OF and SEQUENCE OF, then type is set to |
siBuffer due to the use of PORT_ArenaZAlloc*/ |
- destItem->data = temp.data; |
+ destItem->data = temp.len ? temp.data : NULL; |
destItem->len = temp.len; |
} |
else |