Skip to content

Commit dfbbac6

Browse files
authored
Merge pull request #923 from rhenium/ky/pkcs7-fix-add-recipient
pkcs7: make PKCS7#add_recipient actually useful
2 parents cb46c9d + 9595ecf commit dfbbac6

File tree

2 files changed

+59
-27
lines changed

2 files changed

+59
-27
lines changed

ext/openssl/ossl_pkcs7.c

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,19 @@ ossl_PKCS7_SIGNER_INFO_dup(PKCS7_SIGNER_INFO *si)
143143
}
144144

145145
static PKCS7_RECIP_INFO *
146-
ossl_PKCS7_RECIP_INFO_dup(PKCS7_RECIP_INFO *si)
146+
ossl_PKCS7_RECIP_INFO_dup(PKCS7_RECIP_INFO *ri)
147147
{
148-
return ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO,
149-
(d2i_of_void *)d2i_PKCS7_RECIP_INFO,
150-
si);
148+
PKCS7_RECIP_INFO *ri_new = ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO,
149+
(d2i_of_void *)d2i_PKCS7_RECIP_INFO,
150+
ri);
151+
if (ri_new && ri->cert) {
152+
if (!X509_up_ref(ri->cert)) {
153+
PKCS7_RECIP_INFO_free(ri_new);
154+
return NULL;
155+
}
156+
ri_new->cert = ri->cert;
157+
}
158+
return ri_new;
151159
}
152160

153161
static VALUE
@@ -840,30 +848,38 @@ ossl_pkcs7_add_data(VALUE self, VALUE data)
840848
PKCS7 *pkcs7;
841849
BIO *out, *in;
842850
char buf[4096];
843-
int len;
851+
int len, ret;
844852

845853
GetPKCS7(self, pkcs7);
846-
if(PKCS7_type_is_signed(pkcs7)){
847-
if(!PKCS7_content_new(pkcs7, NID_pkcs7_data))
848-
ossl_raise(ePKCS7Error, NULL);
854+
if (PKCS7_type_is_signed(pkcs7)) {
855+
if (!PKCS7_content_new(pkcs7, NID_pkcs7_data))
856+
ossl_raise(ePKCS7Error, "PKCS7_content_new");
849857
}
850858
in = ossl_obj2bio(&data);
851-
if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err;
852-
for(;;){
853-
if((len = BIO_read(in, buf, sizeof(buf))) <= 0)
854-
break;
855-
if(BIO_write(out, buf, len) != len)
856-
goto err;
859+
if (!(out = PKCS7_dataInit(pkcs7, NULL))) {
860+
BIO_free(in);
861+
ossl_raise(ePKCS7Error, "PKCS7_dataInit");
857862
}
858-
if(!PKCS7_dataFinal(pkcs7, out)) goto err;
859-
ossl_pkcs7_set_data(self, Qnil);
860-
861-
err:
863+
for (;;) {
864+
if ((len = BIO_read(in, buf, sizeof(buf))) <= 0)
865+
break;
866+
if (BIO_write(out, buf, len) != len) {
867+
BIO_free_all(out);
868+
BIO_free(in);
869+
ossl_raise(ePKCS7Error, "BIO_write");
870+
}
871+
}
872+
if (BIO_flush(out) <= 0) {
873+
BIO_free_all(out);
874+
BIO_free(in);
875+
ossl_raise(ePKCS7Error, "BIO_flush");
876+
}
877+
ret = PKCS7_dataFinal(pkcs7, out);
862878
BIO_free_all(out);
863879
BIO_free(in);
864-
if(ERR_peek_error()){
865-
ossl_raise(ePKCS7Error, NULL);
866-
}
880+
if (!ret)
881+
ossl_raise(ePKCS7Error, "PKCS7_dataFinal");
882+
ossl_pkcs7_set_data(self, Qnil);
867883

868884
return data;
869885
}

test/openssl/test_pkcs7.rb

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,28 @@ def test_enveloped
250250
}
251251
end
252252

253+
def test_enveloped_add_recipient
254+
omit_on_fips # PKCS #1 v1.5 padding
255+
256+
data = "aaaaa\nbbbbb\nccccc\n"
257+
ktri_ee1 = OpenSSL::PKCS7::RecipientInfo.new(@ee1_cert)
258+
ktri_ee2 = OpenSSL::PKCS7::RecipientInfo.new(@ee2_cert)
259+
260+
tmp = OpenSSL::PKCS7.new
261+
tmp.type = :enveloped
262+
tmp.cipher = "AES-128-CBC"
263+
tmp.add_recipient(ktri_ee1)
264+
tmp.add_recipient(ktri_ee2)
265+
tmp.add_data(data)
266+
267+
p7 = OpenSSL::PKCS7.new(tmp.to_der)
268+
assert_equal(:enveloped, p7.type)
269+
assert_equal(data, p7.decrypt(@ee1_key, @ee1_cert))
270+
assert_equal(data, p7.decrypt(@ee2_key, @ee2_cert))
271+
assert_equal([@ee1_cert.serial, @ee2_cert.serial].sort,
272+
p7.recipients.map(&:serial).sort)
273+
end
274+
253275
def test_data
254276
asn1 = OpenSSL::ASN1::Sequence([
255277
OpenSSL::ASN1::ObjectId("pkcs7-data"),
@@ -318,12 +340,6 @@ def test_set_type_signed_and_enveloped
318340
assert_equal(:signedAndEnveloped, p7.type)
319341
end
320342

321-
def test_set_type_enveloped
322-
p7 = OpenSSL::PKCS7.new
323-
p7.type = "enveloped"
324-
assert_equal(:enveloped, p7.type)
325-
end
326-
327343
def test_set_type_encrypted
328344
p7 = OpenSSL::PKCS7.new
329345
p7.type = "encrypted"

0 commit comments

Comments
 (0)