summaryrefslogtreecommitdiffstats
path: root/src/lib/types.h
blob: 5a67d4225c062a3fec05e2bfe69a3c10ff4a0e6e (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
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
/*
 * Copyright (c) 2017-2021, [Ribose Inc](https://www.ribose.com).
 * Copyright (c) 2009 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is originally derived from software contributed to
 * The NetBSD Foundation by Alistair Crooks (agc@netbsd.org), and
 * carried further by Ribose Inc (https://www.ribose.com).
 *
 * 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.
 */
/*
 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
 * All rights reserved.
 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
 * their moral rights under the UK Copyright Design and Patents Act 1988 to
 * be recorded as the authors of this copyright work.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef TYPES_H_
#define TYPES_H_

#include <stdint.h>
#include <string>
#include <vector>
#include <array>
#include <cstring>
#include <type_traits>

#include <rnp/rnp_def.h>
#include "crypto/common.h"
#include "sec_profile.hpp"

/* SHA1 Hash Size */
#define PGP_SHA1_HASH_SIZE 20

/* Maximum length of the packet header */
#define PGP_MAX_HEADER_SIZE 6

/* Maximum supported userid length */
#define MAX_ID_LENGTH 128

/* Maximum supported password length */
#define MAX_PASSWORD_LENGTH 256

class id_str_pair {
  public:
    int         id;
    const char *str;

    /**
     * @brief Lookup constant pair array for the specified id or string value.
     *        Note: array must be finished with NULL string to stop the lookup.
     *
     * @param pair pointer to the const array with pairs.
     * @param id identifier to search for
     * @param notfound value to return if identifier is not found.
     * @return string, representing the identifier.
     */
    static const char *lookup(const id_str_pair pair[],
                              int               id,
                              const char *      notfound = "unknown");
    static int         lookup(const id_str_pair pair[], const char *str, int notfound = 0);
    static int         lookup(const id_str_pair           pair[],
                              const std::vector<uint8_t> &bytes,
                              int                         notfound = 0);
    static int         lookup(const id_str_pair                 pair[],
                              const std::basic_string<uint8_t> &bytes,
                              int                               notfound = 0);
};

/** pgp_fingerprint_t */
typedef struct pgp_fingerprint_t {
    uint8_t  fingerprint[PGP_FINGERPRINT_SIZE];
    unsigned length;
    bool     operator==(const pgp_fingerprint_t &src) const;
    bool     operator!=(const pgp_fingerprint_t &src) const;
} pgp_fingerprint_t;

typedef std::array<uint8_t, PGP_KEY_GRIP_SIZE> pgp_sig_id_t;

namespace std {
template <> struct hash<pgp_fingerprint_t> {
    std::size_t
    operator()(pgp_fingerprint_t const &fp) const noexcept
    {
        /* since fingerprint value is hash itself, we may use its low bytes */
        size_t res = 0;
        static_assert(sizeof(fp.fingerprint) == PGP_FINGERPRINT_SIZE,
                      "pgp_fingerprint_t size mismatch");
        static_assert(PGP_FINGERPRINT_SIZE >= sizeof(res), "pgp_fingerprint_t size mismatch");
        std::memcpy(&res, fp.fingerprint, sizeof(res));
        return res;
    }
};

template <> struct hash<pgp_sig_id_t> {
    std::size_t
    operator()(pgp_sig_id_t const &sigid) const noexcept
    {
        /* since signature id value is hash itself, we may use its low bytes */
        size_t res = 0;
        static_assert(std::tuple_size<pgp_sig_id_t>::value >= sizeof(res),
                      "pgp_sig_id_t size mismatch");
        std::memcpy(&res, sigid.data(), sizeof(res));
        return res;
    }
};
}; // namespace std

typedef std::array<uint8_t, PGP_KEY_GRIP_SIZE> pgp_key_grip_t;

typedef std::array<uint8_t, PGP_KEY_ID_SIZE> pgp_key_id_t;

namespace rnp {
class rnp_exception : public std::exception {
    rnp_result_t code_;

  public:
    rnp_exception(rnp_result_t code = RNP_ERROR_GENERIC) : code_(code){};
    virtual const char *
    what() const throw()
    {
        return "rnp_exception";
    };
    rnp_result_t
    code() const
    {
        return code_;
    };
};
} // namespace rnp

/* validity information for the signature/key/userid */
typedef struct pgp_validity_t {
    bool validated{}; /* item was validated */
    bool valid{};     /* item is valid by signature/key checks and calculations.
                         Still may be revoked or expired. */
    bool expired{};   /* item is expired */

    void mark_valid();
    void reset();
} pgp_validity_t;

/**
 * Type to keep public/secret key mpis without any openpgp-dependent data.
 */
typedef struct pgp_key_material_t {
    pgp_pubkey_alg_t alg;      /* algorithm of the key */
    bool             secret;   /* secret part of the key material is populated */
    pgp_validity_t   validity; /* key material validation status */

    union {
        pgp_rsa_key_t rsa;
        pgp_dsa_key_t dsa;
        pgp_eg_key_t  eg;
        pgp_ec_key_t  ec;
    };

    size_t bits() const;
    size_t qbits() const;
    void   validate(rnp::SecurityContext &ctx, bool reset = true);
    bool   valid() const;
} pgp_key_material_t;

/**
 * Type to keep signature without any openpgp-dependent data.
 */
typedef struct pgp_signature_material_t {
    union {
        pgp_rsa_signature_t rsa;
        pgp_dsa_signature_t dsa;
        pgp_ec_signature_t  ecc;
        pgp_eg_signature_t  eg;
    };
} pgp_signature_material_t;

/**
 * Type to keep pk-encrypted data without any openpgp-dependent data.
 */
typedef struct pgp_encrypted_material_t {
    union {
        pgp_rsa_encrypted_t  rsa;
        pgp_eg_encrypted_t   eg;
        pgp_sm2_encrypted_t  sm2;
        pgp_ecdh_encrypted_t ecdh;
    };
} pgp_encrypted_material_t;

typedef struct pgp_s2k_t {
    pgp_s2k_usage_t usage{};

    /* below fields may not all be valid, depending on the usage field above */
    pgp_s2k_specifier_t specifier{};
    pgp_hash_alg_t      hash_alg{};
    uint8_t             salt[PGP_SALT_SIZE];
    unsigned            iterations{};
    /* GnuPG custom s2k data */
    pgp_s2k_gpg_extension_t gpg_ext_num{};
    uint8_t                 gpg_serial_len{};
    uint8_t                 gpg_serial[16];
    /* Experimental s2k data */
    std::vector<uint8_t> experimental{};
} pgp_s2k_t;

typedef struct pgp_key_protection_t {
    pgp_s2k_t         s2k{};         /* string-to-key kdf params */
    pgp_symm_alg_t    symm_alg{};    /* symmetric alg */
    pgp_cipher_mode_t cipher_mode{}; /* block cipher mode */
    uint8_t           iv[PGP_MAX_BLOCK_SIZE];
} pgp_key_protection_t;

typedef struct pgp_key_pkt_t    pgp_key_pkt_t;
typedef struct pgp_userid_pkt_t pgp_userid_pkt_t;
typedef struct pgp_signature_t  pgp_signature_t;

/* Signature subpacket, see 5.2.3.1 in RFC 4880 and RFC 4880 bis 02 */
typedef struct pgp_sig_subpkt_t {
    pgp_sig_subpacket_type_t type;         /* type of the subpacket */
    size_t                   len;          /* length of the data */
    uint8_t *                data;         /* raw subpacket data, excluding the header */
    bool                     critical : 1; /* critical flag */
    bool                     hashed : 1;   /* whether subpacket is hashed or not */
    bool                     parsed : 1;   /* whether subpacket was successfully parsed */
    union {
        uint32_t create; /* 5.2.3.4.   Signature Creation Time */
        uint32_t expiry; /* 5.2.3.6.   Key Expiration Time */
                         /* 5.2.3.10.  Signature Expiration Time */
        bool exportable; /* 5.2.3.11.  Exportable Certification */
        struct {
            uint8_t level;
            uint8_t amount;
        } trust; /* 5.2.3.13.  Trust Signature */
        struct {
            const char *str;
            unsigned    len;
        } regexp;       /* 5.2.3.14.  Regular Expression */
        bool revocable; /* 5.2.3.12.  Revocable */
        struct {
            uint8_t *arr;
            unsigned len;
        } preferred; /* 5.2.3.7.  Preferred Symmetric Algorithms */
                     /* 5.2.3.8.  Preferred Hash Algorithms */
                     /* 5.2.3.9.  Preferred Compression Algorithms */
        struct {
            uint8_t          klass;
            pgp_pubkey_alg_t pkalg;
            uint8_t *        fp;
        } revocation_key; /* 5.2.3.15.  Revocation Key */
        uint8_t *issuer;  /* 5.2.3.5.   Issuer */
        struct {
            uint8_t        flags[4];
            unsigned       nlen;
            unsigned       vlen;
            bool           human;
            const uint8_t *name;
            const uint8_t *value;
        } notation; /* 5.2.3.16.  Notation Data */
        struct {
            bool no_modify;
        } ks_prefs; /* 5.2.3.17.  Key Server Preferences */
        struct {
            const char *uri;
            unsigned    len;
        } preferred_ks;   /* 5.2.3.18.  Preferred Key Server */
        bool primary_uid; /* 5.2.3.19.  Primary User ID */
        struct {
            const char *uri;
            unsigned    len;
        } policy;          /* 5.2.3.20.  Policy URI */
        uint8_t key_flags; /* 5.2.3.21.  Key Flags */
        struct {
            const char *uid;
            unsigned    len;
        } signer; /* 5.2.3.22.  Signer's User ID */
        struct {
            pgp_revocation_type_t code;
            const char *          str;
            unsigned              len;
        } revocation_reason; /* 5.2.3.23.  Reason for Revocation */
        uint8_t features;    /* 5.2.3.24.  Features */
        struct {
            pgp_pubkey_alg_t pkalg;
            pgp_hash_alg_t   halg;
            uint8_t *        hash;
            unsigned         hlen;
        } sig_target;         /* 5.2.3.25.  Signature Target */
        pgp_signature_t *sig; /* 5.2.3.27. Embedded Signature */
        struct {
            uint8_t  version;
            uint8_t *fp;
            unsigned len;
        } issuer_fp; /* 5.2.3.28.  Issuer Fingerprint, RFC 4880 bis 04 */
    } fields;        /* parsed contents of the subpacket */

    pgp_sig_subpkt_t()
        : type(PGP_SIG_SUBPKT_UNKNOWN), len(0), data(NULL), critical(false), hashed(false),
          parsed(false), fields({}){};
    pgp_sig_subpkt_t(const pgp_sig_subpkt_t &src);
    pgp_sig_subpkt_t(pgp_sig_subpkt_t &&src);
    pgp_sig_subpkt_t &operator=(pgp_sig_subpkt_t &&src);
    pgp_sig_subpkt_t &operator=(const pgp_sig_subpkt_t &src);
    ~pgp_sig_subpkt_t();
    bool parse();
} pgp_sig_subpkt_t;

typedef struct pgp_one_pass_sig_t pgp_one_pass_sig_t;

typedef enum {
    /* first octet */
    PGP_KEY_SERVER_NO_MODIFY = 0x80
} pgp_key_server_prefs_t;

typedef struct pgp_literal_hdr_t {
    uint8_t  format;
    char     fname[256];
    uint8_t  fname_len;
    uint32_t timestamp;
} pgp_literal_hdr_t;

typedef struct pgp_aead_hdr_t {
    int            version{};                  /* version of the AEAD packet */
    pgp_symm_alg_t ealg;                       /* underlying symmetric algorithm */
    pgp_aead_alg_t aalg;                       /* AEAD algorithm, i.e. EAX, OCB, etc */
    int            csize{};                    /* chunk size bits */
    uint8_t        iv[PGP_AEAD_MAX_NONCE_LEN]; /* initial vector for the message */
    size_t         ivlen{};                    /* iv length */

    pgp_aead_hdr_t() : ealg(PGP_SA_UNKNOWN), aalg(PGP_AEAD_NONE)
    {
    }
} pgp_aead_hdr_t;

/** litdata_type_t */
typedef enum {
    PGP_LDT_BINARY = 'b',
    PGP_LDT_TEXT = 't',
    PGP_LDT_UTF8 = 'u',
    PGP_LDT_LOCAL = 'l',
    PGP_LDT_LOCAL2 = '1'
} pgp_litdata_enum;

/* user revocation info */
typedef struct pgp_subsig_t pgp_subsig_t;

typedef struct pgp_revoke_t {
    uint32_t              uid{};   /* index in uid array */
    pgp_revocation_type_t code{};  /* revocation code */
    std::string           reason;  /* revocation reason */
    pgp_sig_id_t          sigid{}; /* id of the corresponding subsig */

    pgp_revoke_t() = default;
    pgp_revoke_t(pgp_subsig_t &sig);
} pgp_revoke_t;

typedef struct pgp_user_prefs_t {
    // preferred symmetric algs (pgp_symm_alg_t)
    std::vector<uint8_t> symm_algs{};
    // preferred hash algs (pgp_hash_alg_t)
    std::vector<uint8_t> hash_algs{};
    // preferred compression algs (pgp_compression_type_t)
    std::vector<uint8_t> z_algs{};
    // key server preferences (pgp_key_server_prefs_t)
    std::vector<uint8_t> ks_prefs{};
    // preferred key server
    std::string key_server{};

    void set_symm_algs(const std::vector<uint8_t> &algs);
    void add_symm_alg(pgp_symm_alg_t alg);
    void set_hash_algs(const std::vector<uint8_t> &algs);
    void add_hash_alg(pgp_hash_alg_t alg);
    void set_z_algs(const std::vector<uint8_t> &algs);
    void add_z_alg(pgp_compression_type_t alg);
    void set_ks_prefs(const std::vector<uint8_t> &prefs);
    void add_ks_pref(pgp_key_server_prefs_t pref);
} pgp_user_prefs_t;

struct rnp_keygen_ecc_params_t {
    pgp_curve_t curve;
};

struct rnp_keygen_rsa_params_t {
    uint32_t modulus_bit_len;
};

struct rnp_keygen_dsa_params_t {
    size_t p_bitlen;
    size_t q_bitlen;
};

struct rnp_keygen_elgamal_params_t {
    size_t key_bitlen;
};

/* structure used to hold context of key generation */
namespace rnp {
class SecurityContext;
}

typedef struct rnp_keygen_crypto_params_t {
    // Asymmteric algorithm that user requesed key for
    pgp_pubkey_alg_t key_alg;
    // Hash to be used for key signature
    pgp_hash_alg_t hash_alg;
    // Pointer to security context
    rnp::SecurityContext *ctx;
    union {
        struct rnp_keygen_ecc_params_t     ecc;
        struct rnp_keygen_rsa_params_t     rsa;
        struct rnp_keygen_dsa_params_t     dsa;
        struct rnp_keygen_elgamal_params_t elgamal;
    };
} rnp_keygen_crypto_params_t;

typedef struct rnp_selfsig_cert_info_t {
    std::string      userid;           /* userid, required */
    uint8_t          key_flags{};      /* key flags */
    uint32_t         key_expiration{}; /* key expiration time (sec), 0 = no expiration */
    pgp_user_prefs_t prefs{};          /* user preferences, optional */
    bool             primary;          /* mark this as the primary user id */

    /**
     * @brief Populate uid and sig packet with data stored in this struct.
     *        At some point we should get rid of it.
     */
    void populate(pgp_userid_pkt_t &uid, pgp_signature_t &sig);
} rnp_selfsig_cert_info_t;

typedef struct rnp_selfsig_binding_info_t {
    uint8_t  key_flags;
    uint32_t key_expiration;
} rnp_selfsig_binding_info_t;

typedef struct rnp_keygen_primary_desc_t {
    rnp_keygen_crypto_params_t crypto{};
    rnp_selfsig_cert_info_t    cert{};
} rnp_keygen_primary_desc_t;

typedef struct rnp_keygen_subkey_desc_t {
    rnp_keygen_crypto_params_t crypto;
    rnp_selfsig_binding_info_t binding;
} rnp_keygen_subkey_desc_t;

typedef struct rnp_key_protection_params_t {
    pgp_symm_alg_t    symm_alg;
    pgp_cipher_mode_t cipher_mode;
    unsigned          iterations;
    pgp_hash_alg_t    hash_alg;
} rnp_key_protection_params_t;

#endif /* TYPES_H_ */