Coverage Report

Created: 2025-04-22 06:17

/src/neomutt/ncrypt/cryptglue.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file
3
 * Wrapper around crypto functions
4
 *
5
 * @authors
6
 * Copyright (C) 2017-2023 Richard Russon <rich@flatcap.org>
7
 * Copyright (C) 2019 Pietro Cerutti <gahr@gahr.ch>
8
 *
9
 * @copyright
10
 * This program is free software: you can redistribute it and/or modify it under
11
 * the terms of the GNU General Public License as published by the Free Software
12
 * Foundation, either version 2 of the License, or (at your option) any later
13
 * version.
14
 *
15
 * This program is distributed in the hope that it will be useful, but WITHOUT
16
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18
 * details.
19
 *
20
 * You should have received a copy of the GNU General Public License along with
21
 * this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
/**
25
 * @page crypt_cryptglue Wrapper around crypto functions
26
 *
27
 * This file dispatches the generic crypto functions to the implemented
28
 * backend or provides dummy stubs.
29
 *
30
 * @note Some generic functions are handled in crypt.c
31
 *
32
 * @note This file has been changed to make use of the new module system.
33
 * Consequently there's a 1:1 mapping between the functions contained in this
34
 * file and the functions implemented by the crypto modules.
35
 */
36
37
#include "config.h"
38
#include <stdbool.h>
39
#include <stdio.h>
40
#include "mutt/lib.h"
41
#include "core/lib.h"
42
#include "cryptglue.h"
43
#include "lib.h"
44
#include "crypt_mod.h"
45
#ifndef CRYPT_BACKEND_GPGME
46
#include "gui/lib.h"
47
#endif
48
#if defined(CRYPT_BACKEND_GPGME) || defined(USE_AUTOCRYPT)
49
#include "config/lib.h"
50
#endif
51
#ifdef USE_AUTOCRYPT
52
#include "email/lib.h"
53
#include "autocrypt/lib.h"
54
#include "crypt_gpgme.h"
55
#include "globals.h"
56
#else
57
struct Envelope;
58
#endif
59
60
struct Address;
61
struct AddressList;
62
63
#ifdef CRYPT_BACKEND_CLASSIC_PGP
64
extern const struct CryptModuleSpecs CryptModPgpClassic;
65
#endif
66
67
#ifdef CRYPT_BACKEND_CLASSIC_SMIME
68
extern const struct CryptModuleSpecs CryptModSmimeClassic;
69
#endif
70
71
#ifdef CRYPT_BACKEND_GPGME
72
extern const struct CryptModuleSpecs CryptModPgpGpgme;
73
extern const struct CryptModuleSpecs CryptModSmimeGpgme;
74
#endif
75
76
/* If the crypto module identifier by IDENTIFIER has been registered,
77
 * call its function FUNC.  Do nothing else.  This may be used as an
78
 * expression. */
