Coverage Report

Created: 2023-03-26 06:14

/src/minizip-ng/mz_crypt_openssl.c
Line
Count
Source (jump to first uncovered line)
1
/* mz_crypt_openssl.c -- Crypto/hash functions for OpenSSL
2
   part of the minizip-ng project
3
4
   Copyright (C) Nathan Moinvaziri
5
     https://github.com/zlib-ng/minizip-ng
6
7
   This program is distributed under the terms of the same license as zlib.
8
   See the accompanying LICENSE file for the full text of the license.
9
*/
10
11
#include "mz.h"
12
13
#include <openssl/err.h>
14
#include <openssl/engine.h>
15
#include <openssl/rand.h>
16
#include <openssl/sha.h>
17
#include <openssl/aes.h>
18
#include <openssl/crypto.h>
19
#include <openssl/evp.h>
20
#include <openssl/hmac.h>
21
22
#if defined(MZ_ZIP_SIGNING)
23
/* Note: https://www.imperialviolet.org/2015/10/17/boringssl.html says that
24
   BoringSSL does not support CMS. "#include <etc/cms.h>" will fail. See
25
   https://bugs.chromium.org/p/boringssl/issues/detail?id=421
26
*/
27
#include <openssl/cms.h>
28
#include <openssl/pkcs12.h>
29
#include <openssl/x509.h>
30
#endif
31
32
/***************************************************************************/
33
34
5.75M
static void mz_crypt_init(void) {
35
5.75M
    static int32_t openssl_initialized = 0;
36
5.75M
    if (!openssl_initialized) {
37
1
        OpenSSL_add_all_algorithms();
38
39
1
        ERR_load_BIO_strings();
40
1
        ERR_load_crypto_strings();
41
42
1
        ENGINE_load_builtin_engines();
43
1
        ENGINE_register_all_complete();
44
45
1
        openssl_initialized = 1;
46
1
    }
47
5.75M
}
48
49
0
int32_t mz_crypt_rand(uint8_t *buf, int32_t size) {
50
0
    int32_t result = 0;
51
52
0
    result = RAND_bytes(buf, size);
53
54
0
    if (!result)
55
0
        return MZ_CRYPT_ERROR;
56
57
0
    return size;
58
0
}
59
60
/***************************************************************************/
61
62
typedef struct mz_crypt_sha_s {
63
    union {
64
        SHA512_CTX ctx512;
65
        SHA256_CTX ctx256;
66
        SHA_CTX    ctx1;
67
    };
68
    int32_t        initialized;
69
    int32_t        error;
70
    uint16_t       algorithm;
71
} mz_crypt_sha;
72
73
/***************************************************************************/
74
75
static const uint8_t mz_crypt_sha_digest_size[] = {
76
    MZ_HASH_SHA1_SIZE,                     0, MZ_HASH_SHA224_SIZE,
77
    MZ_HASH_SHA256_SIZE, MZ_HASH_SHA384_SIZE, MZ_HASH_SHA512_SIZE
78
};
79
80
/***************************************************************************/
81
82
0
void mz_crypt_sha_reset(void *handle) {
83
0
    mz_crypt_sha *sha = (mz_crypt_sha *)handle;
84
85
0
    sha->error = 0;
86
0
    sha->initialized = 0;
87
88
0
    mz_crypt_init();
89
0
}
90
91
0
int32_t mz_crypt_sha_begin(void *handle) {
92
0
    mz_crypt_sha *sha = (mz_crypt_sha *)handle;
93
0
    int32_t result = 0;
94
95
0
    if (!sha)
96
0
        return MZ_PARAM_ERROR;
97
98
0
    mz_crypt_sha_reset(handle);
99
100
0
    switch (sha->algorithm) {
101
0
    case MZ_HASH_SHA1:
102
0
        result = SHA1_Init(&sha->ctx1);
103
0
        break;
104
0
    case MZ_HASH_SHA224:
105
0
        result = SHA224_Init(&sha->ctx256);
106
0
        break;
107
0
    case MZ_HASH_SHA256:
108
0
        result = SHA256_Init(&sha->ctx256);
109
0
        break;
110
0
    case MZ_HASH_SHA384:
111
0
        result = SHA384_Init(&sha->ctx512);
112
0
        break;
113
0
    case MZ_HASH_SHA512:
114
0
        result = SHA512_Init(&sha->ctx512);
115
0
        break;
116
0
    }
117
118
0
    if (!result) {
119
0
        sha->error = ERR_get_error();
120
0
        return MZ_HASH_ERROR;
121
0
    }
122
123
0
    sha->initialized = 1;
124
0
    return MZ_OK;
125
0
}
126
127
0
int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size) {
128
0
    mz_crypt_sha *sha = (mz_crypt_sha *)handle;
129
0
    int32_t result = 0;
130
131
0
    if (!sha || !buf || !sha->initialized)
132
0
        return MZ_PARAM_ERROR;
133
134
0
    switch (sha->algorithm) {
135
0
    case MZ_HASH_SHA1:
136
0
        result = SHA1_Update(&sha->ctx1, buf, size);
137
0
        break;
138
0
    case MZ_HASH_SHA224:
139
0
        result = SHA224_Update(&sha->ctx256, buf, size);
140
0
        break;
141
0
    case MZ_HASH_SHA256:
142
0
        result = SHA256_Update(&sha->ctx256, buf, size);
143
0
        break;
144
0
    case MZ_HASH_SHA384:
145
0
        result = SHA384_Update(&sha->ctx512, buf, size);
146
0
        break;
147
0
    case MZ_HASH_SHA512:
148
0
        result = SHA512_Update(&sha->ctx512, buf, size);
149
0
        break;
150
0
    }
151
152
0
    if (!result) {
153
0
        sha->error = ERR_get_error();
154
0
        return MZ_HASH_ERROR;
155
0
    }
156
157
0
    return size;
158
0
}
159
160
0
int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size) {
161
0
    mz_crypt_sha *sha = (mz_crypt_sha *)handle;
162
0
    int32_t result = 0;
163
164
0
    if (!sha || !digest || !sha->initialized)
165
0
        return MZ_PARAM_ERROR;
166
0
    if (digest_size < mz_crypt_sha_digest_size[sha->algorithm - MZ_HASH_SHA1])
167
0
        return MZ_PARAM_ERROR;
168
169
0
    switch (sha->algorithm) {
170
0
    case MZ_HASH_SHA1:
171
0
        result = SHA1_Final(digest, &sha->ctx1);
172
0
        break;
173
0
    case MZ_HASH_SHA224:
174
0
        result = SHA224_Final(digest, &sha->ctx256);
175
0
        break;
176
0
    case MZ_HASH_SHA256:
177
0
        result = SHA256_Final(digest, &sha->ctx256);
178
0
        break;
179
0
    case MZ_HASH_SHA384:
180
0
        result = SHA384_Final(digest, &sha->ctx512);
181
0
        break;
182
0
    case MZ_HASH_SHA512:
183
0
        result = SHA512_Final(digest, &sha->ctx512);
184
0
        break;
185
0
    }
186
187
0
    if (!result) {
188
0
        sha->error = ERR_get_error();
189
0
        return MZ_HASH_ERROR;
190
0
    }
191
192
0
    return MZ_OK;
193
0
}
194
195
0
void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm) {
196
0
    mz_crypt_sha *sha = (mz_crypt_sha *)handle;
197
0
    if (MZ_HASH_SHA1 <= algorithm && algorithm <= MZ_HASH_SHA512)
198
0
        sha->algorithm = algorithm;
199
0
}
200
201
0
void *mz_crypt_sha_create(void **handle) {
202
0
    mz_crypt_sha *sha = NULL;
203
204
0
    sha = (mz_crypt_sha *)calloc(1, sizeof(mz_crypt_sha));
205
0
    if (sha)
206
0
        sha->algorithm = MZ_HASH_SHA256;
207
0
    if (handle)
208
0
        *handle = sha;
209
210
0
    return sha;
211
0
}
212
213
0
void mz_crypt_sha_delete(void **handle) {
214
0
    mz_crypt_sha *sha = NULL;
215
0
    if (!handle)
216
0
        return;
217
0
    sha = (mz_crypt_sha *)*handle;
218
0
    if (sha) {
219
0
        mz_crypt_sha_reset(*handle);
220
0
        free(sha);
221
0
    }
222
0
    *handle = NULL;
223
0
}
224
225
/***************************************************************************/
226
227
typedef struct mz_crypt_aes_s {
228
    AES_KEY    key;
229
    int32_t    mode;
230
    int32_t    error;
231
    uint8_t    *key_copy;
232
    int32_t    key_length;
233
} mz_crypt_aes;
234
235
/***************************************************************************/
236
237
3.42k
void mz_crypt_aes_reset(void *handle) {
238
3.42k
    MZ_UNUSED(handle);
239
240
3.42k
    mz_crypt_init();
241
3.42k
}
242
243
63.8k
int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size) {
244
63.8k
    mz_crypt_aes *aes = (mz_crypt_aes *)handle;
245
246
63.8k
    if (!aes || !buf)
247
0
        return MZ_PARAM_ERROR;
248
63.8k
    if (size != MZ_AES_BLOCK_SIZE)
249
0
        return MZ_PARAM_ERROR;
250
251
63.8k
    AES_encrypt(buf, buf, &aes->key);
252
    /* Equivalent to AES_ecb_encrypt with AES_ENCRYPT */
253
63.8k
    return size;
254
63.8k
}
255
256
0
int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size) {
257
0
    mz_crypt_aes *aes = (mz_crypt_aes *)handle;
258
0
    if (!aes || !buf)
259
0
        return MZ_PARAM_ERROR;
260
0
    if (size != MZ_AES_BLOCK_SIZE)
261
0
        return MZ_PARAM_ERROR;
262
263
0
    AES_decrypt(buf, buf, &aes->key);
264
    /* Equivalent to AES_ecb_encrypt with AES_DECRYPT */
265
0
    return size;
266
0
}
267
268
1.71k
int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length) {
269
1.71k
    mz_crypt_aes *aes = (mz_crypt_aes *)handle;
270
1.71k
    int32_t result = 0;
271
1.71k
    int32_t key_bits = 0;
272
273
1.71k
    if (!aes || !key || !key_length)
274
0
        return MZ_PARAM_ERROR;
275
276
1.71k
    mz_crypt_aes_reset(handle);
277
278
1.71k
    key_bits = key_length * 8;
279
1.71k
    result = AES_set_encrypt_key(key, key_bits, &aes->key);
280
1.71k
    if (result) {
281
0
        aes->error = ERR_get_error();
282
0
        return MZ_HASH_ERROR;
283
0
    }
284
285
1.71k
    return MZ_OK;
286
1.71k
}
287
288
0
int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length) {
289
0
    mz_crypt_aes *aes = (mz_crypt_aes *)handle;
290
0
    int32_t result = 0;
291
0
    int32_t key_bits = 0;
292
293
0
    if (!aes || !key || !key_length)
294
0
        return MZ_PARAM_ERROR;
295
296
0
    mz_crypt_aes_reset(handle);
297
298
0
    key_bits = key_length * 8;
299
0
    result = AES_set_decrypt_key(key, key_bits, &aes->key);
300
0
    if (result) {
301
0
        aes->error = ERR_get_error();
302
0
        return MZ_HASH_ERROR;
303
0
    }
304
305
0
    return MZ_OK;
306
0
}
307
308
1.71k
void mz_crypt_aes_set_mode(void *handle, int32_t mode) {
309
1.71k
    mz_crypt_aes *aes = (mz_crypt_aes *)handle;
310
1.71k
    aes->mode = mode;
311
1.71k
}
312
313
1.72k
void *mz_crypt_aes_create(void **handle) {
314
1.72k
    mz_crypt_aes *aes = NULL;
315
316
1.72k
    aes = (mz_crypt_aes *)calloc(1, sizeof(mz_crypt_aes));
317
1.72k
    if (handle)
318
1.72k
        *handle = aes;
319
320
1.72k
    return aes;
321
1.72k
}
322
323
1.72k
void mz_crypt_aes_delete(void **handle) {
324
1.72k
    mz_crypt_aes *aes = NULL;
325
1.72k
    if (!handle)
326
0
        return;
327
1.72k
    aes = (mz_crypt_aes *)*handle;
328
1.72k
    if (aes)
329
1.72k
        free(aes);
330
1.72k
    *handle = NULL;
331
1.72k
}
332
333
/***************************************************************************/
334
335
typedef struct mz_crypt_hmac_s {
336
    HMAC_CTX   *ctx;
337
    int32_t    initialized;
338
    int32_t    error;
339
    uint16_t   algorithm;
340
} mz_crypt_hmac;
341
342
/***************************************************************************/
343
344
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x2070000fL))
345
static HMAC_CTX *HMAC_CTX_new(void) {
346
    HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX));
