diff --git a/certread.c b/certread.c
--- a/security/nss/lib/pkcs7/certread.c
+++ b/security/nss/lib/pkcs7/certread.c
@@ -163,6 +163,14 @@ CERT_DecodeCertPackage(char *certbuf,
     SECStatus      rv;
     
     if ( certbuf == NULL ) {
+	PORT_SetError(SEC_ERROR_INVALID_ARGS);
+	return(SECFailure);
+    }
+    /* if there's not at least 6 bytes, there is no way we have a packaged
+     * certificate. 6 bytes get's us safely through the der tag/lengh
+     * decode below: tag 0x84 l1 l2 l3 l4 */
+    if (certlen < 6) {
+	PORT_SetError(SEC_ERROR_INPUT_LEN);
 	return(SECFailure);
     }
     
@@ -194,9 +202,11 @@ CERT_DecodeCertPackage(char *certbuf,
 	      case 1:
 		seqLen = cp[1];
 		break;
-	      default:
+	      case 0:
 		/* indefinite length */
 		seqLen = 0;
+	      default:
+		goto notder;
 	    }
 	    cp += ( seqLenLen + 1 );
 
@@ -219,7 +229,8 @@ CERT_DecodeCertPackage(char *certbuf,
 	
 	/* check the type string */
 	/* netscape wrapped DER cert */
-	if ( ( cp[0] == SEC_ASN1_OCTET_STRING ) &&
+	if ( ( certlen > seqLenLen + 4 + CERTIFICATE_TYPE_LEN ) &&
+	    ( cp[0] == SEC_ASN1_OCTET_STRING ) &&
 	    ( cp[1] == CERTIFICATE_TYPE_LEN ) &&
 	    ( PORT_Strcmp((char *)&cp[2], CERTIFICATE_TYPE_STRING) ) ) {
 	    
@@ -232,11 +243,16 @@ CERT_DecodeCertPackage(char *certbuf,
 	    rv = (* f)(arg, &pcertitem, 1);
 	    
 	    return(rv);
-	} else if ( cp[0] == SEC_ASN1_OBJECT_ID ) {
+	} else if ( ( certlen > seqLenLen + 3 ) &&
+		   ( cp[0] == SEC_ASN1_OBJECT_ID ) ) {
 	    SECOidData *oiddata;
 	    SECItem oiditem;
 	    /* XXX - assume DER encoding of OID len!! */
 	    oiditem.len = cp[1];
+	    if (certlen < seqLenLen + 4 + oiditem.len) {
+		PORT_SetError(SEC_ERROR_INPUT_LEN);
+		return(SECFailure);
+	    }
 	    oiditem.data = (unsigned char *)&cp[2];
 	    oiddata = SECOID_FindOID(&oiditem);
 	    if ( oiddata == NULL ) {