79
#define CRYPT_MOD_CALL_CHECK(identifier, func)                                 \
80
0
  (crypto_module_lookup(APPLICATION_##identifier) &&                           \
81
0
   (crypto_module_lookup(APPLICATION_##identifier))->func)
82
83
/* Call the function FUNC in the crypto module identified by
84
 * IDENTIFIER. This may be used as an expression. */
85
#define CRYPT_MOD_CALL(identifier, func)                                       \
86
0
  (*(crypto_module_lookup(APPLICATION_##identifier))->func)
87
88
/**
89
 * crypt_init - Initialise the crypto backends
90
 *
91
 * This calls CryptModuleSpecs::init()
92
 */
93
void crypt_init(void)
94
0
{
95
#ifdef CRYPT_BACKEND_GPGME
96
  const bool c_crypt_use_gpgme = cs_subset_bool(NeoMutt->sub, "crypt_use_gpgme");
97
#endif
98
0
#ifdef CRYPT_BACKEND_CLASSIC_PGP
99
0
  if (
100
#ifdef CRYPT_BACKEND_GPGME
101
      (!c_crypt_use_gpgme)
102
#else
103
0
      1
104
0
#endif
105
0
  )
106
0
    crypto_module_register(&CryptModPgpClassic);
107
0
#endif
108
109
0
#ifdef CRYPT_BACKEND_CLASSIC_SMIME
110
0
  if (
111
#ifdef CRYPT_BACKEND_GPGME
112
      (!c_crypt_use_gpgme)
113
#else
114
0
      1
115
0
#endif
116
0
  )
117
0
    crypto_module_register(&CryptModSmimeClassic);
118
0
#endif
119
120
#ifdef CRYPT_BACKEND_GPGME
121
  if (c_crypt_use_gpgme)
122
  {
123
    crypto_module_register(&CryptModPgpGpgme);
124
    crypto_module_register(&CryptModSmimeGpgme);
125
  }
126
#endif
127
128
0
#if defined(CRYPT_BACKEND_CLASSIC_PGP) ||                                      \
129
0
    defined(CRYPT_BACKEND_CLASSIC_SMIME) || defined(CRYPT_BACKEND_GPGME)
130
0
  if (CRYPT_MOD_CALL_CHECK(PGP, init))
131
0
    CRYPT_MOD_CALL(PGP, init)();
132
133
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, init))
134
0
    CRYPT_MOD_CALL(SMIME, init)();
135
0
#endif
136
0
}
137
138
/**
139
 * crypt_cleanup - Clean up backend
140
 */
141
void crypt_cleanup(void)
142
0
{
143
0
  if (CRYPT_MOD_CALL_CHECK(PGP, cleanup))
144
0
    (CRYPT_MOD_CALL(PGP, cleanup))();
145
146
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, cleanup))
147
0
    (CRYPT_MOD_CALL(SMIME, cleanup))();
148
0
}
149
150
/**
151
 * crypt_invoke_message - Display an informative message
152
 * @param type Crypto type, see #SecurityFlags
153
 *
154
 * Show a message that a backend will be invoked.
155
 */
156
void crypt_invoke_message(SecurityFlags type)
157
0
{
158
0
  if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP))
159
0
    mutt_message(_("Invoking PGP..."));
160
0
  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME))
161
0
    mutt_message(_("Invoking S/MIME..."));
162
0
}
163
164
/**
165
 * crypt_has_module_backend - Is there a crypto backend for a given type?
166
 * @param type Crypto type, see #SecurityFlags
167
 * @retval true  Backend is present
168
 * @retval false Backend is not present
169
 */
170
bool crypt_has_module_backend(SecurityFlags type)
171
0
{
172
0
  if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP) &&
173
0
      crypto_module_lookup(APPLICATION_PGP))
174
0
  {
175
0
    return true;
176
0
  }
177
178
0
  if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME) &&
179
0
      crypto_module_lookup(APPLICATION_SMIME))
180
0
  {
181
0
    return true;
182
0
  }
183
184
0
  return false;
185
0
}
186
187
/**
188
 * crypt_pgp_void_passphrase - Wrapper for CryptModuleSpecs::void_passphrase()
189
 */
190
void crypt_pgp_void_passphrase(void)
191
0
{
192
0
  if (CRYPT_MOD_CALL_CHECK(PGP, void_passphrase))
193
0
    CRYPT_MOD_CALL(PGP, void_passphrase)();
194
0
}
195
196
/**
197
 * crypt_pgp_valid_passphrase - Wrapper for CryptModuleSpecs::valid_passphrase()
198
 */
199
bool crypt_pgp_valid_passphrase(void)
200
0
{
201
0
  if (CRYPT_MOD_CALL_CHECK(PGP, valid_passphrase))
202
0
    return CRYPT_MOD_CALL(PGP, valid_passphrase)();
203
204
0
  return false;
205
0
}
206
207
/**
208
 * crypt_pgp_decrypt_mime - Wrapper for CryptModuleSpecs::decrypt_mime()
209
 */