347
    if (ctx)
348
        HMAC_CTX_init(ctx);
349
    return ctx;
350
}
351
352
static void HMAC_CTX_free(HMAC_CTX *ctx) {
353
    if (ctx) {
354
        HMAC_CTX_cleanup(ctx);
355
        OPENSSL_free(ctx);
356
    }
357
}
358
#endif
359
360
/***************************************************************************/
361
362
5.75M
void mz_crypt_hmac_reset(void *handle) {
363
5.75M
    mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
364
365
5.75M
    HMAC_CTX_free(hmac->ctx);
366
367
5.75M
    hmac->ctx = NULL;
368
5.75M
    hmac->error = 0;
369
370
5.75M
    mz_crypt_init();
371
5.75M
}
372
373
5.13k
int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length) {
374
5.13k
    mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
375
5.13k
    int32_t result = 0;
376
5.13k
    const EVP_MD *evp_md = NULL;
377
378
5.13k
    if (!hmac || !key)
379
0
        return MZ_PARAM_ERROR;
380
381
5.13k
    mz_crypt_hmac_reset(handle);
382
383
5.13k
    hmac->ctx = HMAC_CTX_new();
384
385
5.13k
    if (hmac->algorithm == MZ_HASH_SHA1)
386
5.13k
        evp_md = EVP_sha1();
387
0
    else
388
0
        evp_md = EVP_sha256();
389
390
5.13k
    result = HMAC_Init_ex(hmac->ctx, key, key_length, evp_md, NULL);
391
5.13k
    if (!result) {
392
0
        hmac->error = ERR_get_error();
393
0
        return MZ_HASH_ERROR;
394
0
    }
395
396
5.13k
    return MZ_OK;
397
5.13k
}
398
399
5.73M
int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size) {
400
5.73M
    mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
401
5.73M
    int32_t result = 0;
402
403
5.73M
    if (!hmac || !buf)
404
0
        return MZ_PARAM_ERROR;
405
406
5.73M
    result = HMAC_Update(hmac->ctx, buf, size);
407
5.73M
    if (!result) {
408
0
        hmac->error = ERR_get_error();
409
0
        return MZ_HASH_ERROR;
410
0
    }
411
412
5.73M
    return MZ_OK;
413
5.73M
}
414
415
5.73M
int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size) {
416
5.73M
    mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
417
5.73M
    int32_t result = 0;
418
419
5.73M
    if (!hmac || !digest)
420
0
        return MZ_PARAM_ERROR;
421
422
5.73M
    if (hmac->algorithm == MZ_HASH_SHA1) {
423
5.73M
        if (digest_size < MZ_HASH_SHA1_SIZE)
424
0
            return MZ_BUF_ERROR;
425
426
5.73M
        result = HMAC_Final(hmac->ctx, digest, (uint32_t *)&digest_size);
427
5.73M
    } else {
428
0
        if (digest_size < MZ_HASH_SHA256_SIZE)
429
0
            return MZ_BUF_ERROR;
430
0
        result = HMAC_Final(hmac->ctx, digest, (uint32_t *)&digest_size);
431
0
    }
432
433
5.73M
    if (!result) {
434
0
        hmac->error = ERR_get_error();
435
0
        return MZ_HASH_ERROR;
436
0
    }
437
438
5.73M
    return MZ_OK;
439
5.73M
}
440
441
6.84k
void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm) {
442
6.84k
    mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
443
6.84k
    hmac->algorithm = algorithm;
444
6.84k
}
445
446
5.73M
int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle) {
447
5.73M
    mz_crypt_hmac *source = (mz_crypt_hmac *)src_handle;
448
5.73M
    mz_crypt_hmac *target = (mz_crypt_hmac *)target_handle;
449
5.73M
    int32_t result = 0;
450
451
5.73M
    if (!source || !target)
452
0
        return MZ_PARAM_ERROR;
453
454
5.73M
    mz_crypt_hmac_reset(target_handle);
455
456
5.73M
    if (!target->ctx)
457
5.73M
        target->ctx = HMAC_CTX_new();
458
459
5.73M
    result = HMAC_CTX_copy(target->ctx, source->ctx);
460
5.73M
    if (!result) {
461
0
        target->error = ERR_get_error();
462
0
        return MZ_HASH_ERROR;
463
0
    }
464
465
5.73M
    return MZ_OK;
466
5.73M
}
467
468
6.86k
void *mz_crypt_hmac_create(void **handle) {
469
6.86k
    mz_crypt_hmac *hmac = NULL;
470
471
6.86k
    hmac = (mz_crypt_hmac *)calloc(1, sizeof(mz_crypt_hmac));
472
6.86k
    if (hmac)
473
6.86k
        hmac->algorithm = MZ_HASH_SHA256;
474
6.86k
    if (handle)
475
6.86k
        *handle = hmac;
476
477
6.86k
    return hmac;
478
6.86k
}
479
480
6.86k
void mz_crypt_hmac_delete(void **handle) {
481
6.86k
    mz_crypt_hmac *hmac = NULL;
482
6.86k
    if (!handle)
483
0
        return;
484
6.86k
    hmac = (mz_crypt_hmac *)*handle;
485
6.86k
    if (hmac) {
486
6.86k
        mz_crypt_hmac_reset(*handle);
487
6.86k
        free(hmac);
488
6.86k
    }
489
6.86k
    *handle = NULL;
490
6.86k
}
491
492
/***************************************************************************/
493
494
#if defined(MZ_ZIP_SIGNING)
495
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size,
496
    const char *cert_pwd, uint8_t **signature, int32_t *signature_size) {
497
    PKCS12 *p12 = NULL;
498
    EVP_PKEY *evp_pkey = NULL;
499
    BUF_MEM *buf_mem = NULL;
500
    BIO *cert_bio = NULL;
501
    BIO *message_bio = NULL;
502
    BIO *signature_bio = NULL;
503
    CMS_ContentInfo *cms = NULL;
504
    CMS_SignerInfo *signer_info = NULL;
505
    STACK_OF(X509) *ca_stack = NULL;
506
    X509 *cert = NULL;
507
    int32_t result = 0;
508
    int32_t err = MZ_OK;
509
510
    if (!message || !cert_data || !signature || !signature_size)
511
        return MZ_PARAM_ERROR;
512
513
    mz_crypt_init();
514
515
    *signature = NULL;
516
    *signature_size = 0;
517
518
    cert_bio = BIO_new_mem_buf(cert_data, cert_data_size);
519
520
    if (!d2i_PKCS12_bio(cert_bio, &p12))
521
        err = MZ_SIGN_ERROR;
522
    if (err == MZ_OK)
523
        result = PKCS12_parse(p12, cert_pwd, &evp_pkey, &cert, &ca_stack);
524
    if (result) {
525
        cms = CMS_sign(NULL, NULL, ca_stack, NULL, CMS_BINARY | CMS_PARTIAL);
526
        if (cms)
527
            signer_info = CMS_add1_signer(cms, cert, evp_pkey, EVP_sha256(), 0);
528
        if (!signer_info) {
529
            err = MZ_SIGN_ERROR;
530
        } else {
531
            message_bio = BIO_new_mem_buf(message, message_size);
532
            signature_bio = BIO_new(BIO_s_mem());
533
534
            result = CMS_final(cms, message_bio, NULL, CMS_BINARY);
535
            if (result)
536
                result = i2d_CMS_bio(signature_bio, cms);
537
            if (result) {
538
                BIO_flush(signature_bio);
539
                BIO_get_mem_ptr(signature_bio, &buf_mem);
540
541
                *signature_size = buf_mem->length;
542
                *signature = malloc(buf_mem->length);
543
544
                memcpy(*signature, buf_mem->data, buf_mem->length);
545
            }
546
#if 0
547
            BIO *yy = BIO_new_file("xyz", "wb");
548
            BIO_write(yy, *signature, *signature_size);
549
            BIO_flush(yy);
550
            BIO_free(yy);
551
#endif
552
        }
553
    }
554
555
    if (!result)
556
        err = MZ_SIGN_ERROR;
557
558
    if (cms)
559
        CMS_ContentInfo_free(cms);
560
    if (signature_bio)
561
        BIO_free(signature_bio);
562
    if (cert_bio)
563
        BIO_free(cert_bio);
564
    if (message_bio)
565
        BIO_free(message_bio);
566
    if (p12)
567
        PKCS12_free(p12);
568
569
    if (err != MZ_OK && *signature) {
570
        free(*signature);
571
        *signature = NULL;
572
        *signature_size = 0;
573
    }
574
575
    return err;
576
}
577
578
int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size) {
579
    CMS_ContentInfo *cms = NULL;
580
    STACK_OF(X509) *signers = NULL;
581
    STACK_OF(X509) *intercerts = NULL;
582
    X509_STORE *cert_store = NULL;
583
    X509_LOOKUP *lookup = NULL;
584
    X509_STORE_CTX *store_ctx = NULL;
585
    BIO *message_bio = NULL;
586
    BIO *signature_bio = NULL;
587
    BUF_MEM *buf_mem = NULL;
588
    int32_t signer_count = 0;
589
    int32_t result = 0;
590
    int32_t i = 0;
591
    int32_t err = MZ_SIGN_ERROR;
592
593
    if (!message || !message_size || !signature || !signature_size)
594
        return MZ_PARAM_ERROR;
595
596
    mz_crypt_init();
597
598
    cert_store = X509_STORE_new();
599
600
    X509_STORE_load_locations(cert_store, "cacert.pem", NULL);
601
    X509_STORE_set_default_paths(cert_store);
602
603
#if 0
604
    BIO *yy = BIO_new_file("xyz", "wb");
605
    BIO_write(yy, signature, signature_size);
606
    BIO_flush(yy);
607
    BIO_free(yy);
608
#endif
609
610
    lookup = X509_STORE_add_lookup(cert_store, X509_LOOKUP_file());
611
    if (lookup)
612
        X509_LOOKUP_load_file(lookup, "cacert.pem", X509_FILETYPE_PEM);
613
    lookup = X509_STORE_add_lookup(cert_store, X509_LOOKUP_hash_dir());
614
    if (lookup)
615
        X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
616
617
    signature_bio = BIO_new_mem_buf(signature, signature_size);
618
    message_bio = BIO_new(BIO_s_mem());
619
620
    cms = d2i_CMS_bio(signature_bio, NULL);
621
    if (cms) {
622
        result = CMS_verify(cms, NULL, cert_store, NULL, message_bio, CMS_NO_SIGNER_CERT_VERIFY | CMS_BINARY);
623
        if (result)
624
            signers = CMS_get0_signers(cms);
625
        if (signers)
626
            intercerts = CMS_get1_certs(cms);
627
        if (intercerts) {
628
            /* Verify signer certificates */
629
            signer_count = sk_X509_num(signers);
630
            if (signer_count > 0)
631
                err = MZ_OK;
632
633
            for (i = 0; i < signer_count; i++) {
634
                store_ctx = X509_STORE_CTX_new();
635
                X509_STORE_CTX_init(store_ctx, cert_store, sk_X509_value(signers, i), intercerts);
636
                result = X509_verify_cert(store_ctx);
637
                if (store_ctx)
638
                    X509_STORE_CTX_free(store_ctx);
639
640
                if (!result) {
641
                    err = MZ_SIGN_ERROR;
642
                    break;
643
                }
644
            }
645
        }
646
647
        BIO_get_mem_ptr(message_bio, &buf_mem);
648
649
        if (err == MZ_OK) {
650
            /* Verify the message */
651
            if (((int32_t)buf_mem->length != message_size) ||
652
                (memcmp(buf_mem->data, message, message_size) != 0))
653
                err = MZ_SIGN_ERROR;
654
        }
655
    }
656
657
#if 0
658
    if (!result)
659
        printf(ERR_error_string(ERR_get_error(), NULL));
660
#endif
661
662
    if (cms)
663
        CMS_ContentInfo_free(cms);
664
    if (message_bio)
665
        BIO_free(message_bio);
666
    if (signature_bio)
667
        BIO_free(signature_bio);
668
    if (cert_store)
669
        X509_STORE_free(cert_store);
670
671
    return err;
672
}
673
#endif