зеркало из https://github.com/mozilla/pjs.git
Fix for 280121 - allow encoding simple templates with SEC_ASN1_INLINE and SEC_ASN1_OPTIONAL . r=nelson
This commit is contained in:
Родитель
72086cda85
Коммит
63464b4cb3
|
@ -39,7 +39,7 @@
|
|||
* Encoding Rules). The routines are found in and used extensively by the
|
||||
* security library, but exported for other use.
|
||||
*
|
||||
* $Id: secasn1.h,v 1.12 2004-04-25 15:03:18 gerv%gerv.net Exp $
|
||||
* $Id: secasn1.h,v 1.13 2005-04-09 05:06:34 julien.pierre.bugs%sun.com Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SECASN1_H_
|
||||
|
@ -183,6 +183,11 @@ extern const SEC_ASN1Template *
|
|||
SEC_ASN1GetSubtemplate (const SEC_ASN1Template *inTemplate, void *thing,
|
||||
PRBool encoding);
|
||||
|
||||
/* whether the template is for a primitive type or a choice of
|
||||
* primitive types
|
||||
*/
|
||||
extern PRBool SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/*
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
* Support for ENcoding ASN.1 data based on BER/DER (Basic/Distinguished
|
||||
* Encoding Rules).
|
||||
*
|
||||
* $Id: secasn1e.c,v 1.18 2004-07-13 06:02:54 nelsonb%netscape.com Exp $
|
||||
* $Id: secasn1e.c,v 1.19 2005-04-09 05:06:34 julien.pierre.bugs%sun.com Exp $
|
||||
*/
|
||||
|
||||
#include "secasn1.h"
|
||||
|
@ -193,6 +193,7 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state)
|
|||
unsigned char tag_modifiers;
|
||||
unsigned long encode_kind, under_kind;
|
||||
unsigned long tag_number;
|
||||
PRBool isInline = PR_FALSE;
|
||||
|
||||
|
||||
encode_kind = state->theTemplate->kind;
|
||||
|
@ -222,7 +223,7 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state)
|
|||
} else if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) ||
|
||||
(!universal && !isExplicit)) {
|
||||
const SEC_ASN1Template *subt;
|
||||
void *src;
|
||||
void *src = NULL;
|
||||
|
||||
PORT_Assert ((encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) == 0);
|
||||
|
||||
|
@ -231,6 +232,7 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state)
|
|||
if (encode_kind & SEC_ASN1_POINTER) {
|
||||
src = *(void **)state->src;
|
||||
state->place = afterPointer;
|
||||
|
||||
if (src == NULL) {
|
||||
/*
|
||||
* If this is optional, but NULL, then the field does
|
||||
|
@ -249,8 +251,9 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state)
|
|||
src = state->src;
|
||||
if (encode_kind & SEC_ASN1_INLINE) {
|
||||
/* check that there are no extraneous bits */
|
||||
PORT_Assert (encode_kind == SEC_ASN1_INLINE && !optional);
|
||||
/* PORT_Assert (encode_kind == SEC_ASN1_INLINE && !optional); */
|
||||
state->place = afterInline;
|
||||
isInline = PR_TRUE;
|
||||
} else {
|
||||
/*
|
||||
* Save the tag modifiers and tag number here before moving
|
||||
|
@ -268,6 +271,22 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state)
|
|||
}
|
||||
|
||||
subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->src, PR_TRUE);
|
||||
if (isInline && optional) {
|
||||
/* we only handle a very limited set of optional inline cases at
|
||||
this time */
|
||||
if (PR_FALSE != SEC_ASN1IsTemplateSimple(subt)) {
|
||||
/* we now know that the target is a SECItem*, so we can check
|
||||
if the source contains one */
|
||||
SECItem* target = (SECItem*)state->src;
|
||||
if (!target || !target->data || !target->len) {
|
||||
/* no valid data to encode subtemplate */
|
||||
return state;
|
||||
}
|
||||
} else {
|
||||
PORT_Assert(0); /* complex templates are not handled as
|
||||
inline optional */
|
||||
}
|
||||
}
|
||||
state = sec_asn1e_push_state (state->top, subt, src, PR_FALSE);
|
||||
if (state == NULL)
|
||||
return state;
|
||||
|
@ -552,7 +571,21 @@ sec_asn1e_contents_length (const SEC_ASN1Template *theTemplate, void *src,
|
|||
}
|
||||
} else if (encode_kind & SEC_ASN1_INLINE) {
|
||||
/* check that there are no extraneous bits */
|
||||
PORT_Assert (encode_kind == SEC_ASN1_INLINE && !optional);
|
||||
if (optional) {
|
||||
if (PR_FALSE != SEC_ASN1IsTemplateSimple(theTemplate)) {
|
||||
/* we now know that the target is a SECItem*, so we can check
|
||||
if the source contains one */
|
||||
SECItem* target = (SECItem*)src;
|
||||
if (!target || !target->data || !target->len) {
|
||||
/* no valid data to encode subtemplate */
|
||||
*noheaderp = PR_TRUE;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
PORT_Assert(0); /* complex templates not handled as inline
|
||||
optional */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
src = (char *)src + theTemplate->offset;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
/*
|
||||
* Utility routines to complement the ASN.1 encoding and decoding functions.
|
||||
*
|
||||
* $Id: secasn1u.c,v 1.3 2004-04-25 15:03:18 gerv%gerv.net Exp $
|
||||
* $Id: secasn1u.c,v 1.4 2005-04-09 05:06:34 julien.pierre.bugs%sun.com Exp $
|
||||
*/
|
||||
|
||||
#include "secasn1.h"
|
||||
|
@ -107,3 +107,25 @@ SEC_ASN1GetSubtemplate (const SEC_ASN1Template *theTemplate, void *thing,
|
|||
}
|
||||
return subt;
|
||||
}
|
||||
|
||||
PRBool SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate)
|
||||
{
|
||||
if (!theTemplate) {
|
||||
return PR_TRUE; /* it doesn't get any simpler than NULL */
|
||||
}
|
||||
/* only templates made of one primitive type or a choice of primitive
|
||||
types are considered simple */
|
||||
if (! (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK))) {
|
||||
return PR_TRUE; /* primitive type */
|
||||
}
|
||||
if (!theTemplate->kind & SEC_ASN1_CHOICE) {
|
||||
return PR_FALSE; /* no choice means not simple */
|
||||
}
|
||||
while (++theTemplate && theTemplate->kind) {
|
||||
if (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK)) {
|
||||
return PR_FALSE; /* complex type */
|
||||
}
|
||||
}
|
||||
return PR_TRUE; /* choice of primitive types */
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче