1#include "mupdf/fitz.h"
2#include "mupdf/pdf.h"
3#include "../../fitz/fitz-imp.h" /* for fz_keep/drop_imp */
4
5#include "mupdf/helpers/pkcs7-openssl.h"
6
7#ifndef HAVE_LIBCRYPTO
8
9enum pdf_signature_error
10pkcs7_openssl_check_digest(fz_context *ctx, fz_stream *stm, char *sig, int sig_len)
11{
12 return PDF_SIGNATURE_ERROR_UNKNOWN;
13}
14
15/* Check a singature's certificate is trusted */
16enum pdf_signature_error
17pkcs7_openssl_check_certificate(char *sig, int sig_len)
18{
19 return PDF_SIGNATURE_ERROR_UNKNOWN;
20}
21
22pdf_pkcs7_designated_name *
23pkcs7_openssl_designated_name(fz_context *ctx, char *sig, int sig_len)
24{
25 return NULL;
26}
27
28void
29pkcs7_openssl_drop_designated_name(fz_context *ctx, pdf_pkcs7_designated_name *dn)
30{
31}
32
33pdf_pkcs7_signer *
34pkcs7_openssl_read_pfx(fz_context *ctx, const char *pfile, const char *pw)
35{
36 fz_throw(ctx, FZ_ERROR_GENERIC, "No OpenSSL support.");
37}
38
39#else
40
41#include <limits.h>
42#include <string.h>
43
44/* Generated from resources/certs/AdobeCA.p7c */
45static const char AdobeCA_p7c[] = {
4648,130,4,208,6,9,42,134,72,134,247,13,1,7,2,160,130,4,193,48,130,4,189,2,
471,1,49,0,48,11,6,9,42,134,72,134,247,13,1,7,1,160,130,4,165,48,130,4,161,
4848,130,3,137,160,3,2,1,2,2,4,62,28,189,40,48,13,6,9,42,134,72,134,247,13,
491,1,5,5,0,48,105,49,11,48,9,6,3,85,4,6,19,2,85,83,49,35,48,33,6,3,85,4,10,
5019,26,65,100,111,98,101,32,83,121,115,116,101,109,115,32,73,110,99,111,114,
51112,111,114,97,116,101,100,49,29,48,27,6,3,85,4,11,19,20,65,100,111,98,101,
5232,84,114,117,115,116,32,83,101,114,118,105,99,101,115,49,22,48,20,6,3,85,
534,3,19,13,65,100,111,98,101,32,82,111,111,116,32,67,65,48,30,23,13,48,51,
5448,49,48,56,50,51,51,55,50,51,90,23,13,50,51,48,49,48,57,48,48,48,55,50,51,
5590,48,105,49,11,48,9,6,3,85,4,6,19,2,85,83,49,35,48,33,6,3,85,4,10,19,26,
5665,100,111,98,101,32,83,121,115,116,101,109,115,32,73,110,99,111,114,112,
57111,114,97,116,101,100,49,29,48,27,6,3,85,4,11,19,20,65,100,111,98,101,32,
5884,114,117,115,116,32,83,101,114,118,105,99,101,115,49,22,48,20,6,3,85,4,
593,19,13,65,100,111,98,101,32,82,111,111,116,32,67,65,48,130,1,34,48,13,6,
609,42,134,72,134,247,13,1,1,1,5,0,3,130,1,15,0,48,130,1,10,2,130,1,1,0,204,
6179,84,132,247,167,162,231,51,83,127,63,156,18,136,107,44,153,71,103,126,15,
6230,185,173,20,136,249,195,16,216,29,240,240,213,159,105,10,47,89,53,176,204,
63108,169,76,156,21,160,159,206,32,191,160,207,84,226,224,32,102,69,63,57,134,
6456,126,156,196,142,7,34,198,36,246,1,18,176,53,223,85,234,105,144,176,219,
65133,55,30,226,78,7,178,66,161,106,19,105,160,102,234,128,145,17,89,42,155,
668,121,90,32,68,45,201,189,115,56,139,60,47,224,67,27,93,179,11,240,175,53,
6726,41,254,239,166,146,221,129,76,157,61,89,142,173,49,60,64,126,155,145,54,
686,252,226,92,141,209,141,38,213,92,69,207,175,101,63,177,170,210,98,150,244,
69168,56,234,186,96,66,244,244,28,74,53,21,206,248,78,34,86,15,149,24,197,248,
70150,159,159,251,176,183,120,37,233,128,107,189,214,10,240,198,116,148,157,
71243,15,80,219,154,119,206,75,112,131,35,141,160,202,120,32,68,92,60,84,100,
72241,234,162,48,25,159,234,76,6,77,6,120,75,94,146,223,34,210,201,103,179,
73122,210,1,2,3,1,0,1,163,130,1,79,48,130,1,75,48,17,6,9,96,134,72,1,134,248,
7466,1,1,4,4,3,2,0,7,48,129,142,6,3,85,29,31,4,129,134,48,129,131,48,129,128,
75160,126,160,124,164,122,48,120,49,11,48,9,6,3,85,4,6,19,2,85,83,49,35,48,
7633,6,3,85,4,10,19,26,65,100,111,98,101,32,83,121,115,116,101,109,115,32,73,
77110,99,111,114,112,111,114,97,116,101,100,49,29,48,27,6,3,85,4,11,19,20,65,
78100,111,98,101,32,84,114,117,115,116,32,83,101,114,118,105,99,101,115,49,
7922,48,20,6,3,85,4,3,19,13,65,100,111,98,101,32,82,111,111,116,32,67,65,49,
8013,48,11,6,3,85,4,3,19,4,67,82,76,49,48,43,6,3,85,29,16,4,36,48,34,128,15,
8150,48,48,51,48,49,48,56,50,51,51,55,50,51,90,129,15,50,48,50,51,48,49,48,
8257,48,48,48,55,50,51,90,48,11,6,3,85,29,15,4,4,3,2,1,6,48,31,6,3,85,29,35,
834,24,48,22,128,20,130,183,56,74,147,170,155,16,239,128,187,217,84,226,241,
8415,251,128,156,222,48,29,6,3,85,29,14,4,22,4,20,130,183,56,74,147,170,155,
8516,239,128,187,217,84,226,241,15,251,128,156,222,48,12,6,3,85,29,19,4,5,48,
863,1,1,255,48,29,6,9,42,134,72,134,246,125,7,65,0,4,16,48,14,27,8,86,54,46,
8748,58,52,46,48,3,2,4,144,48,13,6,9,42,134,72,134,247,13,1,1,5,5,0,3,130,1,
881,0,50,218,159,67,117,193,250,111,201,111,219,171,29,54,55,62,188,97,25,54,
89183,2,60,29,35,89,152,108,158,238,77,133,231,84,200,32,31,167,212,187,226,
90191,0,119,125,36,107,112,47,92,193,58,118,73,181,211,224,35,132,42,113,106,
9134,243,193,39,41,152,21,246,53,144,228,4,76,195,141,188,159,97,28,231,253,
9236,140,209,68,67,140,22,186,155,77,165,212,53,47,188,17,206,189,247,81,55,
93141,159,144,228,20,241,24,63,190,233,89,18,53,249,51,146,243,158,224,213,
94107,154,113,155,153,75,200,113,195,225,177,97,9,196,229,250,145,240,66,58,
9555,125,52,249,114,232,205,170,98,28,33,233,213,244,130,16,227,123,5,182,45,
96104,86,11,126,126,146,44,111,77,114,130,12,237,86,116,178,157,185,171,45,
9743,29,16,95,219,39,117,112,143,253,29,215,226,2,160,121,229,28,229,255,175,
98100,64,81,45,158,155,71,219,66,165,124,31,194,166,72,176,215,190,146,105,
9977,164,246,41,87,197,120,17,24,220,135,81,202,19,178,98,157,79,43,50,189,
10049,165,193,250,82,171,5,136,200,49,0
101};
102
103#include "openssl/err.h"
104#include "openssl/bio.h"
105#include "openssl/asn1.h"
106#include "openssl/x509.h"
107#include "openssl/x509v3.h"
108#include "openssl/err.h"
109#include "openssl/objects.h"
110#include "openssl/pem.h"
111#include "openssl/pkcs7.h"
112#include "openssl/pkcs12.h"
113#include "openssl/opensslv.h"
114
115#ifndef OPENSSL_VERSION_NUMBER
116#warning detect version of openssl at compile time
117#endif
118
119typedef struct
120{
121 fz_context *ctx;
122 fz_stream *stm;
123} BIO_stream_data;
124
125static int stream_read(BIO *b, char *buf, int size)
126{
127 BIO_stream_data *data = (BIO_stream_data *)BIO_get_data(b);
128 return fz_read(data->ctx, data->stm, (unsigned char *) buf, size);
129}
130
131static long stream_ctrl(BIO *b, int cmd, long arg1, void *arg2)
132{
133 BIO_stream_data *data = (BIO_stream_data *)BIO_get_data(b);
134 switch (cmd)
135 {
136 case BIO_C_FILE_SEEK:
137 fz_seek(data->ctx, data->stm, arg1, SEEK_SET);
138 return 0;
139 default:
140 return 1;
141 }
142}
143
144static int stream_new(BIO *b)
145{
146 BIO_stream_data *data = (BIO_stream_data *)malloc(sizeof(BIO_stream_data));
147 if (!data)
148 return 0;
149
150 data->ctx = NULL;
151 data->stm = NULL;
152
153 BIO_set_init(b, 1);
154 BIO_set_data(b, data);
155 BIO_clear_flags(b, INT_MAX);
156
157 return 1;
158}
159
160static int stream_free(BIO *b)
161{
162 if (b == NULL)
163 return 0;
164
165 free(BIO_get_data(b));
166 BIO_set_data(b, NULL);
167 BIO_set_init(b, 0);
168 BIO_clear_flags(b, INT_MAX);
169
170 return 1;
171}
172
173static long stream_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
174{
175 return 1;
176}
177
178static BIO *BIO_new_stream(fz_context *ctx, fz_stream *stm)
179{
180 static BIO_METHOD *methods = NULL;
181 BIO *bio;
182 BIO_stream_data *data;
183
184 if (!methods)
185 {
186 methods = BIO_meth_new(BIO_TYPE_NONE, "segment reader");
187 if (!methods)
188 return NULL;
189
190 BIO_meth_set_read(methods, stream_read);
191 BIO_meth_set_ctrl(methods, stream_ctrl);
192 BIO_meth_set_create(methods, stream_new);
193 BIO_meth_set_destroy(methods, stream_free);
194 BIO_meth_set_callback_ctrl(methods, stream_callback_ctrl);
195 }
196
197 bio = BIO_new(methods);
198 data = BIO_get_data(bio);
199 data->ctx = ctx;
200 data->stm = stm;
201
202 return bio;
203}
204
205static int verify_callback(int ok, X509_STORE_CTX *ctx)
206{
207 int err, depth;
208
209 err = X509_STORE_CTX_get_error(ctx);
210 depth = X509_STORE_CTX_get_error_depth(ctx);
211
212 if (!ok && depth >= 6)
213 {
214 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG);
215 }
216
217 switch (err)
218 {
219 case X509_V_ERR_INVALID_PURPOSE:
220 case X509_V_ERR_CERT_HAS_EXPIRED:
221 case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
222 X509_STORE_CTX_set_error(ctx, X509_V_OK);
223 ok = 1;
224 break;
225
226 default:
227 break;
228 }
229
230 return ok;
231}
232
233/* Get the certificates from a PKCS7 object */
234static STACK_OF(X509) *pk7_certs(PKCS7 *pk7)
235{
236 if (pk7 == NULL || pk7->d.ptr == NULL)
237 return NULL;
238
239 if (PKCS7_type_is_signed(pk7))
240 return pk7->d.sign->cert;
241 else if (PKCS7_type_is_signedAndEnveloped(pk7))
242 return pk7->d.signed_and_enveloped->cert;
243 else
244 return NULL;
245}
246
247/* Get the signing certificate from a PKCS7 object */
248static X509 *pk7_signer(STACK_OF(X509) *certs, PKCS7_SIGNER_INFO *si)
249{
250 PKCS7_ISSUER_AND_SERIAL *ias = si->issuer_and_serial;
251 if (certs == NULL)
252 return NULL;
253
254 return X509_find_by_issuer_and_serial(certs, ias->issuer, ias->serial);
255}
256
257static enum pdf_signature_error pk7_verify_sig(PKCS7 *p7, BIO *detached)
258{
259 BIO *p7bio=NULL;
260 char readbuf[1024*4];
261 int res = PDF_SIGNATURE_ERROR_UNKNOWN;
262 int i;
263 STACK_OF(PKCS7_SIGNER_INFO) *sk;
264
265 ERR_clear_error();
266
267 p7bio = PKCS7_dataInit(p7, detached);
268 if (!p7bio)
269 goto exit;
270
271 /* We now have to 'read' from p7bio to calculate digests etc. */
272 while (BIO_read(p7bio, readbuf, sizeof(readbuf)) > 0)
273 ;
274
275 /* We can now verify signatures */
276 sk = PKCS7_get_signer_info(p7);
277 if (sk == NULL || sk_PKCS7_SIGNER_INFO_num(sk) <= 0)
278 {
279 /* there are no signatures on this data */
280 res = PDF_SIGNATURE_ERROR_NO_SIGNATURES;
281 goto exit;
282 }
283
284 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sk); i++)
285 {
286 int rc;
287 PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sk, i);
288 X509 *x509 = pk7_signer(pk7_certs(p7), si);
289
290 /* were we able to find the cert in passed to us */
291 if (x509 == NULL)
292 goto exit;
293
294 rc = PKCS7_signatureVerify(p7bio, p7, si, x509);
295 if (rc > 0)
296 {
297 res = PDF_SIGNATURE_ERROR_OKAY;
298 }
299 else
300 {
301 long err = ERR_GET_REASON(ERR_get_error());
302 switch (err)
303 {
304 case PKCS7_R_DIGEST_FAILURE:
305 res = PDF_SIGNATURE_ERROR_DIGEST_FAILURE;
306 break;
307 default:
308 break;
309 }
310 goto exit;
311 }
312 }
313
314exit:
315 BIO_free(p7bio);
316 ERR_free_strings();
317
318 return res;
319}
320
321static enum pdf_signature_error pk7_verify_cert(X509_STORE *cert_store, PKCS7 *p7)
322{
323 int res = PDF_SIGNATURE_ERROR_OKAY;
324 int i;
325 STACK_OF(PKCS7_SIGNER_INFO) *sk;
326 X509_STORE_CTX *ctx;
327
328 ctx = X509_STORE_CTX_new();
329 if (!ctx)
330 return PDF_SIGNATURE_ERROR_UNKNOWN;
331
332 ERR_clear_error();
333
334 X509_STORE_set_verify_cb_func(cert_store, verify_callback);
335
336 /* We can now verify signatures */
337 sk = PKCS7_get_signer_info(p7);
338 if (sk == NULL)
339 {
340 /* there are no signatures on this data */
341 res = PDF_SIGNATURE_ERROR_NO_SIGNATURES;
342 goto exit;
343 }
344
345 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sk); i++)
346 {
347 int ctx_err;
348 PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sk, i);
349 STACK_OF(X509) *certs = pk7_certs(p7);
350 X509 *cert = pk7_signer(certs, si);
351 if (cert == NULL)
352 {
353 res = PDF_SIGNATURE_ERROR_NO_CERTIFICATE;
354 goto exit;
355 }
356
357 /* Acrobat reader creates self-signed certificates that don't list
358 * certificate signing within the key usage parameters. openssl does
359 * not recognise those as self signed. We work around this by removing
360 * the key usage parameters before the verification check */
361 {
362 int i = X509_get_ext_by_NID(cert, NID_key_usage, -1);
363 if (i >= 0)
364 {
365 X509_EXTENSION *ext = X509_get_ext(cert, i);
366 X509_delete_ext(cert, i);
367 X509_EXTENSION_free(ext);
368 }
369 }
370
371 if (!X509_STORE_CTX_init(ctx, cert_store, cert, certs))
372 {
373 res = PDF_SIGNATURE_ERROR_UNKNOWN;
374 goto exit;
375 }
376
377 if (!X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN))
378 {
379 res = PDF_SIGNATURE_ERROR_UNKNOWN;
380 goto exit;
381 }
382
383 /* X509_verify_cert may return an error, but in all such cases
384 * it sets a context error */
385 X509_verify_cert(ctx);
386 X509_STORE_CTX_cleanup(ctx);
387 ctx_err = X509_STORE_CTX_get_error(ctx);
388 switch (ctx_err)
389 {
390 case X509_V_OK:
391 break;
392 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
393 res = PDF_SIGNATURE_ERROR_SELF_SIGNED;
394 goto exit;
395 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
396 res = PDF_SIGNATURE_ERROR_SELF_SIGNED_IN_CHAIN;
397 goto exit;
398 default:
399 res = PDF_SIGNATURE_ERROR_UNKNOWN;
400 goto exit;
401 }
402 }
403
404exit:
405 X509_STORE_CTX_free(ctx);
406 ERR_free_strings();
407
408 return res;
409}
410
411enum pdf_signature_error pkcs7_openssl_check_digest(fz_context *ctx, fz_stream *stm, char *sig, int sig_len)
412{
413 PKCS7 *pk7sig = NULL;
414 BIO *bsig = NULL;
415 BIO *bdata = NULL;
416 int res = PDF_SIGNATURE_ERROR_UNKNOWN;
417
418 bsig = BIO_new_mem_buf(sig, sig_len);
419 pk7sig = d2i_PKCS7_bio(bsig, NULL);
420 if (pk7sig == NULL)
421 goto exit;
422
423 bdata = BIO_new_stream(ctx, stm);
424 if (bdata == NULL)
425 goto exit;
426
427 res = pk7_verify_sig(pk7sig, bdata);
428
429exit:
430 BIO_free(bdata);
431 PKCS7_free(pk7sig);
432 BIO_free(bsig);
433
434 return res;
435}
436
437enum pdf_signature_error pkcs7_openssl_check_certificate(char *sig, int sig_len)
438{
439 PKCS7 *pk7sig = NULL;
440 PKCS7 *pk7cert = NULL;
441 X509_STORE *st = NULL;
442 BIO *bsig = NULL;
443 BIO *bcert = NULL;
444 STACK_OF(X509) *certs = NULL;
445 int res = PDF_SIGNATURE_ERROR_UNKNOWN;
446
447 bsig = BIO_new_mem_buf(sig, sig_len);
448 pk7sig = d2i_PKCS7_bio(bsig, NULL);
449 if (pk7sig == NULL)
450 goto exit;
451
452 /* Find the certificates in the pk7 file */
453 bcert = BIO_new_mem_buf((void*)AdobeCA_p7c, sizeof AdobeCA_p7c);
454 pk7cert = d2i_PKCS7_bio(bcert, NULL);
455 if (pk7cert == NULL)
456 goto exit;
457
458 certs = pk7_certs(pk7cert);
459
460 st = X509_STORE_new();
461 if (st == NULL)
462 goto exit;
463
464 /* Add the certificates to the store */
465 if (certs != NULL)
466 {
467 int i, n = sk_X509_num(certs);
468
469 for (i = 0; i < n; i++)
470 {
471 X509 *c = sk_X509_value(certs, i);
472 X509_STORE_add_cert(st, c);
473 }
474 }
475
476 res = pk7_verify_cert(st, pk7sig);
477
478exit:
479 X509_STORE_free(st);
480 PKCS7_free(pk7cert);
481 BIO_free(bcert);
482 PKCS7_free(pk7sig);
483 BIO_free(bsig);
484
485 return res;
486}
487
488typedef struct pdf_pkcs7_designated_name_openssl_s
489{
490 pdf_pkcs7_designated_name base;
491 char buf[8192];
492} pdf_pkcs7_designated_name_openssl;
493
494void pkcs7_openssl_drop_designated_name(fz_context *ctx, pdf_pkcs7_designated_name *dn)
495{
496 fz_free(ctx, dn);
497}
498
499typedef struct
500{
501 pdf_pkcs7_signer base;
502 fz_context *ctx;
503 int refs;
504 X509 *x509;
505 EVP_PKEY *pkey;
506} openssl_signer;
507
508static void signer_drop_designated_name(pdf_pkcs7_signer *signer, pdf_pkcs7_designated_name *dn)
509{
510 openssl_signer *osigner = (openssl_signer *)signer;
511 fz_free(osigner->ctx, dn);
512}
513
514static void add_from_bags(X509 **pX509, EVP_PKEY **pPkey, const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pw);
515
516static void add_from_bag(X509 **pX509, EVP_PKEY **pPkey, PKCS12_SAFEBAG *bag, const char *pw)
517{
518 EVP_PKEY *pkey = NULL;
519 X509 *x509 = NULL;
520 switch (M_PKCS12_bag_type(bag))
521 {
522 case NID_keyBag:
523 {
524 const PKCS8_PRIV_KEY_INFO *p8 = PKCS12_SAFEBAG_get0_p8inf(bag);
525 pkey = EVP_PKCS82PKEY(p8);
526 }
527 break;
528
529 case NID_pkcs8ShroudedKeyBag:
530 {
531 PKCS8_PRIV_KEY_INFO *p8 = PKCS12_decrypt_skey(bag, pw, (int)strlen(pw));
532 if (p8)
533 {
534 pkey = EVP_PKCS82PKEY(p8);
535 PKCS8_PRIV_KEY_INFO_free(p8);
536 }
537 }
538 break;
539
540 case NID_certBag:
541 if (M_PKCS12_cert_bag_type(bag) == NID_x509Certificate)
542 x509 = PKCS12_certbag2x509(bag);
543 break;
544
545 case NID_safeContentsBag:
546 add_from_bags(pX509, pPkey, PKCS12_SAFEBAG_get0_safes(bag), pw);
547 break;
548 }
549
550 if (pkey)
551 {
552 if (!*pPkey)
553 *pPkey = pkey;
554 else
555 EVP_PKEY_free(pkey);
556 }
557
558 if (x509)
559 {
560 if (!*pX509)
561 *pX509 = x509;
562 else
563 X509_free(x509);
564 }
565}
566
567static void add_from_bags(X509 **pX509, EVP_PKEY **pPkey, const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pw)
568{
569 int i;
570
571 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++)
572 add_from_bag(pX509, pPkey, sk_PKCS12_SAFEBAG_value(bags, i), pw);
573}
574
575static pdf_pkcs7_signer *keep_signer(pdf_pkcs7_signer *signer)
576{
577 openssl_signer *osigner = (openssl_signer *)signer;
578 return fz_keep_imp(osigner->ctx, osigner, &osigner->refs);
579}
580
581static void drop_signer(pdf_pkcs7_signer *signer)
582{
583 openssl_signer *osigner = (openssl_signer *)signer;
584 if (fz_drop_imp(osigner->ctx, osigner, &osigner->refs))
585 {
586 X509_free(osigner->x509);
587 EVP_PKEY_free(osigner->pkey);
588 fz_free(osigner->ctx, osigner);
589 }
590}
591
592static pdf_pkcs7_designated_name *x509_designated_name(fz_context *ctx, X509 *x509)
593{
594 pdf_pkcs7_designated_name_openssl *dn = fz_malloc_struct(ctx, pdf_pkcs7_designated_name_openssl);
595 char *p;
596
597 X509_NAME_oneline(X509_get_subject_name(x509), dn->buf, sizeof(dn->buf));
598 p = strstr(dn->buf, "/CN=");
599 if (p) dn->base.cn = p+4;
600 p = strstr(dn->buf, "/O=");
601 if (p) dn->base.o = p+3;
602 p = strstr(dn->buf, "/OU=");
603 if (p) dn->base.ou = p+4;
604 p = strstr(dn->buf, "/emailAddress=");
605 if (p) dn->base.email = p+14;
606 p = strstr(dn->buf, "/C=");
607 if (p) dn->base.c = p+3;
608
609 for (p = dn->buf; *p; p++)
610 if (*p == '/')
611 *p = 0;
612
613 return (pdf_pkcs7_designated_name *)dn;
614}
615
616static pdf_pkcs7_designated_name *signer_designated_name(pdf_pkcs7_signer *signer)
617{
618 openssl_signer *osigner = (openssl_signer *)signer;
619 return x509_designated_name(osigner->ctx, osigner->x509);
620}
621
622static int signer_create_digest(pdf_pkcs7_signer *signer, fz_stream *in, unsigned char *digest, int *digest_len)
623{
624 openssl_signer *osigner = (openssl_signer *)signer;
625 fz_context *ctx = osigner->ctx;
626 int res = 0;
627 BIO *bdata = NULL;
628 BIO *bp7in = NULL;
629 BIO *bp7 = NULL;
630 PKCS7 *p7 = NULL;
631 PKCS7_SIGNER_INFO *si;
632
633 unsigned char *p7_ptr;
634 int p7_len;
635
636 if (in != NULL)
637 {
638 bdata = BIO_new_stream(ctx, in);
639 if (bdata == NULL)
640 goto exit;
641 }
642
643 p7 = PKCS7_new();
644 if (p7 == NULL)
645 goto exit;
646
647 PKCS7_set_type(p7, NID_pkcs7_signed);
648 si = PKCS7_add_signature(p7, osigner->x509, osigner->pkey, EVP_sha1());
649 if (si == NULL)
650 goto exit;
651
652 PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));
653 PKCS7_add_certificate(p7, osigner->x509);
654
655 PKCS7_content_new(p7, NID_pkcs7_data);
656 PKCS7_set_detached(p7, 1);
657
658 bp7in = PKCS7_dataInit(p7, NULL);
659 if (bp7in == NULL)
660 goto exit;
661
662 while(bdata) /* bdata knowingly not changed in the loop */
663 {
664 char buf[4096];
665 int n = BIO_read(bdata, buf, sizeof(buf));
666 if (n <= 0)
667 break;
668 BIO_write(bp7in, buf, n);
669 }
670
671 if (!PKCS7_dataFinal(p7, bp7in))
672 goto exit;
673
674 BIO_free(bdata);
675 bdata = NULL;
676
677 bp7 = BIO_new(BIO_s_mem());
678 if (bp7 == NULL || !i2d_PKCS7_bio(bp7, p7))
679 goto exit;
680
681 p7_len = BIO_get_mem_data(bp7, &p7_ptr);
682 if (digest && p7_len > *digest_len)
683 goto exit;
684
685 if (digest)
686 memcpy(digest, p7_ptr, p7_len);
687
688 *digest_len = p7_len;
689 res = 1;
690
691exit:
692 BIO_free(bp7);
693 BIO_free(bp7in);
694 PKCS7_free(p7);
695 BIO_free(bdata);
696
697 return res;
698}
699
700static int max_digest_size(pdf_pkcs7_signer *signer)
701{
702 /* Perform a test digest generation to find the required size. Size
703 * is assumed independent of data being hashed */
704 int digest_len = 0;
705
706 signer_create_digest(signer, NULL, NULL, &digest_len);
707
708 return digest_len;
709}
710
711pdf_pkcs7_signer *pkcs7_openssl_read_pfx(fz_context *ctx, const char *pfile, const char *pw)
712{
713 BIO *pfxbio = NULL;
714 PKCS12 *p12 = NULL;
715 STACK_OF(PKCS7) *asafes;
716 openssl_signer *signer = NULL;
717 int i;
718
719 fz_var(pfxbio);
720 fz_var(p12);
721 fz_var(signer);
722 fz_try(ctx)
723 {
724 signer = fz_malloc_struct(ctx, openssl_signer);
725 signer->base.keep = keep_signer;
726 signer->base.drop = drop_signer;
727 signer->base.designated_name = signer_designated_name;
728 signer->base.drop_designated_name = signer_drop_designated_name;
729 signer->base.max_digest_size = max_digest_size;
730 signer->base.create_digest = signer_create_digest;
731 signer->ctx = ctx;
732 signer->refs = 1;
733
734 OpenSSL_add_all_algorithms();
735
736 EVP_add_digest(EVP_md5());
737 EVP_add_digest(EVP_sha1());
738
739 ERR_load_crypto_strings();
740
741 ERR_clear_error();
742
743 pfxbio = BIO_new_file(pfile, "rb");
744 if (pfxbio == NULL)
745 fz_throw(ctx, FZ_ERROR_GENERIC, "Can't open pfx file: %s", pfile);
746
747 p12 = d2i_PKCS12_bio(pfxbio, NULL);
748 if (p12 == NULL)
749 fz_throw(ctx, FZ_ERROR_GENERIC, "Invalid pfx file: %s", pfile);
750
751 asafes = PKCS12_unpack_authsafes(p12);
752 if (asafes == NULL)
753 fz_throw(ctx, FZ_ERROR_GENERIC, "Invalid pfx file: %s", pfile);
754
755 /* Nothing in this for loop can fz_throw */
756 for (i = 0; i < sk_PKCS7_num(asafes); i++)
757 {
758 PKCS7 *p7;
759 STACK_OF(PKCS12_SAFEBAG) *bags;
760 int bagnid;
761
762 p7 = sk_PKCS7_value(asafes, i);
763 bagnid = OBJ_obj2nid(p7->type);
764 switch (bagnid)
765 {
766 case NID_pkcs7_data:
767 bags = PKCS12_unpack_p7data(p7);
768 break;
769 case NID_pkcs7_encrypted:
770 bags = PKCS12_unpack_p7encdata(p7, pw, (int)strlen(pw));
771 break;
772 default:
773 continue;
774 }
775
776 if (bags)
777 {
778 add_from_bags(&signer->x509, &signer->pkey, bags, pw);
779 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
780 }
781 }
782 sk_PKCS7_pop_free (asafes, PKCS7_free);
783
784 if (signer->pkey == NULL)
785 fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to obtain public key");
786
787 if (signer->x509 == NULL)
788 fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to obtain certificate");
789 }
790 fz_always(ctx)
791 {
792 PKCS12_free(p12);
793 BIO_free(pfxbio);
794 }
795 fz_catch(ctx)
796 {
797 drop_signer(&signer->base);
798 fz_rethrow(ctx);
799 }
800
801 return &signer->base;
802}
803
804pdf_pkcs7_designated_name *pkcs7_openssl_designated_name(fz_context *ctx, char *sig, int sig_len)
805{
806 pdf_pkcs7_designated_name *name = NULL;
807 PKCS7 *pk7sig = NULL;
808 BIO *bsig = NULL;
809 STACK_OF(PKCS7_SIGNER_INFO) *sk = NULL;
810 X509 *x509 = NULL;
811
812 bsig = BIO_new_mem_buf(sig, sig_len);
813 pk7sig = d2i_PKCS7_bio(bsig, NULL);
814 if (pk7sig == NULL)
815 goto exit;
816
817 sk = PKCS7_get_signer_info(pk7sig);
818 if (sk == NULL || sk_PKCS7_SIGNER_INFO_num(sk) <= 0)
819 goto exit;
820
821 x509 = pk7_signer(pk7_certs(pk7sig), sk_PKCS7_SIGNER_INFO_value(sk, 0));
822
823 name = x509_designated_name(ctx, x509);
824
825exit:
826 PKCS7_free(pk7sig);
827 BIO_free(bsig);
828
829 return name;
830}
831
832#endif
833