]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_smime/lib/cmsdecode.c
Security-58286.41.2.tar.gz
[apple/security.git] / libsecurity_smime / lib / cmsdecode.c
index 29f501c896304fc3a261a5e785b13897a5826766..2dd6f8ac8e3fad7e65bdc53a61e4b86d15b2aa9a 100644 (file)
@@ -283,7 +283,7 @@ nss_cms_before_data(SecCmsDecoderRef p7dcx)
        goto loser;
 
     /* start the child decoder */
-    childp7dcx->dcx = SEC_ASN1DecoderStart(poolp, childp7dcx->content.pointer, template, NULL);
+    childp7dcx->dcx = SEC_ASN1DecoderStart(poolp, childp7dcx->content.pointer, template, NULL, 0);
     if (childp7dcx->dcx == NULL)
        goto loser;
 
@@ -374,9 +374,6 @@ static OSStatus
 nss_cms_after_end(SecCmsDecoderRef p7dcx)
 {
     OSStatus rv;
-    PLArenaPool *poolp;
-
-    poolp = p7dcx->cmsg->poolp;
 
     switch (p7dcx->type) {
     case SEC_OID_PKCS7_SIGNED_DATA:
@@ -522,6 +519,13 @@ nss_cms_decoder_work_data(SecCmsDecoderRef p7dcx,
        storage = cinfo->content.data;
 
        offset = storage->Length;
+
+       /* check for potential overflow */
+       if (len >= (size_t)(INT_MAX - storage->Length)) {
+         p7dcx->error = SEC_ERROR_NO_MEMORY;
+         goto loser;
+       }
+
        if (storage->Length == 0) {
            dest = (unsigned char *)PORT_ArenaAlloc(p7dcx->cmsg->poolp, len);
        } else {
@@ -603,7 +607,7 @@ SecCmsDecoderCreate(SecCmsContentCallback cb, void *cb_arg,
        goto loser;
     }
 
-    p7dcx->dcx = SEC_ASN1DecoderStart(cmsg->poolp, cmsg, SecCmsMessageTemplate, NULL);
+    p7dcx->dcx = SEC_ASN1DecoderStart(cmsg->poolp, cmsg, SecCmsMessageTemplate, NULL, 0);
     if (p7dcx->dcx == NULL) {
        PORT_Free (p7dcx);
        SecCmsMessageDestroy(cmsg);
@@ -632,6 +636,10 @@ loser:
 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();
@@ -661,11 +669,15 @@ SecCmsDecoderUpdate(SecCmsDecoderRef p7dcx, const void *buf, CFIndex len)
 void
 SecCmsDecoderDestroy(SecCmsDecoderRef p7dcx)
 {
-    /* XXXX what about inner decoders? running digests? decryption? */
-    /* XXXX there's a leak here! */
+    /* SecCmsMessageDestroy frees inner decoders and digests. */
     SecCmsMessageDestroy(p7dcx->cmsg);
+    p7dcx->cmsg = NULL;
     if (p7dcx->dcx)
         (void)SEC_ASN1DecoderFinish(p7dcx->dcx);
+    /* Clear out references */
+    p7dcx->cmsg = NULL;
+    p7dcx->dcx = NULL;
+    p7dcx->childp7dcx = NULL;
     PORT_Free(p7dcx);
 }
 
@@ -683,7 +695,9 @@ SecCmsDecoderFinish(SecCmsDecoderRef p7dcx, SecCmsMessageRef *outMessage)
     if (p7dcx->dcx == NULL || SEC_ASN1DecoderFinish(p7dcx->dcx) != SECSuccess ||
        nss_cms_after_end(p7dcx) != SECSuccess)
     {
-       SecCmsMessageDestroy(cmsg);
+        if (p7dcx->cmsg) {
+            SecCmsMessageDestroy(cmsg);
+        }
         result = PORT_GetError();
         goto loser;
     }
@@ -692,6 +706,10 @@ SecCmsDecoderFinish(SecCmsDecoderRef p7dcx, SecCmsMessageRef *outMessage)
     result = errSecSuccess;
 
 loser:
+    /* Clear out references */
+    p7dcx->cmsg = NULL;
+    p7dcx->dcx = NULL;
+    p7dcx->childp7dcx = NULL;
     PORT_Free(p7dcx);
     return result;
 }