summaryrefslogtreecommitdiffstats
path: root/src/lib/ffi-priv-types.h
blob: beb624c9bab57886642ee48358e4593929d102d3 (plain)
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
/*-
 * Copyright (c) 2019 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.h>
#include <json.h>
#include "utils.h"
#include <list>
#include <crypto/mem.h>
#include "sec_profile.hpp"

struct rnp_key_handle_st {
    rnp_ffi_t        ffi;
    pgp_key_search_t locator;
    pgp_key_t *      pub;
    pgp_key_t *      sec;
};

struct rnp_uid_handle_st {
    rnp_ffi_t  ffi;
    pgp_key_t *key;
    size_t     idx;
};

struct rnp_signature_handle_st {
    rnp_ffi_t        ffi;
    const pgp_key_t *key;
    pgp_subsig_t *   sig;
    bool             own_sig;
};

struct rnp_recipient_handle_st {
    rnp_ffi_t        ffi;
    uint8_t          keyid[PGP_KEY_ID_SIZE];
    pgp_pubkey_alg_t palg;
};

struct rnp_symenc_handle_st {
    rnp_ffi_t           ffi;
    pgp_symm_alg_t      alg;
    pgp_hash_alg_t      halg;
    pgp_s2k_specifier_t s2k_type;
    uint32_t            iterations;
    pgp_aead_alg_t      aalg;
};

struct rnp_ffi_st {
    FILE *                  errs;
    rnp_key_store_t *       pubring;
    rnp_key_store_t *       secring;
    rnp_get_key_cb          getkeycb;
    void *                  getkeycb_ctx;
    rnp_password_cb         getpasscb;
    void *                  getpasscb_ctx;
    pgp_key_provider_t      key_provider;
    pgp_password_provider_t pass_provider;
    rnp::SecurityContext    context;

    rnp_ffi_st(pgp_key_store_format_t pub_fmt, pgp_key_store_format_t sec_fmt);
    ~rnp_ffi_st();

    rnp::RNG &            rng() noexcept;
    rnp::SecurityProfile &profile() noexcept;
};

struct rnp_input_st {
    /* either src or src_directory are valid, not both */
    pgp_source_t        src;
    std::string         src_directory;
    rnp_input_reader_t *reader;
    rnp_input_closer_t *closer;
    void *              app_ctx;

    rnp_input_st();
    rnp_input_st(const rnp_input_st &) = delete;
    rnp_input_st(rnp_input_st &&) = delete;
    ~rnp_input_st();

    rnp_input_st &operator=(const rnp_input_st &) = delete;
    rnp_input_st &operator=(rnp_input_st &&src);
};

struct rnp_output_st {
    /* either dst or dst_directory are valid, not both */
    pgp_dest_t           dst;
    char *               dst_directory;
    rnp_output_writer_t *writer;
    rnp_output_closer_t *closer;
    void *               app_ctx;
    bool                 keep;
};

struct rnp_op_generate_st {
    rnp_ffi_t  ffi{};
    bool       primary{};
    pgp_key_t *primary_sec{};
    pgp_key_t *primary_pub{};
    pgp_key_t *gen_sec{};
    pgp_key_t *gen_pub{};
    /* password used to encrypt the key, if specified */
    rnp::secure_vector<char> password;
    /* request password for key encryption via ffi's password provider */
    bool request_password{};
    /* we don't use top-level keygen action here for easier fields access */
    rnp_keygen_crypto_params_t  crypto{};
    rnp_key_protection_params_t protection{};
    rnp_selfsig_cert_info_t     cert{};
    rnp_selfsig_binding_info_t  binding{};
};

struct rnp_op_sign_signature_st {
    rnp_ffi_t         ffi{};
    rnp_signer_info_t signer{};
    bool              expiry_set : 1;
    bool              create_set : 1;
    bool              hash_set : 1;
};

typedef std::list<rnp_op_sign_signature_st> rnp_op_sign_signatures_t;

