summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornicolson%netscape.com <devnull@localhost>2002-03-26 01:13:23 +0000
committernicolson%netscape.com <devnull@localhost>2002-03-26 01:13:23 +0000
commitfd476cc36bc0675f09f7f9ca9fc7218f8d467e3c (patch)
tree21694a11241352bea0bca223d52eb3be2943136b
parent23a769af691b3354fa705688593bdb6cc5c142cc (diff)
downloadnss-hg-fd476cc36bc0675f09f7f9ca9fc7218f8d467e3c.tar.gz
Fix 130522: ASN.1 decoder asserts with corrupt input.
r=wtc
-rw-r--r--security/nss/lib/util/secasn1d.c46
1 files changed, 38 insertions, 8 deletions
diff --git a/security/nss/lib/util/secasn1d.c b/security/nss/lib/util/secasn1d.c
index b0f62b75c..4bb0e7d3f 100644
--- a/security/nss/lib/util/secasn1d.c
+++ b/security/nss/lib/util/secasn1d.c
@@ -1513,7 +1513,11 @@ sec_asn1d_next_substring (sec_asn1d_state *state)
if (state->pending) {
PORT_Assert (!state->indefinite);
- PORT_Assert (child_consumed <= state->pending);
+ if( child_consumed > state->pending ) {
+ PORT_SetError (SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return;
+ }
state->pending -= child_consumed;
if (state->pending == 0)
@@ -1628,7 +1632,11 @@ sec_asn1d_next_in_group (sec_asn1d_state *state)
*/
if (state->pending) {
PORT_Assert (!state->indefinite);
- PORT_Assert (child_consumed <= state->pending);
+ if( child_consumed > state->pending ) {
+ PORT_SetError (SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return;
+ }
state->pending -= child_consumed;
if (state->pending == 0) {
@@ -1694,7 +1702,11 @@ sec_asn1d_next_in_sequence (sec_asn1d_state *state)
sec_asn1d_free_child (child, PR_FALSE);
if (state->pending) {
PORT_Assert (!state->indefinite);
- PORT_Assert (child_consumed <= state->pending);
+ if( child_consumed > state->pending ) {
+ PORT_SetError (SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return;
+ }
state->pending -= child_consumed;
if (state->pending == 0) {
child->theTemplate++;
@@ -1739,8 +1751,13 @@ sec_asn1d_next_in_sequence (sec_asn1d_state *state)
*/
if (state->indefinite && child->endofcontents) {
PORT_Assert (child_consumed == 2);
- state->consumed += child_consumed;
- state->place = afterEndOfContents;
+ if( child_consumed != 2 ) {
+ PORT_SetError (SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ } else {
+ state->consumed += child_consumed;
+ state->place = afterEndOfContents;
+ }
} else {
PORT_SetError (SEC_ERROR_BAD_DER);
state->top->status = decodeError;
@@ -2090,8 +2107,12 @@ sec_asn1d_pop_state (sec_asn1d_state *state)
state->consumed += state->child->consumed;
if (state->pending) {
PORT_Assert (!state->indefinite);
- PORT_Assert (state->child->consumed <= state->pending);
- state->pending -= state->child->consumed;
+ if( state->child->consumed > state->pending ) {
+ PORT_SetError (SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ } else {
+ state->pending -= state->child->consumed;
+ }
}
state->child->consumed = 0;
}
@@ -2176,7 +2197,11 @@ sec_asn1d_during_choice
/* cargo'd from next_in_sequence innards */
if( state->pending ) {
PORT_Assert(!state->indefinite);
- PORT_Assert(child->consumed <= state->pending);
+ if( child->consumed > state->pending ) {
+ PORT_SetError (SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return NULL;
+ }
state->pending -= child->consumed;
if( 0 == state->pending ) {
/* XXX uh.. not sure if I should have stopped this
@@ -2432,6 +2457,11 @@ SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx,
/* We should not consume more than we have. */
PORT_Assert (consumed <= len);
+ if( consumed > len ) {
+ PORT_SetError (SEC_ERROR_BAD_DER);
+ cx->status = decodeError;
+ break;
+ }
/* It might have changed, so we have to update our local copy. */
state = cx->current;