From 0d78d3814cf54409e2d8d1900866e913fdeb7777 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Fri, 15 Mar 2019 13:55:41 -0400 Subject: [PATCH] (fix) correctly handle the full cert chain in S/MIME --- NEWS | 1 + SoObjects/Mailer/NSData+SMIME.m | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 28549c3f5..ca4e63b96 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Bug fixes - [web] fixed wrong translation of custom calendar categories - [web] fixed wrong colors assigned to default calendar categories - [core] allow super users to modify any event (#4216) + - [core] correctly handle the full cert chain in S/MIME 4.0.7 (2019-02-27) ------------------ diff --git a/SoObjects/Mailer/NSData+SMIME.m b/SoObjects/Mailer/NSData+SMIME.m index 4e55fa193..1245ca2f2 100644 --- a/SoObjects/Mailer/NSData+SMIME.m +++ b/SoObjects/Mailer/NSData+SMIME.m @@ -51,6 +51,8 @@ BIO *tbio = NULL, *sbio = NULL, *obio = NULL; X509 *scert = NULL; + X509 *link = NULL; + STACK_OF(X509) *chain = NULL; EVP_PKEY *skey = NULL; PKCS7 *p7 = NULL; BUF_MEM *bptr; @@ -69,9 +71,7 @@ len = [theData length]; tbio = BIO_new_mem_buf((void *)bytes, len); - // Grab the last certificate in case it's chained - scert = NULL; - while (PEM_read_bio_X509(tbio, &scert, 0, NULL) != NULL); + scert = PEM_read_bio_X509(tbio, NULL, 0, NULL); if (!scert) { @@ -79,6 +79,10 @@ goto cleanup; } + chain = sk_X509_new_null(); + while (link = PEM_read_bio_X509_AUX(tbio, NULL, 0, NULL)) + sk_X509_unshift(chain, link); + BIO_reset(tbio); skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); @@ -93,7 +97,7 @@ sbytes = [self bytes]; slen = [self length]; sbio = BIO_new_mem_buf((void *)sbytes, slen); - p7 = PKCS7_sign(scert, skey, NULL, sbio, flags); + p7 = PKCS7_sign(scert, skey, (sk_X509_num(chain) > 0) ? chain : NULL, sbio, flags); if (!p7) { @@ -110,6 +114,7 @@ cleanup: PKCS7_free(p7); + sk_X509_pop_free(chain, X509_free); X509_free(scert); BIO_free(tbio); BIO_free(sbio);