struct rnp_op_sign_st {
    rnp_ffi_t                ffi{};
    rnp_input_t              input{};
    rnp_output_t             output{};
    rnp_ctx_t                rnpctx{};
    rnp_op_sign_signatures_t signatures{};
};

struct rnp_op_verify_signature_st {
    rnp_ffi_t       ffi;
    rnp_result_t    verify_status;
    pgp_signature_t sig_pkt;
};

struct rnp_op_verify_st {
    rnp_ffi_t    ffi{};
    rnp_input_t  input{};
    rnp_input_t  detached_input{}; /* for detached signature will be source file/data */
    rnp_output_t output{};
    rnp_ctx_t    rnpctx{};
    /* these fields are filled after operation execution */
    rnp_op_verify_signature_t signatures{};
    size_t                    signature_count{};
    char *                    filename{};
    uint32_t                  file_mtime{};
    /* encryption information */
    bool           encrypted{};
    bool           mdc{};
    bool           validated{};
    pgp_aead_alg_t aead{};
    pgp_symm_alg_t salg{};
    bool           ignore_sigs{};
    bool           require_all_sigs{};
    bool           allow_hidden{};
    /* recipient/symenc information */
    rnp_recipient_handle_t recipients{};
    size_t                 recipient_count{};
    rnp_recipient_handle_t used_recipient{};
    rnp_symenc_handle_t    symencs{};
    size_t                 symenc_count{};
    rnp_symenc_handle_t    used_symenc{};
    size_t                 encrypted_layers{};

    ~rnp_op_verify_st();
};

struct rnp_op_encrypt_st {
    rnp_ffi_t                ffi{};
    rnp_input_t              input{};
    rnp_output_t             output{};
    rnp_ctx_t                rnpctx{};
    rnp_op_sign_signatures_t signatures{};
};

#define RNP_LOCATOR_MAX_SIZE (MAX_ID_LENGTH + 1)
static_assert(RNP_LOCATOR_MAX_SIZE > PGP_FINGERPRINT_SIZE * 2, "Locator size mismatch.");
static_assert(RNP_LOCATOR_MAX_SIZE > PGP_KEY_ID_SIZE * 2, "Locator size mismatch.");
static_assert(RNP_LOCATOR_MAX_SIZE > PGP_KEY_GRIP_SIZE * 2, "Locator size mismatch.");
static_assert(RNP_LOCATOR_MAX_SIZE > MAX_ID_LENGTH, "Locator size mismatch.");

struct rnp_identifier_iterator_st {
    rnp_ffi_t                       ffi;
    pgp_key_search_type_t           type;
    rnp_key_store_t *               store;
    std::list<pgp_key_t>::iterator *keyp;
    unsigned                        uididx;
    json_object *                   tbl;
    char                            buf[RNP_LOCATOR_MAX_SIZE];
};

struct rnp_decryption_kp_param_t {
    rnp_op_verify_t op;
    bool            has_hidden; /* key provider had hidden keyid request */
    pgp_key_t *     last;       /* last key, returned in hidden keyid request */

    rnp_decryption_kp_param_t(rnp_op_verify_t opobj)
        : op(opobj), has_hidden(false), last(NULL){};
};

/* This is just for readability at the call site and will hopefully reduce mistakes.
 *
 * Instead of:
 *  void do_something(rnp_ffi_t ffi, bool with_secret_keys);
 *  do_something(ffi, true);
 *  do_something(ffi, false);
 *
 * You can have something a bit clearer:
 *  void do_something(rnp_ffi_t ffi, key_type_t key_type);
 *  do_something(ffi, KEY_TYPE_PUBLIC);
 *  do_something(ffi, KEY_TYPE_SECRET);
 */
typedef enum key_type_t {
    KEY_TYPE_NONE,
    KEY_TYPE_PUBLIC,
    KEY_TYPE_SECRET,
    KEY_TYPE_ANY
} key_type_t;