210
int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
211
0
{
212
#ifdef USE_AUTOCRYPT
213
  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
214
  if (c_autocrypt)
215
  {
216
    OptAutocryptGpgme = true;
217
    int result = pgp_gpgme_decrypt_mime(fp_in, fp_out, b, b_dec);
218
    OptAutocryptGpgme = false;
219
    if (result == 0)
220
    {
221
      b->is_autocrypt = true;
222
      return result;
223
    }
224
  }
225
#endif
226
227
0
  if (CRYPT_MOD_CALL_CHECK(PGP, decrypt_mime))
228
0
    return CRYPT_MOD_CALL(PGP, decrypt_mime)(fp_in, fp_out, b, b_dec);
229
230
0
  return -1;
231
0
}
232
233
/**
234
 * crypt_pgp_application_handler - Wrapper for CryptModuleSpecs::application_handler() - Implements ::handler_t - @ingroup handler_api
235
 */
236
int crypt_pgp_application_handler(struct Body *b_email, struct State *state)
237
0
{
238
0
  if (CRYPT_MOD_CALL_CHECK(PGP, application_handler))
239
0
    return CRYPT_MOD_CALL(PGP, application_handler)(b_email, state);
240
241
0
  return -1;
242
0
}
243
244
/**
245
 * crypt_pgp_encrypted_handler - Wrapper for CryptModuleSpecs::encrypted_handler() - Implements ::handler_t - @ingroup handler_api
246
 */
247
int crypt_pgp_encrypted_handler(struct Body *b_email, struct State *state)
248
0
{
249
#ifdef USE_AUTOCRYPT
250
  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
251
  if (c_autocrypt)
252
  {
253
    OptAutocryptGpgme = true;
254
    int result = pgp_gpgme_encrypted_handler(b_email, state);
255
    OptAutocryptGpgme = false;
256
    if (result == 0)
257
    {
258
      b_email->is_autocrypt = true;
259
      return result;
260
    }
261
  }
262
#endif
263
264
0
  if (CRYPT_MOD_CALL_CHECK(PGP, encrypted_handler))
265
0
    return CRYPT_MOD_CALL(PGP, encrypted_handler)(b_email, state);
266
267
0
  return -1;
268
0
}
269
270
/**
271
 * crypt_pgp_invoke_getkeys - Wrapper for CryptModuleSpecs::pgp_invoke_getkeys()
272
 */
273
void crypt_pgp_invoke_getkeys(struct Address *addr)
274
0
{
275
0
  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_invoke_getkeys))
276
0
    CRYPT_MOD_CALL(PGP, pgp_invoke_getkeys)(addr);
277
0
}
278
279
/**
280
 * crypt_pgp_check_traditional - Wrapper for CryptModuleSpecs::pgp_check_traditional()
281
 */
282
bool crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
283
0
{
284
0
  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_check_traditional))
285
0
    return CRYPT_MOD_CALL(PGP, pgp_check_traditional)(fp, b, just_one);
286
287
0
  return false;
288
0
}
289
290
/**
291
 * crypt_pgp_traditional_encryptsign - Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
292
 */
293
struct Body *crypt_pgp_traditional_encryptsign(struct Body *b, SecurityFlags flags, char *keylist)
294
0
{
295
0
  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_traditional_encryptsign))
296
0
    return CRYPT_MOD_CALL(PGP, pgp_traditional_encryptsign)(b, flags, keylist);
297
298
0
  return NULL;
299
0
}
300
301
/**
302
 * crypt_pgp_make_key_attachment - Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
303
 */
304
struct Body *crypt_pgp_make_key_attachment(void)
305
0
{
306
0
  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_make_key_attachment))
307
0
    return CRYPT_MOD_CALL(PGP, pgp_make_key_attachment)();
308
309
0
  return NULL;
310
0
}
311
312
/**
313
 * crypt_pgp_find_keys - Wrapper for CryptModuleSpecs::find_keys()
314
 */
315
char *crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
316
0
{
317
0
  if (CRYPT_MOD_CALL_CHECK(PGP, find_keys))
318
0
    return CRYPT_MOD_CALL(PGP, find_keys)(addrlist, oppenc_mode);
319
320
0
  return NULL;
321
0
}
322
323
/**
324
 * crypt_pgp_sign_message - Wrapper for CryptModuleSpecs::sign_message()
325
 */
