if (!BIO_get_cipher_status(in))
goto err;
}
+ if (i < 0)
+ goto err;
break;
}
- if (tmpout)
- BIO_write(tmpout, buf, i);
+ if (tmpout && (BIO_write(tmpout, buf, i) != i))
+ goto err;
}
if(flags & CMS_TEXT)
return 1;
}
+static void do_free_upto(BIO *f, BIO *upto)
+ {
+ if (upto)
+ {
+ BIO *tbio;
+ do
+ {
+ tbio = BIO_pop(f);
+ BIO_free(f);
+ f = tbio;
+ }
+ while (f != upto);
+ }
+ else
+ BIO_free_all(f);
+ }
+
int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
{
BIO *cont;
r = cms_copy_content(out, cont, flags);
if (r)
r = cms_DigestedData_do_final(cms, cont, 1);
- BIO_free_all(cont);
+ do_free_upto(cont, dcont);
return r;
}
if (!cont)
return 0;
r = cms_copy_content(out, cont, flags);
- BIO_free_all(cont);
+ do_free_upto(cont, dcont);
return r;
}
err:
if (dcont && (tmpin == dcont))
- BIO_pop(cmsbio);
- BIO_free_all(cmsbio);
+ do_free_upto(cmsbio, dcont);
+ else
+ BIO_free_all(cmsbio);
if (cms_certs)
sk_X509_pop_free(cms_certs, X509_free);
{
CMS_ContentInfo *cms;
int i;
+
cms = CMS_ContentInfo_new();
- if (!cms)
+ if (!cms || !CMS_SignedData_init(cms))
goto merr;
+
if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags))
{
CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
goto err;
}
+
for (i = 0; i < sk_X509_num(certs); i++)
{
X509 *x = sk_X509_value(certs, i);
if (!CMS_add1_cert(cms, x))
goto merr;
}
- /* If no signer or certs initialize signedData */
- if (!pkey && !i && !CMS_SignedData_init(cms))
- goto merr;
if(!(flags & CMS_DETACHED))
CMS_set_detached(cms, 0);
if (!cont)
return 0;
r = cms_copy_content(out, cont, flags);
- BIO_free_all(cont);
+ do_free_upto(cont, dcont);
return r;
}
ret = 1;
err:
- BIO_free_all(cmsbio);
+ do_free_upto(cmsbio, dcont);
return ret;
if (!cont)
return 0;
r = cms_copy_content(out, cont, flags);
- BIO_free_all(cont);
+ do_free_upto(cont, dcont);
return r;
}
if(!(flags & CMS_DETACHED))
CMS_set_detached(cms, 0);
- if ((flags & CMS_STREAM) || CMS_final(cms, in, flags))
+ if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
return cms;
CMS_ContentInfo_free(cms);