/
rnp.h
3654 lines (3352 loc) · 167 KB
/
rnp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*-
* Copyright (c) 2017-2021 Ribose Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
* CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <rnp/rnp_export.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#if defined(__cplusplus)
extern "C" {
#endif
/**
* Function return type. 0 == SUCCESS, all other values indicate an error.
*/
typedef uint32_t rnp_result_t;
#define RNP_KEY_EXPORT_ARMORED (1U << 0)
#define RNP_KEY_EXPORT_PUBLIC (1U << 1)
#define RNP_KEY_EXPORT_SECRET (1U << 2)
#define RNP_KEY_EXPORT_SUBKEYS (1U << 3)
/* Export base64-encoded autocrypt key instead of binary */
#define RNP_KEY_EXPORT_BASE64 (1U << 9)
#define RNP_KEY_REMOVE_PUBLIC (1U << 0)
#define RNP_KEY_REMOVE_SECRET (1U << 1)
#define RNP_KEY_REMOVE_SUBKEYS (1U << 2)
#define RNP_KEY_UNLOAD_PUBLIC (1U << 0)
#define RNP_KEY_UNLOAD_SECRET (1U << 1)
/**
* Flags for optional details to include in JSON.
*/
#define RNP_JSON_PUBLIC_MPIS (1U << 0)
#define RNP_JSON_SECRET_MPIS (1U << 1)
#define RNP_JSON_SIGNATURES (1U << 2)
#define RNP_JSON_SIGNATURE_MPIS (1U << 3)
/**
* Flags to include additional data in packet dumping
*/
#define RNP_JSON_DUMP_MPI (1U << 0)
#define RNP_JSON_DUMP_RAW (1U << 1)
#define RNP_JSON_DUMP_GRIP (1U << 2)
#define RNP_DUMP_MPI (1U << 0)
#define RNP_DUMP_RAW (1U << 1)
#define RNP_DUMP_GRIP (1U << 2)
/**
* Flags for the key loading/saving functions.
*/
#define RNP_LOAD_SAVE_PUBLIC_KEYS (1U << 0)
#define RNP_LOAD_SAVE_SECRET_KEYS (1U << 1)
#define RNP_LOAD_SAVE_PERMISSIVE (1U << 8)
#define RNP_LOAD_SAVE_SINGLE (1U << 9)
#define RNP_LOAD_SAVE_BASE64 (1U << 10)
/**
* Flags for the rnp_key_remove_signatures
*/
#define RNP_KEY_SIGNATURE_INVALID (1U << 0)
#define RNP_KEY_SIGNATURE_UNKNOWN_KEY (1U << 1)
#define RNP_KEY_SIGNATURE_NON_SELF_SIG (1U << 2)
#define RNP_KEY_SIGNATURE_KEEP (0U)
#define RNP_KEY_SIGNATURE_REMOVE (1U)
/**
* Flags for output structure creation.
*/
#define RNP_OUTPUT_FILE_OVERWRITE (1U << 0)
#define RNP_OUTPUT_FILE_RANDOM (1U << 1)
/**
* Flags for default key selection.
*/
#define RNP_KEY_SUBKEYS_ONLY (1U << 0)
/**
* User id type
*/
#define RNP_USER_ID (1U)
#define RNP_USER_ATTR (2U)
/**
* Predefined feature security levels
*/
#define RNP_SECURITY_PROHIBITED (0U)
#define RNP_SECURITY_INSECURE (1U)
#define RNP_SECURITY_DEFAULT (2U)
/**
* Flags for feature security rules.
*/
#define RNP_SECURITY_OVERRIDE (1U << 0)
#define RNP_SECURITY_VERIFY_KEY (1U << 1)
#define RNP_SECURITY_VERIFY_DATA (1U << 2)
#define RNP_SECURITY_REMOVE_ALL (1U << 16)
/**
* Encryption flags
*/
#define RNP_ENCRYPT_NOWRAP (1U << 0)
/**
* Decryption/verification flags
*/
#define RNP_VERIFY_IGNORE_SIGS_ON_DECRYPT (1U << 0)
#define RNP_VERIFY_REQUIRE_ALL_SIGS (1U << 1)
#define RNP_VERIFY_ALLOW_HIDDEN_RECIPIENT (1U << 2)
/**
* Revocation key flags.
*/
#define RNP_REVOKER_SENSITIVE (1U << 0)
/**
* Key feature flags.
*/
#define RNP_KEY_FEATURE_MDC (1U << 0)
#define RNP_KEY_FEATURE_AEAD (1U << 1)
#define RNP_KEY_FEATURE_V5 (1U << 2)
/**
* Return a constant string describing the result code
*/
RNP_API const char *rnp_result_to_string(rnp_result_t result);
RNP_API const char *rnp_version_string();
RNP_API const char *rnp_version_string_full();
/** return a value representing the version of librnp
*
* This function is only useful for releases. For non-releases,
* it will return 0.
*
* The value returned can be used in comparisons by utilizing
* rnp_version_for.
*
* @return a value representing the librnp version
**/
RNP_API uint32_t rnp_version();
/** return a value representing a specific version of librnp
*
* This value can be used in comparisons.
*
* @return a value representing a librnp version
**/
RNP_API uint32_t rnp_version_for(uint32_t major, uint32_t minor, uint32_t patch);
/** return the librnp major version
*
* @return
**/
RNP_API uint32_t rnp_version_major(uint32_t version);
/** return the librnp minor version
*
* @return
**/
RNP_API uint32_t rnp_version_minor(uint32_t version);
/** return the librnp patch version
*
* @return
**/
RNP_API uint32_t rnp_version_patch(uint32_t version);
/** return a unix timestamp of the last commit, if available
*
* This function is only useful for non-releases. For releases,
* it will return 0.
*
* The intended usage is to provide a form of versioning for the main
* branch.
*
* @return the unix timestamp of the last commit, or 0 if unavailable
**/
RNP_API uint64_t rnp_version_commit_timestamp();
#ifndef RNP_NO_DEPRECATED
/** @brief This function is deprecated and should not be used anymore. It would just silently
* return RNP_SUCCESS.
*
* @param file name of the sourcer file. Use 'all' to enable debug for all code.
*
*/
RNP_API RNP_DEPRECATED rnp_result_t rnp_enable_debug(const char *file);
/**
* @brief This function is deprecated and should not be used anymore. It would just silently
* return RNP_SUCCESS.
*
*/
RNP_API RNP_DEPRECATED rnp_result_t rnp_disable_debug();
#endif
/*
* Opaque structures
*/
typedef struct rnp_ffi_st * rnp_ffi_t;
typedef struct rnp_key_handle_st * rnp_key_handle_t;
typedef struct rnp_input_st * rnp_input_t;
typedef struct rnp_output_st * rnp_output_t;
typedef struct rnp_op_generate_st * rnp_op_generate_t;
typedef struct rnp_op_sign_st * rnp_op_sign_t;
typedef struct rnp_op_sign_signature_st * rnp_op_sign_signature_t;
typedef struct rnp_op_verify_st * rnp_op_verify_t;
typedef struct rnp_op_verify_signature_st *rnp_op_verify_signature_t;
typedef struct rnp_op_encrypt_st * rnp_op_encrypt_t;
typedef struct rnp_identifier_iterator_st *rnp_identifier_iterator_t;
typedef struct rnp_uid_handle_st * rnp_uid_handle_t;
typedef struct rnp_signature_handle_st * rnp_signature_handle_t;
typedef struct rnp_recipient_handle_st * rnp_recipient_handle_t;
typedef struct rnp_symenc_handle_st * rnp_symenc_handle_t;
/* Callbacks */
/**
* @brief Callback, used to read data from the source.
*
* @param app_ctx custom parameter, passed back to the function.
* @param buf on successful call data should be put here. Cannot be NULL,
* and must be capable to store at least len bytes.
* @param len number of bytes to read.
* @param read on successful call number of read bytes must be put here.
* @return true on success (including EOF condition), or false on read error.
* EOF case is indicated by zero bytes read on non-zero read call.
*/
typedef bool rnp_input_reader_t(void *app_ctx, void *buf, size_t len, size_t *read);
/**
* @brief Callback, used to close input stream.
*
* @param app_ctx custom parameter, passed back to the function.
* @return void
*/
typedef void rnp_input_closer_t(void *app_ctx);
/**
* @brief Callback, used to write data to the output stream.
*
* @param app_ctx custom parameter, passed back to the function.
* @param buf buffer with data, cannot be NULL.
* @param len number of bytes to write.
* @return true if call was successful and all data is written, or false otherwise.
*/
typedef bool rnp_output_writer_t(void *app_ctx, const void *buf, size_t len);
/**
* @brief Callback, used to close output stream.
*
* @param app_ctx custom parameter, passed back to the function.
* @param discard true if the already written data should be deleted.
* @return void
*/
typedef void rnp_output_closer_t(void *app_ctx, bool discard);
/**
* Callback used for getting a password.
*
* @param ffi
* @param app_ctx provided by application
* @param key the key, if any, for which the password is being requested.
* Note: this key handle should not be held by the application,
* it is destroyed after the callback. It should only be used to
* retrieve information like the userids, grip, etc.
* @param pgp_context a descriptive string on why the password is being
* requested, may have one of the following values:
* - "add subkey": add subkey to the encrypted secret key
* - "add userid": add userid to the encrypted secret key
* - "sign": sign data
* - "decrypt": decrypt data using the encrypted secret key
* - "unlock": temporary unlock secret key (decrypting its fields), so it may be used
* later without need to decrypt
* - "protect": encrypt secret key fields
* - "unprotect": decrypt secret key fields, leaving those in a raw format
* - "decrypt (symmetric)": decrypt data, using the password
* - "encrypt (symmetric)": encrypt data, using the password
* @param buf to which the callback should write the returned password, NULL terminated.
* @param buf_len the size of buf
* @return true if a password was provided, false otherwise
*/
typedef bool (*rnp_password_cb)(rnp_ffi_t ffi,
void * app_ctx,
rnp_key_handle_t key,
const char * pgp_context,
char buf[],
size_t buf_len);
/** callback used to signal the application that a key is needed
*
* The application should use the appropriate functions (rnp_load_keys() or
* rnp_import_keys()) to load the requested key.
*
* This may be called multiple times for the same key. For example, if attempting
* to verify a signature, the signer's keyid may be used first to request the key.
* If that is not successful, the signer's fingerprint (if available) may be used.
*
* Please note that there is a special case with 'hidden' recipient, with all-zero keyid. In
* this case implementation should load all available secret keys for the decryption attempt
* (or do nothing, in this case decryption to the hidden recipient would fail).
*
* Situations in which this callback would be used include:
* - When decrypting data that includes a public-key encrypted session key,
* and the key is not found in the keyrings.
* - When attempting to verify a signature, when the signer's key is not found in
* the keyrings.
*
* @param ffi
* @param app_ctx provided by application in rnp_ffi_set_key_provider()
* @param identifier_type the type of identifier ("userid", "keyid", "grip")
* @param identifier the identifier for locating the key
* @param secret true if a secret key is being requested
*/
typedef void (*rnp_get_key_cb)(rnp_ffi_t ffi,
void * app_ctx,
const char *identifier_type,
const char *identifier,
bool secret);
/**
* @brief callback used to report back signatures from the function
* rnp_key_remove_signatures(). This may be used to implement custom signature filtering
* code or record information about the signatures which are removed.
* @param ffi
* @param app_ctx custom context, provided by application.
* @param sig signature handle to retrieve information about the signature. Callback must not
* call rnp_signature_handle_destroy() on it.
* @param action action which will be performed on the signature. Currently defined are
* RNP_KEY_SIGNATURE_KEEP an RNP_KEY_SIGNATURE_REMOVE.
* Callback may overwrite this value.
*
*/
typedef void (*rnp_key_signatures_cb)(rnp_ffi_t ffi,
void * app_ctx,
rnp_signature_handle_t sig,
uint32_t * action);
/** create the top-level object used for interacting with the library
*
* @param ffi pointer that will be set to the created ffi object
* @param pub_format the format of the public keyring, RNP_KEYSTORE_GPG or other
* RNP_KEYSTORE_* constant
* @param sec_format the format of the secret keyring, RNP_KEYSTORE_GPG or other
* RNP_KEYSTORE_* constant
* @return RNP_SUCCESS on success, or any other value on error
*/
RNP_API rnp_result_t rnp_ffi_create(rnp_ffi_t * ffi,
const char *pub_format,
const char *sec_format);
/** destroy the top-level object used for interacting with the library
*
* Note that this invalidates key handles, keyrings, and any other
* objects associated with this particular object.
*
* @param ffi the ffi object
* @return RNP_SUCCESS on success, or any other value on error
*/
RNP_API rnp_result_t rnp_ffi_destroy(rnp_ffi_t ffi);
RNP_API rnp_result_t rnp_ffi_set_log_fd(rnp_ffi_t ffi, int fd);
/**
* @brief Set key provider callback. This callback would be called in case when required public
* or secret key is not loaded to the keyrings.
*
* @param ffi initialized ffi object, cannot be NULL.
* @param getkeycb callback function. See rnp_get_key_cb documentation for details.
* @param getkeycb_ctx implementation-specific context, which would be passed to the getkeycb
* on invocation.
* @return RNP_SUCCESS on success, or any other value on error.
*/
RNP_API rnp_result_t rnp_ffi_set_key_provider(rnp_ffi_t ffi,
rnp_get_key_cb getkeycb,
void * getkeycb_ctx);
RNP_API rnp_result_t rnp_ffi_set_pass_provider(rnp_ffi_t ffi,
rnp_password_cb getpasscb,
void * getpasscb_ctx);
/* Operations on key rings */
/** retrieve the default homedir (example: /home/user/.rnp)
*
* @param homedir pointer that will be set to the homedir path.
* The caller should free this with rnp_buffer_destroy.
* @return RNP_SUCCESS on success, or any other value on error
*/
RNP_API rnp_result_t rnp_get_default_homedir(char **homedir);
/** Try to detect the formats and paths of the homedir keyrings.
* @param homedir the path to the home directory (example: /home/user/.rnp)
* @param pub_format pointer that will be set to the format of the public keyring.
* The caller should free this with rnp_buffer_destroy.
* Note: this and below may be set to NULL in case of no known format is found.
* @param pub_path pointer that will be set to the path to the public keyring.
* The caller should free this with rnp_buffer_destroy.
* @param sec_format pointer that will be set to the format of the secret keyring.
* The caller should free this with rnp_buffer_destroy.
* @param sec_path pointer that will be set to the path to the secret keyring.
* The caller should free this with rnp_buffer_destroy.
* @return RNP_SUCCESS on success (even if no known format was found), or any other value on
* error.
*/
RNP_API rnp_result_t rnp_detect_homedir_info(
const char *homedir, char **pub_format, char **pub_path, char **sec_format, char **sec_path);
/** try to detect the key format of the provided data
*
* @param buf the key data, must not be NULL
* @param buf_len the size of the buffer, must be > 0
* @param format pointer that will be set to the format of the keyring.
* Must not be NULL. The caller should free this with rnp_buffer_destroy.
* @return RNP_SUCCESS on success, or any other value on error
*/
RNP_API rnp_result_t rnp_detect_key_format(const uint8_t buf[], size_t buf_len, char **format);
/** Get the number of s2k hash iterations, based on calculation time requested.
* Number of iterations is used to derive encryption key from password.
*
* @param hash hash algorithm to try
* @param msec number of milliseconds which will be needed to derive key from the password.
* Since it depends on CPU speed the calculated value will make sense only for the
* system it was calculated for.
* @param iterations approximate number of iterations to satisfy time complexity.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_calculate_iterations(const char *hash,
size_t msec,
size_t * iterations);
/** Check whether rnp supports specific feature (algorithm, elliptic curve, whatever else).
*
* @param type string with the feature type. See RNP_FEATURE_* defines for the supported
* values.
* @param name value of the feature to check whether it is supported.
* @param supported will contain true or false depending whether feature is supported or not.
* @return RNP_SUCCESS on success or any other value on error.
*/
RNP_API rnp_result_t rnp_supports_feature(const char *type, const char *name, bool *supported);
/** Get the JSON with array of supported rnp feature values (algorithms, curves, etc) by type.
*
* @param type type of the feature. See RNP_FEATURE_* defines for the supported values.
* @param result after successful execution will contain the JSON array with supported feature
* string values. You must destroy it using the rnp_buffer_destroy() function.\n
* Example JSON array output listing available hash algorithms:\n
*
* [
* "MD5",
* "SHA1",
* "RIPEMD160",
* "SHA256",
* "SHA384",
* "SHA512",
* "SHA224",
* "SHA3-256",
* "SHA3-512"
* ]
*
* @return RNP_SUCCESS on success or any other value on error.
*/
RNP_API rnp_result_t rnp_supported_features(const char *type, char **result);
/**
* @brief Add new security rule to the FFI. Security rules allows to override default algorithm
* security settings by disabling them or marking as insecure. After creation of FFI
* object default rules are added, however caller may add more strict rules or
* completely overwrite rule table by calling rnp_remove_security_rule().
* Note: key signature validation status is cached, so rules should be changed before
* keyrings are loaded or keyring should be reloaded after updating rules.
*
* @param ffi initialized FFI object.
* @param type type of the feature, cannot be NULL. Currently only RNP_FEATURE_HASH_ALG is
* supported.
* @param name name of the feature, i.e. SHA1, MD5. The same values are used in
* rnp_supports_feature()/rnp_supported_features().
* @param flags additional flags. Following ones currently supported:
* - RNP_SECURITY_OVERRIDE : override all other rules for the specified feature.
* May be used to temporarily enable or disable some feature value (e.g., to
* enable verification of SHA1 or MD5 signature), and then revert changes via
* rnp_remove_security_rule().
* - RNP_SECURITY_VERIFY_KEY : limit rule only to the key signature verification.
* - RNP_SECURITY_VERIFY_DATA : limit rule only to the data signature
* verification.
* Note: by default rule applies to all possible usages.
*
* @param from timestamp, from when the rule is active. Objects that have creation time (like
* signatures) are matched with the closest rules from the past, unless there is
* a rule with an override flag. For instance, given a single rule with algorithm
* 'MD5', level 'insecure' and timestamp '2012-01-01', all signatures made before
* 2012-01-01 using the MD5 hash algorithm are considered to be at the default
* security level (i.e., valid), whereas all signatures made after 2021-01-01 will
* be marked as 'insecure' (i.e., invalid).
* @param level security level of the rule. Currently the following ones are defined:
* - RNP_SECURITY_PROHIBITED : feature (for instance, MD5 algorithm) is completely
* disabled, so no processing can be done. In terms of signature check, that
* would mean the check will fail right after the hashing begins.
* Note: Currently it works in the same way as RNP_SECURITY_INSECURE.
* - RNP_SECURITY_INSECURE : feature (for instance, SHA1 algorithm) is marked as
* insecure. So even valid signatures, produced later than `from`, will be
* marked as invalid.
* - RNP_SECURITY_DEFAULT : feature is secure enough. Default value when there are
* no other rules for feature.
*
* @return RNP_SUCCESS or any other value on error.
*/
RNP_API rnp_result_t rnp_add_security_rule(rnp_ffi_t ffi,
const char *type,
const char *name,
uint32_t flags,
uint64_t from,
uint32_t level);
/**
* @brief Get security rule applicable for the corresponding feature value and timestamp.
* Note: if there is no matching rule, it will fall back to the default security level
* with empty flags and `from`.
*
* @param ffi initialized FFI object.
* @param type feature type to search for. Only RNP_FEATURE_HASH_ALG is supported right now.
* @param name feature name, i.e. SHA1 or so on.
* @param time timestamp for which feature should be checked.
* @param flags if non-NULL then rule's flags will be put here. In this case *flags must be
* initialized to the desired usage limitation:
* - 0 to look up for any usage (this is also assumed if flags parameter is
* NULL).
* - RNP_SECURITY_VERIFY_KEY, RNP_SECURITY_VERIFY_DATA and so on to look up for
* the specific usage. Please note that constants cannot be ORed here, only
* single one must be present.
* @param from if non-NULL then rule's from time will be put here.
* @param level cannot be NULL. Security level will be stored here.
* @return RNP_SUCCESS or any other value on error.
*/
RNP_API rnp_result_t rnp_get_security_rule(rnp_ffi_t ffi,
const char *type,
const char *name,
uint64_t time,
uint32_t * flags,
uint64_t * from,
uint32_t * level);
/**
* @brief Remove security rule(s), matching the parameters.
* Note: use this with caution, as this may also clear default security rules, so
* all affected features would be considered of the default security level.
*
* @param ffi populated FFI structure, cannot be NULL.
* @param type type of the feature. If NULL, then all of the rules will be cleared.
* @param name name of the feature. If NULL, then all rules of the type will be cleared.
* @param level security level of the rule.
* @param flags additional flags, following are defined at the moment:
* - RNP_SECURITY_OVERRIDE : rule should match this flag
* - RNP_SECURITY_VERIFY_KEY, RNP_SECURITY_VERIFY_DATA : rule should match these flags
* (can be ORed together)
* - RNP_SECURITY_REMOVE_ALL : remove all rules for type and name.
* @param from timestamp, for when the rule should be removed. Ignored if
* RNP_SECURITY_REMOVE_ALL_FROM is specified.
* @param removed if non-NULL then number of removed rules will be stored here.
* @return RNP_SUCCESS on success or any other value on error. Please note that if no rules are
* matched, execution will be marked as successful. Use the `removed` parameter to
* check for this case.
*/
RNP_API rnp_result_t rnp_remove_security_rule(rnp_ffi_t ffi,
const char *type,
const char *name,
uint32_t level,
uint32_t flags,
uint64_t from,
size_t * removed);
/**
* @brief Request password via configured FFI's callback
*
* @param ffi initialized FFI structure
* @param key key handle for which password is requested. May be NULL.
* @param context string describing the purpose of password request. See description of
* rnp_password_cb for the list of possible values. Also you may use any
* custom one as far as your password callback handles it.
* @param password password will be put here on success. Must be destroyed via
* rnp_buffer_destroy(), also it is good idea to securely clear it via
* rnp_buffer_clear().
* @return RNP_SUCCESS or other value on error.
*/
RNP_API rnp_result_t rnp_request_password(rnp_ffi_t ffi,
rnp_key_handle_t key,
const char * context,
char ** password);
/**
* @brief Set timestamp, used in all operations instead of system's time. These operations
* include key/signature generation (this timestamp will be used as signature/key
* creation date), verification of the keys and signatures (this timestamp will be used
* as 'current' time).
* Please note, that exactly this timestamp will be used during the whole ffi lifetime.
*
* @param ffi initialized FFI structure
* @param time non-zero timestamp to be used. Zero value restores original behaviour and uses
* system's time.
* @return RNP_SUCCESS or other value on error.
*/
RNP_API rnp_result_t rnp_set_timestamp(rnp_ffi_t ffi, uint64_t time);
/** load keys
*
* Note that for G10, the input must be a directory (which must already exist).
*
* @param ffi
* @param format the key format of the data (GPG, KBX, G10). Must not be NULL.
* @param input source to read from.
* @param flags the flags. See RNP_LOAD_SAVE_*.
* @return RNP_SUCCESS on success, or any other value on error
*/
RNP_API rnp_result_t rnp_load_keys(rnp_ffi_t ffi,
const char *format,
rnp_input_t input,
uint32_t flags);
/** unload public and/or secret keys
* Note: After unloading all key handles will become invalid and must be destroyed.
* @param ffi
* @param flags choose which keys should be unloaded (pubic, secret or both).
* See RNP_KEY_UNLOAD_PUBLIC/RNP_KEY_UNLOAD_SECRET.
* @return RNP_SUCCESS on success, or any other value on error.
*/
RNP_API rnp_result_t rnp_unload_keys(rnp_ffi_t ffi, uint32_t flags);
/** import keys to the keyring and receive JSON list of the new/updated keys.
* Note: this will work only with keys in OpenPGP format, use rnp_load_keys for other formats.
* @param ffi
* @param input source to read from. Cannot be NULL.
* @param flags see RNP_LOAD_SAVE_* constants. If RNP_LOAD_SAVE_PERMISSIVE is specified
* then import process will skip unrecognized or bad keys/signatures instead of
* failing the whole operation.
* If flag RNP_LOAD_SAVE_SINGLE is set, then only first key will be loaded (subkey
* or primary key with its subkeys). In case RNP_LOAD_SAVE_PERMISSIVE and
* erroneous first key on the stream RNP_SUCCESS will be returned, but results
* will include an empty array. Also RNP_ERROR_EOF will be returned if the last
* key was read.
* RNP_LOAD_SAVE_BASE64 should set to allow import of base64-encoded keys (i.e.
* autocrypt ones). By default only binary and OpenPGP-armored keys are allowed.
* @param results if not NULL then after the successful execution will contain JSON with
* information about new and updated keys. You must free it using the
* rnp_buffer_destroy() function.
* JSON output is an object containing array of objects named "keys".
* Each array item is an object representing an imported key.
* It contains the following members:\n
* JSON member | Description
* -------------|------------
* "public" | string, status of a public key, one of "new", "updated", "unchanged", "none"
* "secret" | string, status of a secret key, same possible values as for public
* "fingerprint"| string, hexadecimal fingerprint of the key
* Example of JSON output:\n
*
* {
* "keys":[
* {
* "public":"unchanged",
* "secret":"new",
* "fingerprint":"090bd712a1166be572252c3c9747d2a6b3a63124"
* }
* ]
* }
*
* @return RNP_SUCCESS on success
* RNP_ERROR_EOF if last key was read (if RNP_LOAD_SAVE_SINGLE was used)
* any other value on error.
*/
RNP_API rnp_result_t rnp_import_keys(rnp_ffi_t ffi,
rnp_input_t input,
uint32_t flags,
char ** results);
/** import standalone signatures to the keyring and receive JSON list of the updated
* signatures.
*
* @param ffi
* @param input source to read from. Cannot be NULL.
* @param flags additional import flags, currently must be 0.
* @param results if not NULL then after the successful execution will contain JSON with
* information about the updated signatures. You must free it using the
* rnp_buffer_destroy() function.
* JSON output is an object containing array of objects named "sigs".
* Each array item is an object representing imported signature.
* It contains the following members:\n
* JSON member | Description
* --------------------|------------
* "public" |string, signature import status in a public keyring
* "secret" |string, signature import status in a secret keyring
* "signer fingerprint"|string, optional, fingerprint of a signing key
* "public" and "secret" status strings can have any of these string values:
* "new", "unchanged", "unknown key", "none".
* The "signer fingerprint" member could be missing
* if the signer key is not available.\n
* Example JSON output:\n
*
* {
* "sigs":[
* {
* "public":"new",
* "secret":"unknown key",
* "signer fingerprint":"73edcc9119afc8e2dbbdcde50451409669ffde3c"
* },
* {
* "public":"none",
* "secret":"none",
* }
* ]
* }
*
* @return RNP_SUCCESS on success, or any other value on error.
*/
RNP_API rnp_result_t rnp_import_signatures(rnp_ffi_t ffi,
rnp_input_t input,
uint32_t flags,
char ** results);
/** save keys
*
* Note that for G10, the output must be a directory (which must already exist).
*
* @param ffi
* @param format the key format of the data (GPG, KBX, G10). Must not be NULL.
* @param output the output destination to write to.
* @param flags the flags. See RNP_LOAD_SAVE_*.
* @return RNP_SUCCESS on success, or any other value on error
*/
RNP_API rnp_result_t rnp_save_keys(rnp_ffi_t ffi,
const char * format,
rnp_output_t output,
uint32_t flags);
RNP_API rnp_result_t rnp_get_public_key_count(rnp_ffi_t ffi, size_t *count);
RNP_API rnp_result_t rnp_get_secret_key_count(rnp_ffi_t ffi, size_t *count);
/** Search for the key
* Note: only valid userids are checked while searching by userid.
*
* @param ffi
* @param identifier_type string with type of the identifier: userid, keyid, fingerprint, grip
* @param identifier for userid is the userid string, for other search types - hex string
* representation of the value
* @param key if key was found then the resulting key handle will be stored here, otherwise it
* will contain NULL value. You must free handle after use with rnp_key_handle_destroy.
* @return RNP_SUCCESS on success (including case where key is not found), or any other value
* on error
*/
RNP_API rnp_result_t rnp_locate_key(rnp_ffi_t ffi,
const char * identifier_type,
const char * identifier,
rnp_key_handle_t *key);
RNP_API rnp_result_t rnp_key_handle_destroy(rnp_key_handle_t key);
/** generate a key or pair of keys using a JSON description
*
* Notes:
* - When generating a subkey, the pass provider may be required.
*
* @param ffi
* @param json the json data that describes the key generation.
* Must not be NULL.
* JSON input must be an object containing one or two members:\n
*
* JSON member | Description
* ------------|------------
* "primary" | JSON object describing parameters of primary key generation.
* "sub" | optional member, JSON object describing subkey generation parameters.
* Both "primary" and "sub" objects can contain the following members,
* if not specified otherwise:\n
* JSON member | Description
* -------------|------------
* "type" | string, key algorithm, see rnp_op_generate_create()
* "length" | integer, key size in bits, see rnp_op_generate_set_bits()
* "curve" | string, curve name, see rnp_op_generate_set_curve()
* "expiration" | integer, see rnp_op_generate_set_expiration()
* "usage" | string or array of strings, see rnp_op_generate_add_usage()
* "hash" | string, hash algorithm, see rnp_op_generate_set_hash()
* "userid" | string, primary key only, user ID, see rnp_op_generate_set_userid()
* "preferences"| object, primary key only, user preferences, see description below
* "protection" | object, secret key protection settings, see description below
* The "preferences" member object can contain the following members:\n
* JSON member | Description
* -------------|------------
* "hashes" | array of strings, see rnp_op_generate_add_pref_hash()
* "ciphers" | array of strings, see rnp_op_generate_add_pref_cipher()
* "compression"| array of strings, see rnp_op_generate_add_pref_compression()
* "key server" | string, see rnp_op_generate_set_pref_keyserver()
* The "protection" member object describes the secret key protection settings
* and it can contain the following members:\n
* JSON member | Description
* ------------|------------
* "cipher" | string, protection cipher, see rnp_op_generate_set_protection_cipher()
* "hash" | string, protection hash, see rnp_op_generate_set_protection_hash()
* "mode" | string, protection mode, see rnp_op_generate_set_protection_mode()
* "iterations"| integer, see rnp_op_generate_set_protection_iterations()
* Example JSON input:\n
*
* {
* "primary": {
* "type": "ECDSA",
* "curve": "NIST P-256",
* "userid": "test0",
* "usage": "sign",
* "expiration": 0,
* "hash": "SHA256",
* "preferences" : {
* "hashes": ["SHA512", "SHA256"],
* "ciphers": ["AES256", "AES128"],
* "compression": ["Zlib"],
* "key server": "hkp://pgp.mit.edu"
* },
* "protection" : {
* "cipher": "AES256",
* "hash": "SHA256",
* "mode": "CBC",
* "iterations": 65536
* }
* },
* "sub": {
* "type": "RSA",
* "length": 1024
* }
* }
*
* @param results pointer that will be set to the JSON results.
* Must not be NULL. The caller should free this with rnp_buffer_destroy.
* Serialized JSON output will contain a JSON object with a mandatory
* "primary" member object for the generated primary key and an optional "sub"
* member object if the subkey generation was requested. Both of them contain
* a single string member "grip" that holds
* hexadecimal key grip of a generated key.\n
* Example JSON output:\n
*
* {
* "primary":{
* "grip":"9F593A6333467A534BE8520CAE2600206BFE3681"
* },
* "sub":{
* "grip":"ED822D77DDF199707B13D0E1BCA00868314FE47D"
* }
* }
*
* @return RNP_SUCCESS on success, or any other value on error
*/
RNP_API rnp_result_t rnp_generate_key_json(rnp_ffi_t ffi, const char *json, char **results);
/* Key operations */
/** Shortcut function for rsa key-subkey pair generation. See rnp_generate_key_ex() for the
* detailed parameters description.
*/
RNP_API rnp_result_t rnp_generate_key_rsa(rnp_ffi_t ffi,
uint32_t bits,
uint32_t subbits,
const char * userid,
const char * password,
rnp_key_handle_t *key);
/** Shortcut function for DSA/ElGamal key-subkey pair generation. See rnp_generate_key_ex() for
* the detailed parameters description.
*/
RNP_API rnp_result_t rnp_generate_key_dsa_eg(rnp_ffi_t ffi,
uint32_t bits,
uint32_t subbits,
const char * userid,
const char * password,
rnp_key_handle_t *key);
/** Shortcut function for ECDSA/ECDH key-subkey pair generation. See rnp_generate_key_ex() for
* the detailed parameters description.
*/
RNP_API rnp_result_t rnp_generate_key_ec(rnp_ffi_t ffi,
const char * curve,
const char * userid,
const char * password,
rnp_key_handle_t *key);
/** Shortcut function for EdDSA/x25519 key-subkey pair generation. See rnp_generate_key_ex()
* for the detailed parameters description.
*/
RNP_API rnp_result_t rnp_generate_key_25519(rnp_ffi_t ffi,
const char * userid,
const char * password,
rnp_key_handle_t *key);
/** Shortcut function for SM2/SM2 key-subkey pair generation. See rnp_generate_key_ex() for
* for the detailed parameters description.
*/
RNP_API rnp_result_t rnp_generate_key_sm2(rnp_ffi_t ffi,
const char * userid,
const char * password,
rnp_key_handle_t *key);
/**
* @brief Shortcut for quick key generation. It is used in other shortcut functions for
* key generation (rnp_generate_key_*).
*
* @param ffi
* @param key_alg string with primary key algorithm. Cannot be NULL.
* @param sub_alg string with subkey algorithm. If NULL then subkey will not be generated.
* @param key_bits size of key in bits. If zero then default value will be used.
* Must be zero for EC-based primary key algorithm (use curve instead).
* @param sub_bits size of subkey in bits. If zero then default value will be used.
* Must be zero for EC-based subkey algorithm (use scurve instead).
* @param key_curve Curve name. Must be non-NULL only with EC-based primary key algorithm,
* otherwise error will be returned.
* @param sub_curve Subkey curve name. Must be non-NULL only with EC-based subkey algorithm,
* otherwise error will be returned.
* @param userid String with userid. Cannot be NULL.
* @param password String with password which would be used to protect the key and subkey.
* If NULL then key will be stored in cleartext (unencrypted).
* @param key if non-NULL, then handle of the primary key will be stored here on success.
* Caller must destroy it with rnp_key_handle_destroy() call.
* @return RNP_SUCCESS or error code instead.
*/
RNP_API rnp_result_t rnp_generate_key_ex(rnp_ffi_t ffi,
const char * key_alg,
const char * sub_alg,
uint32_t key_bits,
uint32_t sub_bits,
const char * key_curve,
const char * sub_curve,
const char * userid,
const char * password,
rnp_key_handle_t *key);
/** Create key generation context for the primary key.
* To generate a subkey use function rnp_op_generate_subkey_create() instead.
* Note: pass provider is required if generated key needs protection.
*
* @param op pointer to opaque key generation context.
* @param ffi
* @param alg key algorithm as string. Must be able to sign. Currently the following algorithms
* are supported (case-insensetive) : 'rsa', 'dsa', 'ecdsa', 'eddsa', 'sm2'.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_op_generate_create(rnp_op_generate_t *op,
rnp_ffi_t ffi,
const char * alg);
/** Create key generation context for the subkey.
* Note: you need to have primary key before calling this function. It can be loaded from
* keyring or generated via the function rnp_op_generate_create(). Also pass provider is needed
* if primary key is encrypted (protected and locked).
*
* @param op pointer to opaque key generation context.
* @param ffi
* @param primary primary key handle, must have secret part.
* @param alg key algorithm as string. Currently the following algorithms are supported
* (case-insensetive) : 'rsa', 'dsa', 'elgamal', 'ecdsa', 'eddsa', 'ecdh', 'sm2'.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_op_generate_subkey_create(rnp_op_generate_t *op,
rnp_ffi_t ffi,
rnp_key_handle_t primary,
const char * alg);
/** Set bits of the generated key or subkey.
* Note: this is applicable only to rsa, dsa and el-gamal keys.
*
* @param op pointer to opaque key generation context.
* @param bits number of bits
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_op_generate_set_bits(rnp_op_generate_t op, uint32_t bits);
/** Set hash algorithm used in self signature or subkey binding signature.
*
* @param op pointer to opaque key generation context.
* @param hash string with hash algorithm name. Following hash algorithms are supported:
* "MD5", "SHA1", "RIPEMD160", "SHA256", "SHA384", "SHA512", "SHA224", "SM3"