326
struct Body *crypt_pgp_sign_message(struct Body *b, const struct AddressList *from)
327
0
{
328
0
  if (CRYPT_MOD_CALL_CHECK(PGP, sign_message))
329
0
    return CRYPT_MOD_CALL(PGP, sign_message)(b, from);
330
331
0
  return NULL;
332
0
}
333
334
/**
335
 * crypt_pgp_encrypt_message - Wrapper for CryptModuleSpecs::pgp_encrypt_message()
336
 */
337
struct Body *crypt_pgp_encrypt_message(struct Email *e, struct Body *b, char *keylist,
338
                                       int sign, const struct AddressList *from)
339
0
{
340
#ifdef USE_AUTOCRYPT
341
  if (e->security & SEC_AUTOCRYPT)
342
  {
343
    if (mutt_autocrypt_set_sign_as_default_key(e))
344
      return NULL;
345
346
    OptAutocryptGpgme = true;
347
    struct Body *result = pgp_gpgme_encrypt_message(b, keylist, sign, from);
348
    OptAutocryptGpgme = false;
349
350
    return result;
351
  }
352
#endif
353
354
0
  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_encrypt_message))
355
0
    return CRYPT_MOD_CALL(PGP, pgp_encrypt_message)(b, keylist, sign, from);
356
357
0
  return NULL;
358
0
}
359
360
/**
361
 * crypt_pgp_invoke_import - Wrapper for CryptModuleSpecs::pgp_invoke_import()
362
 */
363
void crypt_pgp_invoke_import(const char *fname)
364
0
{
365
0
  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_invoke_import))
366
0
    CRYPT_MOD_CALL(PGP, pgp_invoke_import)(fname);
367
0
}
368
369
/**
370
 * crypt_pgp_verify_one - Wrapper for CryptModuleSpecs::verify_one()
371
 */
372
int crypt_pgp_verify_one(struct Body *b, struct State *state, const char *tempf)
373
0
{
374
0
  if (CRYPT_MOD_CALL_CHECK(PGP, verify_one))
375
0
    return CRYPT_MOD_CALL(PGP, verify_one)(b, state, tempf);
376
377
0
  return -1;
378
0
}
379
380
/**
381
 * crypt_pgp_send_menu - Wrapper for CryptModuleSpecs::send_menu()
382
 */
383
SecurityFlags crypt_pgp_send_menu(struct Email *e)
384
0
{
385
0
  if (CRYPT_MOD_CALL_CHECK(PGP, send_menu))
386
0
    return CRYPT_MOD_CALL(PGP, send_menu)(e);
387
388
0
  return 0;
389
0
}
390
391
/**
392
 * crypt_pgp_extract_key_from_attachment - Wrapper for CryptModuleSpecs::pgp_extract_key_from_attachment()
393
 */
394
void crypt_pgp_extract_key_from_attachment(FILE *fp, struct Body *b)
395
0
{
396
0
  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_extract_key_from_attachment))
397
0
    CRYPT_MOD_CALL(PGP, pgp_extract_key_from_attachment)(fp, b);
398
0
}
399
400
/**
401
 * crypt_pgp_set_sender - Wrapper for CryptModuleSpecs::set_sender()
402
 */
403
void crypt_pgp_set_sender(const char *sender)
404
0
{
405
0
  if (CRYPT_MOD_CALL_CHECK(PGP, set_sender))
406
0
    CRYPT_MOD_CALL(PGP, set_sender)(sender);
407
0
}
408
409
/**
410
 * crypt_smime_void_passphrase - Wrapper for CryptModuleSpecs::void_passphrase()
411
 */
412
void crypt_smime_void_passphrase(void)
413
0
{
414
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, void_passphrase))
415
0
    CRYPT_MOD_CALL(SMIME, void_passphrase)();
416
0
}
417
418
/**
419
 * crypt_smime_valid_passphrase - Wrapper for CryptModuleSpecs::valid_passphrase()
420
 */
421
bool crypt_smime_valid_passphrase(void)
422
0
{
423
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, valid_passphrase))
424
0
    return CRYPT_MOD_CALL(SMIME, valid_passphrase)();
425
426
0
  return false;
427
0
}
428
429
/**
430
 * crypt_smime_decrypt_mime - Wrapper for CryptModuleSpecs::decrypt_mime()
431
 */
