]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_smime/lib/cmsdecode.c
Security-58286.260.20.tar.gz
[apple/security.git] / OSX / libsecurity_smime / lib / cmsdecode.c
index 765a1685f670dde02abe16f7a165438b961ce6ea..fdc69f3f74231e3934aa6612a343f9eb7268f485 100644 (file)
@@ -177,12 +177,15 @@ nss_cms_decoder_notify(void *arg, Boolean before, void *dest, int depth)
            if (nss_cms_before_data(p7dcx) != SECSuccess) {
                SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);     /* stop all processing */
                p7dcx->error = PORT_GetError();
            if (nss_cms_before_data(p7dcx) != SECSuccess) {
                SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);     /* stop all processing */
                p7dcx->error = PORT_GetError();
+                PORT_SetError(0); // Clean the thread error since we've returned the error
            }
        }
        if (after && dest == &(cinfo->rawContent)) {
            /* we're right after of the data */
            }
        }
        if (after && dest == &(cinfo->rawContent)) {
            /* we're right after of the data */
-           if (nss_cms_after_data(p7dcx) != SECSuccess)
+            if (nss_cms_after_data(p7dcx) != SECSuccess) {
                p7dcx->error = PORT_GetError();
                p7dcx->error = PORT_GetError();
+                PORT_SetError(0); // Clean the thread error since we've returned the error
+            }
 
            /* we don't need to see the contents anymore */
            SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);
 
            /* we don't need to see the contents anymore */
            SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);
@@ -380,9 +383,6 @@ static OSStatus
 nss_cms_after_end(SecCmsDecoderRef p7dcx)
 {
     OSStatus rv;
 nss_cms_after_end(SecCmsDecoderRef p7dcx)
 {
     OSStatus rv;
-    PLArenaPool *poolp;
-
-    poolp = p7dcx->cmsg->poolp;
 
     switch (p7dcx->type) {
     case SEC_OID_PKCS7_SIGNED_DATA:
 
     switch (p7dcx->type) {
     case SEC_OID_PKCS7_SIGNED_DATA:
@@ -488,6 +488,7 @@ nss_cms_decoder_work_data(SecCmsDecoderRef p7dcx,
                               data, len, final);
        if (rv != SECSuccess) {
            p7dcx->error = PORT_GetError();
                               data, len, final);
        if (rv != SECSuccess) {
            p7dcx->error = PORT_GetError();
+            PORT_SetError(0); // Clean the thread error since we've returned the error
            goto loser;
        }
 
            goto loser;
        }
 
@@ -603,6 +604,9 @@ SecCmsDecoderCreate(SecArenaPoolRef pool,
     SecCmsMessageRef cmsg;
     OSStatus result;
 
     SecCmsMessageRef cmsg;
     OSStatus result;
 
+    /* Clear the thread error to clean up dirty threads */
+    PORT_SetError(0);
+
     cmsg = SecCmsMessageCreate(pool);
     if (cmsg == NULL)
         goto loser;
     cmsg = SecCmsMessageCreate(pool);
     if (cmsg == NULL)
         goto loser;
@@ -636,6 +640,7 @@ SecCmsDecoderCreate(SecArenaPoolRef pool,
 
 loser:
     result = PORT_GetError();
 
 loser:
     result = PORT_GetError();
+    PORT_SetError(0); // Clean the thread error since we've returned the error
     return result;
 }
 
     return result;
 }
 
@@ -645,6 +650,10 @@ loser:
 OSStatus
 SecCmsDecoderUpdate(SecCmsDecoderRef p7dcx, const void *buf, CFIndex len)
 {
 OSStatus
 SecCmsDecoderUpdate(SecCmsDecoderRef p7dcx, const void *buf, CFIndex len)
 {
+    if (!p7dcx) {
+        return errSecParam;
+    }
+
     if (p7dcx->dcx != NULL && p7dcx->error == 0) {     /* if error is set already, don't bother */
        if (SEC_ASN1DecoderUpdate (p7dcx->dcx, buf, len) != SECSuccess) {
            p7dcx->error = PORT_GetError();
     if (p7dcx->dcx != NULL && p7dcx->error == 0) {     /* if error is set already, don't bother */
        if (SEC_ASN1DecoderUpdate (p7dcx->dcx, buf, len) != SECSuccess) {
            p7dcx->error = PORT_GetError();
@@ -663,7 +672,7 @@ SecCmsDecoderUpdate(SecCmsDecoderRef p7dcx, const void *buf, CFIndex len)
        (void) SEC_ASN1DecoderFinish (p7dcx->dcx);
        p7dcx->dcx = NULL;
     }
        (void) SEC_ASN1DecoderFinish (p7dcx->dcx);
        p7dcx->dcx = NULL;
     }
-    PORT_SetError (p7dcx->error);
+    PORT_SetError (0); // Clean the thread error since we've returned the error
 
     return p7dcx->error;
 }
 
     return p7dcx->error;
 }
@@ -674,11 +683,17 @@ SecCmsDecoderUpdate(SecCmsDecoderRef p7dcx, const void *buf, CFIndex len)
 void
 SecCmsDecoderDestroy(SecCmsDecoderRef p7dcx)
 {
 void
 SecCmsDecoderDestroy(SecCmsDecoderRef p7dcx)
 {
-    /* XXXX what about inner decoders? running digests? decryption? */
-    /* XXXX there's a leak here! */
-    SecCmsMessageDestroy(p7dcx->cmsg);
-    if (p7dcx->dcx)
+    /* SecCmsMessageDestroy frees inner decoders and digests. */
+    if (p7dcx->cmsg) {
+        SecCmsMessageDestroy(p7dcx->cmsg);
+    }
+    if (p7dcx->dcx) {
         (void)SEC_ASN1DecoderFinish(p7dcx->dcx);
         (void)SEC_ASN1DecoderFinish(p7dcx->dcx);
+    }
+    /* Clear out references */
+    p7dcx->cmsg = NULL;
+    p7dcx->dcx = NULL;
+    p7dcx->childp7dcx = NULL;
     PORT_Free(p7dcx);
 }
 
     PORT_Free(p7dcx);
 }
 
@@ -696,7 +711,9 @@ SecCmsDecoderFinish(SecCmsDecoderRef p7dcx, SecCmsMessageRef *outMessage)
     if (p7dcx->dcx == NULL || SEC_ASN1DecoderFinish(p7dcx->dcx) != SECSuccess ||
        nss_cms_after_end(p7dcx) != SECSuccess)
     {
     if (p7dcx->dcx == NULL || SEC_ASN1DecoderFinish(p7dcx->dcx) != SECSuccess ||
        nss_cms_after_end(p7dcx) != SECSuccess)
     {
-       SecCmsMessageDestroy(cmsg);     /* needs to get rid of pool if it's ours */
+        if (p7dcx->cmsg) {
+            SecCmsMessageDestroy(cmsg);        /* needs to get rid of pool if it's ours */
+        }
         result = PORT_GetError();
         goto loser;
     }
         result = PORT_GetError();
         goto loser;
     }
@@ -705,7 +722,12 @@ SecCmsDecoderFinish(SecCmsDecoderRef p7dcx, SecCmsMessageRef *outMessage)
     result = noErr;
 
 loser:
     result = noErr;
 
 loser:
+    /* Clear out references */
+    p7dcx->cmsg = NULL;
+    p7dcx->dcx = NULL;
+    p7dcx->childp7dcx = NULL;
     PORT_Free(p7dcx);
     PORT_Free(p7dcx);
+    PORT_SetError(0); // Clean the thread error since we've returned the error
     return result;
 }
 
     return result;
 }