432
int crypt_smime_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
433
0
{
434
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, decrypt_mime))
435
0
    return CRYPT_MOD_CALL(SMIME, decrypt_mime)(fp_in, fp_out, b, b_dec);
436
437
0
  return -1;
438
0
}
439
440
/**
441
 * crypt_smime_application_handler - Wrapper for CryptModuleSpecs::application_handler() - Implements ::handler_t - @ingroup handler_api
442
 */
443
int crypt_smime_application_handler(struct Body *b_email, struct State *state)
444
0
{
445
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, application_handler))
446
0
    return CRYPT_MOD_CALL(SMIME, application_handler)(b_email, state);
447
448
0
  return -1;
449
0
}
450
451
/**
452
 * crypt_smime_getkeys - Wrapper for CryptModuleSpecs::smime_getkeys()
453
 */
454
void crypt_smime_getkeys(struct Envelope *env)
455
0
{
456
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, smime_getkeys))
457
0
    CRYPT_MOD_CALL(SMIME, smime_getkeys)(env);
458
0
}
459
460
/**
461
 * crypt_smime_verify_sender - Wrapper for CryptModuleSpecs::smime_verify_sender()
462
 */
463
int crypt_smime_verify_sender(struct Email *e, struct Message *msg)
464
0
{
465
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, smime_verify_sender))
466
0
    return CRYPT_MOD_CALL(SMIME, smime_verify_sender)(e, msg);
467
468
0
  return 1;
469
0
}
470
471
/**
472
 * crypt_smime_find_keys - Wrapper for CryptModuleSpecs::find_keys()
473
 */
474
char *crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
475
0
{
476
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, find_keys))
477
0
    return CRYPT_MOD_CALL(SMIME, find_keys)(addrlist, oppenc_mode);
478
479
0
  return NULL;
480
0
}
481
482
/**
483
 * crypt_smime_sign_message - Wrapper for CryptModuleSpecs::sign_message()
484
 */
485
struct Body *crypt_smime_sign_message(struct Body *b, const struct AddressList *from)
486
0
{
487
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, sign_message))
488
0
    return CRYPT_MOD_CALL(SMIME, sign_message)(b, from);
489
490
0
  return NULL;
491
0
}
492
493
/**
494
 * crypt_smime_build_smime_entity - Wrapper for CryptModuleSpecs::smime_build_smime_entity()
495
 */
496
struct Body *crypt_smime_build_smime_entity(struct Body *b, char *certlist)
497
0
{
498
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, smime_build_smime_entity))
499
0
    return CRYPT_MOD_CALL(SMIME, smime_build_smime_entity)(b, certlist);
500
501
0
  return NULL;
502
0
}
503
504
/**
505
 * crypt_smime_invoke_import - Wrapper for CryptModuleSpecs::smime_invoke_import()
506
 */
507
void crypt_smime_invoke_import(const char *infile, const char *mailbox)
508
0
{
509
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, smime_invoke_import))
510
0
    CRYPT_MOD_CALL(SMIME, smime_invoke_import)(infile, mailbox);
511
0
}
512
513
/**
514
 * crypt_smime_verify_one - Wrapper for CryptModuleSpecs::verify_one()
515
 */
516
int crypt_smime_verify_one(struct Body *b, struct State *state, const char *tempf)
517
0
{
518
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, verify_one))
519
0
    return CRYPT_MOD_CALL(SMIME, verify_one)(b, state, tempf);
520
521
0
  return -1;
522
0
}
523
524
/**
525
 * crypt_smime_send_menu - Wrapper for CryptModuleSpecs::send_menu()
526
 */
527
SecurityFlags crypt_smime_send_menu(struct Email *e)
528
0
{
529
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, send_menu))
530
0
    return CRYPT_MOD_CALL(SMIME, send_menu)(e);
531
532
0
  return 0;
533
0
}
534
535
/**
536
 * crypt_smime_set_sender - Wrapper for CryptModuleSpecs::set_sender()
537
 */
538
void crypt_smime_set_sender(const char *sender)
539
0
{
540
0
  if (CRYPT_MOD_CALL_CHECK(SMIME, set_sender))
541
0
    CRYPT_MOD_CALL(SMIME, set_sender)(sender);
542
0
}