Coverage Report

Created: 2026-04-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rnp/src/librepgp/stream-packet.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2017-2020,2023 [Ribose Inc](https://www.ribose.com).
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without modification,
6
 * are permitted provided that the following conditions are met:
7
 *
8
 * 1.  Redistributions of source code must retain the above copyright notice,
9
 *     this list of conditions and the following disclaimer.
10
 *
11
 * 2.  Redistributions in binary form must reproduce the above copyright notice,
12
 *     this list of conditions and the following disclaimer in the documentation
13
 *     and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#include "config.h"
28
#include <sys/stat.h>
29
#include <stdlib.h>
30
#include <stdio.h>
31
#ifdef HAVE_UNISTD_H
32
#include <unistd.h>
33
#else
34
#include "uniwin.h"
35
#endif
36
#include <string.h>
37
#ifndef __STDC_FORMAT_MACROS
38
#define __STDC_FORMAT_MACROS
39
#endif
40
#include <cinttypes>
41
#include <rnp/rnp_def.h>
42
#include "types.h"
43
#include "crypto/mem.h"
44
#include "stream-packet.h"
45
#include "stream-key.h"
46
#include <algorithm>
47
48
size_t
49
write_packet_len(uint8_t *buf, size_t len)
50
0
{
51
0
    if (len < 192) {
52
0
        buf[0] = len;
53
0
        return 1;
54
0
    } else if (len < 8192 + 192) {
55
0
        buf[0] = ((len - 192) >> 8) + 192;
56
0
        buf[1] = (len - 192) & 0xff;
57
0
        return 2;
58
0
    } else {
59
0
        buf[0] = 0xff;
60
0
        write_uint32(&buf[1], len);
61
0
        return 5;
62
0
    }
63
0
}
64
65
int
66
get_packet_type(uint8_t ptag)
67
0
{
68
0
    if (!(ptag & PGP_PTAG_ALWAYS_SET)) {
69
0
        return -1;
70
0
    }
71
72
0
    if (ptag & PGP_PTAG_NEW_FORMAT) {
73
0
        return (int) (ptag & PGP_PTAG_NF_CONTENT_TAG_MASK);
74
0
    } else {
75
0
        return (int) ((ptag & PGP_PTAG_OF_CONTENT_TAG_MASK) >> PGP_PTAG_OF_CONTENT_TAG_SHIFT);
76
0
    }
77
0
}
78
79
int
80
stream_pkt_type(pgp_source_t &src)
81
0
{
82
0
    if (src.eof()) {
83
0
        return 0;
84
0
    }
85
0
    size_t hdrneed = 0;
86
0
    if (!stream_pkt_hdr_len(src, hdrneed)) {
87
0
        return -1;
88
0
    }
89
0
    uint8_t hdr[PGP_MAX_HEADER_SIZE];
90
0
    if (!src.peek_eq(hdr, hdrneed)) {
91
0
        return -1;
92
0
    }
93
0
    return get_packet_type(hdr[0]);
94
0
}
95
96
bool
97
stream_pkt_hdr_len(pgp_source_t &src, size_t &hdrlen)
98
0
{
99
0
    uint8_t buf[2];
100
101
0
    if (!src.peek_eq(buf, 2) || !(buf[0] & PGP_PTAG_ALWAYS_SET)) {
102
0
        return false;
103
0
    }
104
105
0
    if (buf[0] & PGP_PTAG_NEW_FORMAT) {
106
0
        if (buf[1] < 192) {
107
0
            hdrlen = 2;
108
0
        } else if (buf[1] < 224) {
109
0
            hdrlen = 3;
110
0
        } else if (buf[1] < 255) {
111
0
            hdrlen = 2;
112
0
        } else {
113
0
            hdrlen = 6;
114
0
        }
115
0
        return true;
116
0
    }
117
118
0
    switch (buf[0] & PGP_PTAG_OF_LENGTH_TYPE_MASK) {
119
0
    case PGP_PTAG_OLD_LEN_1:
120
0
        hdrlen = 2;
121
0
        return true;
122
0
    case PGP_PTAG_OLD_LEN_2:
123
0
        hdrlen = 3;
124
0
        return true;
125
0
    case PGP_PTAG_OLD_LEN_4:
126
0
        hdrlen = 5;
127
0
        return true;
128
0
    case PGP_PTAG_OLD_LEN_INDETERMINATE:
129
0
        hdrlen = 1;
130
0
        return true;
131
0
    default:
132
0
        return false;
133
0
    }
134
0
}
135
136
static bool
137
get_pkt_len(uint8_t *hdr, size_t *pktlen)
138
0
{
139
0
    if (hdr[0] & PGP_PTAG_NEW_FORMAT) {
140
        // 1-byte length
141
0
        if (hdr[1] < 192) {
142
0
            *pktlen = hdr[1];
143
0
            return true;
144
0
        }
145
        // 2-byte length
146
0
        if (hdr[1] < 224) {
147
0
            *pktlen = ((size_t)(hdr[1] - 192) << 8) + (size_t) hdr[2] + 192;
148
0
            return true;
149
0
        }
150
        // partial length - we do not allow it here
151
0
        if (hdr[1] < 255) {
152
0
            return false;
153
0
        }
154
        // 4-byte length
155
0
        *pktlen = read_uint32(&hdr[2]);
156
0
        return true;
157
0
    }
158
159
0
    switch (hdr[0] & PGP_PTAG_OF_LENGTH_TYPE_MASK) {
160
0
    case PGP_PTAG_OLD_LEN_1:
161
0
        *pktlen = hdr[1];
162
0
        return true;
163
0
    case PGP_PTAG_OLD_LEN_2:
164
0
        *pktlen = read_uint16(&hdr[1]);
165
0
        return true;
166
0
    case PGP_PTAG_OLD_LEN_4:
167
0
        *pktlen = read_uint32(&hdr[1]);
168
0
        return true;
169
0
    default:
170
0
        return false;
171
0
    }
172
0
}
173
174
bool
175
stream_read_pkt_len(pgp_source_t &src, size_t *pktlen)
176
0
{
177
0
    uint8_t buf[6] = {};
178
0
    size_t  read = 0;
179
180
0
    if (!stream_pkt_hdr_len(src, read)) {
181
0
        return false;
182
0
    }
183
184
0
    if (!src.read_eq(buf, read)) {
185
0
        return false;
186
0
    }
187
188
0
    return get_pkt_len(buf, pktlen);
189
0
}
190
191
bool
192
stream_read_partial_chunk_len(pgp_source_t *src, size_t *clen, bool *last)
193
0
{
194
0
    uint8_t hdr[5] = {};
195
0
    size_t  read = 0;
196
197
0
    if (!src->read(hdr, 1, &read)) {
198
0
        RNP_LOG("failed to read header");
199
0
        return false;
200
0
    }
201
0
    if (read < 1) {
202
0
        RNP_LOG("wrong eof");
203
0
        return false;
204
0
    }
205
206
0
    *last = true;
207
    // partial length
208
0
    if ((hdr[0] >= 224) && (hdr[0] < 255)) {
209
0
        *last = false;
210
0
        *clen = get_partial_pkt_len(hdr[0]);
211
0
        return true;
212
0
    }
213
    // 1-byte length
214
0
    if (hdr[0] < 192) {
215
0
        *clen = hdr[0];
216
0
        return true;
217
0
    }
218
    // 2-byte length
219
0
    if (hdr[0] < 224) {
220
0
        if (!src->read_eq(&hdr[1], 1)) {
221
0
            RNP_LOG("wrong 2-byte length");
222
0
            return false;
223
0
        }
224
0
        *clen = ((size_t)(hdr[0] - 192) << 8) + (size_t) hdr[1] + 192;
225
0
        return true;
226
0
    }
227
    // 4-byte length
228
0
    if (!src->read_eq(&hdr[1], 4)) {
229
0
        RNP_LOG("wrong 4-byte length");
230
0
        return false;
231
0
    }
232
0
    *clen = ((size_t) hdr[1] << 24) | ((size_t) hdr[2] << 16) | ((size_t) hdr[3] << 8) |
233
0
            (size_t) hdr[4];
234
0
    return true;
235
0
}
236
237
bool
238
stream_old_indeterminate_pkt_len(pgp_source_t *src)
239
0
{
240
0
    uint8_t ptag = 0;
241
0
    if (!src->peek_eq(&ptag, 1)) {
242
0
        return false;
243
0
    }
244
0
    return !(ptag & PGP_PTAG_NEW_FORMAT) &&
245
0
           ((ptag & PGP_PTAG_OF_LENGTH_TYPE_MASK) == PGP_PTAG_OLD_LEN_INDETERMINATE);
246
0
}
247
248
bool
249
stream_partial_pkt_len(pgp_source_t *src)
250
0
{
251
0
    uint8_t hdr[2] = {};
252
0
    if (!src->peek_eq(hdr, 2)) {
253
0
        return false;
254
0
    }
255
0
    return (hdr[0] & PGP_PTAG_NEW_FORMAT) && (hdr[1] >= 224) && (hdr[1] < 255);
256
0
}
257
258
size_t
259
get_partial_pkt_len(uint8_t blen)
260
0
{
261
0
    return 1 << (blen & 0x1f);
262
0
}
263
264
rnp_result_t
265
stream_peek_packet_hdr(pgp_source_t *src, pgp_packet_hdr_t *hdr)
266
0
{
267
0
    size_t hlen = 0;
268
0
    memset(hdr, 0, sizeof(*hdr));
269
0
    if (!stream_pkt_hdr_len(*src, hlen)) {
270
0
        uint8_t hdr2[2] = {0};
271
0
        if (!src->peek_eq(hdr2, 2)) {
272
0
            RNP_LOG("pkt header read failed");
273
0
            return RNP_ERROR_READ;
274
0
        }
275
276
0
        RNP_LOG("bad packet header: 0x%02x%02x", hdr2[0], hdr2[1]);
277
0
        return RNP_ERROR_BAD_FORMAT;
278
0
    }
279
280
0
    if (!src->peek_eq(hdr->hdr, hlen)) {
281
0
        RNP_LOG("failed to read pkt header");
282
0
        return RNP_ERROR_READ;
283
0
    }
284
285
0
    hdr->hdr_len = hlen;
286
0
    hdr->tag = (pgp_pkt_type_t) get_packet_type(hdr->hdr[0]);
287
288
0
    if (stream_partial_pkt_len(src)) {
289
0
        hdr->partial = true;
290
0
    } else if (stream_old_indeterminate_pkt_len(src)) {
291
0
        hdr->indeterminate = true;
292
0
    } else {
293
0
        (void) get_pkt_len(hdr->hdr, &hdr->pkt_len);
294
0
    }
295
296
0
    return RNP_SUCCESS;
297
0
}
298
299
static rnp_result_t
300
stream_read_packet_partial(pgp_source_t *src, pgp_dest_t *dst)
301
0
{
302
0
    uint8_t hdr = 0;
303
0
    if (!src->read_eq(&hdr, 1)) {
304
0
        return RNP_ERROR_READ;
305
0
    }
306
307
0
    bool   last = false;
308
0
    size_t partlen = 0;
309
0
    if (!stream_read_partial_chunk_len(src, &partlen, &last)) {
310
0
        return RNP_ERROR_BAD_FORMAT;
311
0
    }
312
313
0
    uint8_t *buf = (uint8_t *) malloc(PGP_INPUT_CACHE_SIZE);
314
0
    if (!buf) {
315
0
        return RNP_ERROR_OUT_OF_MEMORY;
316
0
    }
317
318
0
    while (partlen > 0) {
319
0
        size_t read = std::min(partlen, (size_t) PGP_INPUT_CACHE_SIZE);
320
0
        if (!src->read_eq(buf, read)) {
321
0
            free(buf);
322
0
            return RNP_ERROR_READ;
323
0
        }
324
0
        if (dst) {
325
0
            dst_write(dst, buf, read);
326
0
        }
327
0
        partlen -= read;
328
0
        if (partlen > 0) {
329
0
            continue;
330
0
        }
331
0
        if (last) {
332
0
            break;
333
0
        }
334
0
        if (!stream_read_partial_chunk_len(src, &partlen, &last)) {
335
0
            free(buf);
336
0
            return RNP_ERROR_BAD_FORMAT;
337
0
        }
338
0
    }
339
0
    free(buf);
340
0
    return RNP_SUCCESS;
341
0
}
342
343
rnp_result_t
344
stream_read_packet(pgp_source_t *src, pgp_dest_t *dst)
345
0
{
346
0
    if (stream_old_indeterminate_pkt_len(src)) {
347
0
        return dst_write_src(src, dst, PGP_MAX_OLD_LEN_INDETERMINATE_PKT_SIZE);
348
0
    }
349
350
0
    if (stream_partial_pkt_len(src)) {
351
0
        return stream_read_packet_partial(src, dst);
352
0
    }
353
354
0
    try {
355
0
        pgp_packet_body_t body(PGP_PKT_RESERVED);
356
0
        rnp_result_t      ret = body.read(*src);
357
0
        if (dst) {
358
0
            body.write(*dst, false);
359
0
        }
360
0
        return ret;
361
0
    } catch (const std::exception &e) {
362
0
        RNP_LOG("%s", e.what());
363
0
        return RNP_ERROR_GENERIC;
364
0
    }
365
0
}
366
367
rnp_result_t
368
stream_skip_packet(pgp_source_t *src)
369
0
{
370
0
    return stream_read_packet(src, NULL);
371
0
}
372
373
rnp_result_t
374
stream_parse_marker(pgp_source_t &src)
375
0
{
376
0
    try {
377
0
        pgp_packet_body_t pkt(PGP_PKT_MARKER);
378
0
        rnp_result_t      res = pkt.read(src);
379
0
        if (res) {
380
0
            return res;
381
0
        }
382
0
        if ((pkt.size() != PGP_MARKER_LEN) ||
383
0
            memcmp(pkt.data(), PGP_MARKER_CONTENTS, PGP_MARKER_LEN)) {
384
0
            return RNP_ERROR_BAD_FORMAT;
385
0
        }
386
0
        return RNP_SUCCESS;
387
0
    } catch (const std::exception &e) {
388
0
        RNP_LOG("%s", e.what());
389
0
        return RNP_ERROR_OUT_OF_MEMORY;
390
0
    }
391
0
}
392
393
bool
394
is_key_pkt(int tag)
395
0
{
396
0
    switch (tag) {
397
0
    case PGP_PKT_PUBLIC_KEY:
398
0
    case PGP_PKT_PUBLIC_SUBKEY:
399
0
    case PGP_PKT_SECRET_KEY:
400
0
    case PGP_PKT_SECRET_SUBKEY:
401
0
        return true;
402
0
    default:
403
0
        return false;
404
0
    }
405
0
}
406
407
bool
408
is_subkey_pkt(int tag)
409
750
{
410
750
    return (tag == PGP_PKT_PUBLIC_SUBKEY) || (tag == PGP_PKT_SECRET_SUBKEY);
411
750
}
412
413
bool
414
is_primary_key_pkt(int tag)
415
150
{
416
150
    return (tag == PGP_PKT_PUBLIC_KEY) || (tag == PGP_PKT_SECRET_KEY);
417
150
}
418
419
bool
420
is_public_key_pkt(int tag)
421
0
{
422
0
    switch (tag) {
423
0
    case PGP_PKT_PUBLIC_KEY:
424
0
    case PGP_PKT_PUBLIC_SUBKEY:
425
0
        return true;
426
0
    default:
427
0
        return false;
428
0
    }
429
0
}
430
431
bool
432
is_secret_key_pkt(int tag)
433
0
{
434
0
    switch (tag) {
435
0
    case PGP_PKT_SECRET_KEY:
436
0
    case PGP_PKT_SECRET_SUBKEY:
437
0
        return true;
438
0
    default:
439
0
        return false;
440
0
    }
441
0
}
442
443
bool
444
is_rsa_key_alg(pgp_pubkey_alg_t alg)
445
0
{
446
0
    switch (alg) {
447
0
    case PGP_PKA_RSA:
448
0
    case PGP_PKA_RSA_ENCRYPT_ONLY:
449
0
    case PGP_PKA_RSA_SIGN_ONLY:
450
0
        return true;
451
0
    default:
452
0
        return false;
453
0
    }
454
0
}
455
456
pgp_packet_body_t::pgp_packet_body_t(pgp_pkt_type_t tag)
457
0
{
458
0
    data_.reserve(16);
459
0
    tag_ = tag;
460
0
    secure_ = is_secret_key_pkt(tag);
461
0
}
462
463
pgp_packet_body_t::pgp_packet_body_t(const uint8_t *data, size_t len)
464
0
{
465
0
    data_.assign(data, data + len);
466
0
    tag_ = PGP_PKT_RESERVED;
467
0
    secure_ = false;
468
0
}
469
470
pgp_packet_body_t::pgp_packet_body_t(const std::vector<uint8_t> &data)
471
0
    : pgp_packet_body_t(data.data(), data.size())
472
0
{
473
0
}
474
475
pgp_packet_body_t::~pgp_packet_body_t()
476
0
{
477
0
    if (secure_) {
478
0
        secure_clear(data_.data(), data_.size());
479
0
    }
480
0
}
481
482
uint8_t *
483
pgp_packet_body_t::data() noexcept
484
0
{
485
0
    return data_.data();
486
0
}
487
488
uint8_t *
489
pgp_packet_body_t::cur() noexcept
490
0
{
491
0
    return data_.data() + pos_;
492
0
}
493
494
size_t
495
pgp_packet_body_t::size() const noexcept
496
0
{
497
0
    return data_.size();
498
0
}
499
500
size_t
501
pgp_packet_body_t::left() const noexcept
502
0
{
503
0
    return data_.size() - pos_;
504
0
}
505
506
void
507
pgp_packet_body_t::skip(size_t bt) noexcept
508
0
{
509
0
    pos_ += bt;
510
0
}
511
512
void
513
pgp_packet_body_t::skip_back(size_t bt) noexcept
514
0
{
515
0
    pos_ = bt > pos_ ? 0 : pos_ - bt;
516
0
}
517
518
bool
519
pgp_packet_body_t::get(uint8_t &val) noexcept
520
0
{
521
0
    if (pos_ >= data_.size()) {
522
0
        return false;
523
0
    }
524
0
    val = data_[pos_++];
525
0
    return true;
526
0
}
527
528
bool
529
pgp_packet_body_t::get(uint16_t &val) noexcept
530
0
{
531
0
    if (pos_ + 2 > data_.size()) {
532
0
        return false;
533
0
    }
534
0
    val = read_uint16(data_.data() + pos_);
535
0
    pos_ += 2;
536
0
    return true;
537
0
}
538
539
bool
540
pgp_packet_body_t::get(uint32_t &val) noexcept
541
0
{
542
0
    if (pos_ + 4 > data_.size()) {
543
0
        return false;
544
0
    }
545
0
    val = read_uint32(data_.data() + pos_);
546
0
    pos_ += 4;
547
0
    return true;
548
0
}
549
550
bool
551
pgp_packet_body_t::get(uint8_t *val, size_t len) noexcept
552
0
{
553
0
    if (pos_ + len > data_.size()) {
554
0
        return false;
555
0
    }
556
0
    memcpy(val, data_.data() + pos_, len);
557
0
    pos_ += len;
558
0
    return true;
559
0
}
560
561
bool
562
pgp_packet_body_t::get(std::vector<uint8_t> &val, size_t len)
563
0
{
564
0
    if (pos_ + len > data_.size()) {
565
0
        return false;
566
0
    }
567
0
    val.assign(data_.data() + pos_, data_.data() + pos_ + len);
568
0
    pos_ += len;
569
0
    return true;
570
0
}
571
572
bool
573
pgp_packet_body_t::get(pgp::KeyID &val) noexcept
574
0
{
575
0
    static_assert(std::tuple_size<pgp::KeyID>::value == PGP_KEY_ID_SIZE,
576
0
                  "pgp::KeyID size mismatch");
577
0
    return get(val.data(), val.size());
578
0
}
579
580
bool
581
pgp_packet_body_t::get(pgp::mpi &val) noexcept
582
0
{
583
0
    uint16_t bits = 0;
584
0
    if (!get(bits)) {
585
0
        return false;
586
0
    }
587
0
    size_t len = (bits + 7) >> 3;
588
0
    if (len > PGP_MPINT_SIZE) {
589
0
        RNP_LOG("too large mpi");
590
0
        return false;
591
0
    }
592
0
    if (!len) {
593
0
        RNP_LOG("0 mpi");
594
0
        return false;
595
0
    }
596
0
    val.resize(len);
597
0
    if (!get(val.data(), len)) {
598
0
        RNP_LOG("failed to read mpi body");
599
0
        return false;
600
0
    }
601
    /* check the mpi bit count */
602
0
    size_t mbits = val.bits();
603
0
    if (mbits != bits) {
604
0
        RNP_LOG(
605
0
          "Warning! Wrong mpi bit count: got %" PRIu16 ", but actual is %zu", bits, mbits);
606
0
    }
607
0
    return true;
608
0
}
609
610
bool
611
pgp_packet_body_t::get(pgp_curve_t &val) noexcept
612
0
{
613
0
    uint8_t oidlen = 0;
614
0
    if (!get(oidlen)) {
615
0
        return false;
616
0
    }
617
0
    if (!oidlen || (oidlen == 0xff)) {
618
0
        RNP_LOG("unsupported curve oid len: %" PRIu8, oidlen);
619
0
        return false;
620
0
    }
621
0
    std::vector<uint8_t> oid(oidlen, 0);
622
0
    if (!get(oid, oidlen)) {
623
0
        return false;
624
0
    }
625
0
    pgp_curve_t res = pgp::ec::Curve::by_OID(oid);
626
0
    if (res == PGP_CURVE_MAX) {
627
0
        RNP_LOG("unsupported curve");
628
0
        return false;
629
0
    }
630
0
    val = res;
631
0
    return true;
632
0
}
633
634
bool
635
pgp_packet_body_t::get(pgp_s2k_t &s2k) noexcept
636
0
{
637
0
    uint8_t spec = 0, halg = 0;
638
0
    if (!get(spec) || !get(halg)) {
639
0
        return false;
640
0
    }
641
0
    s2k.specifier = (pgp_s2k_specifier_t) spec;
642
0
    s2k.hash_alg = (pgp_hash_alg_t) halg;
643
644
0
    switch (s2k.specifier) {
645
0
    case PGP_S2KS_SIMPLE:
646
0
        return true;
647
0
    case PGP_S2KS_SALTED:
648
0
        return get(s2k.salt, PGP_SALT_SIZE);
649
0
    case PGP_S2KS_ITERATED_AND_SALTED: {
650
0
        uint8_t iter = 0;
651
0
        if (!get(s2k.salt, PGP_SALT_SIZE) || !get(iter)) {
652
0
            return false;
653
0
        }
654
0
        s2k.iterations = iter;
655
0
        return true;
656
0
    }
657
0
    case PGP_S2KS_EXPERIMENTAL: {
658
0
        try {
659
0
            s2k.experimental = {data_.begin() + pos_, data_.end()};
660
0
        } catch (const std::exception &e) {
661
0
            RNP_LOG("%s", e.what());
662
0
            return false;
663
0
        }
664
0
        uint8_t gnu[3] = {0};
665
0
        if (!get(gnu, 3) || memcmp(gnu, "GNU", 3)) {
666
0
            RNP_LOG("Unknown experimental s2k. Skipping.");
667
0
            pos_ = data_.size();
668
0
            s2k.gpg_ext_num = PGP_S2K_GPG_NONE;
669
0
            return true;
670
0
        }
671
0
        uint8_t ext_num = 0;
672
0
        if (!get(ext_num)) {
673
0
            return false;
674
0
        }
675
0
        if ((ext_num != PGP_S2K_GPG_NO_SECRET) && (ext_num != PGP_S2K_GPG_SMARTCARD)) {
676
0
            RNP_LOG("Unsupported gpg extension num: %" PRIu8 ", skipping", ext_num);
677
0
            pos_ = data_.size();
678
0
            s2k.gpg_ext_num = PGP_S2K_GPG_NONE;
679
0
            return true;
680
0
        }
681
0
        s2k.gpg_ext_num = (pgp_s2k_gpg_extension_t) ext_num;
682
0
        if (s2k.gpg_ext_num == PGP_S2K_GPG_NO_SECRET) {
683
0
            return true;
684
0
        }
685
0
        if (!get(s2k.gpg_serial_len)) {
686
0
            RNP_LOG("Failed to get GPG serial len");
687
0
            return false;
688
0
        }
689
0
        size_t len = s2k.gpg_serial_len;
690
0
        if (s2k.gpg_serial_len > 16) {
691
0
            RNP_LOG("Warning: gpg_serial_len is %d", (int) len);
692
0
            len = 16;
693
0
        }
694
0
        if (!get(s2k.gpg_serial, len)) {
695
0
            RNP_LOG("Failed to get GPG serial");
696
0
            return false;
697
0
        }
698
0
        return true;
699
0
    }
700
0
    default:
701
0
        RNP_LOG("unknown s2k specifier: %d", (int) s2k.specifier);
702
0
        return false;
703
0
    }
704
0
}
705
706
void
707
pgp_packet_body_t::add(const void *data, size_t len)
708
0
{
709
0
    data_.insert(data_.end(), (uint8_t *) data, (uint8_t *) data + len);
710
0
}
711
712
void
713
pgp_packet_body_t::add(const std::vector<uint8_t> &data)
714
0
{
715
0
    add(data.data(), data.size());
716
0
}
717
718
void
719
pgp_packet_body_t::add_byte(uint8_t bt)
720
0
{
721
0
    data_.push_back(bt);
722
0
}
723
724
void
725
pgp_packet_body_t::add_uint16(uint16_t val)
726
0
{
727
0
    uint8_t bytes[2];
728
0
    write_uint16(bytes, val);
729
0
    add(bytes, 2);
730
0
}
731
732
void
733
pgp_packet_body_t::add_uint32(uint32_t val)
734
0
{
735
0
    uint8_t bytes[4];
736
0
    write_uint32(bytes, val);
737
0
    add(bytes, 4);
738
0
}
739
740
void
741
pgp_packet_body_t::add(const pgp::KeyID &val)
742
0
{
743
0
    add(val.data(), val.size());
744
0
}
745
746
void
747
pgp_packet_body_t::add(const pgp::mpi &val)
748
0
{
749
0
    if (!val.size()) {
750
0
        throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
751
0
    }
752
753
0
    size_t idx = 0;
754
0
    while ((idx < val.size() - 1) && (!val[idx])) {
755
0
        idx++;
756
0
    }
757
758
0
    size_t  bits = (val.size() - idx - 1) << 3;
759
0
    uint8_t hibyte = val[idx];
760
0
    while (hibyte) {
761
0
        bits++;
762
0
        hibyte = hibyte >> 1;
763
0
    }
764
765
0
    uint8_t hdr[2] = {(uint8_t)(bits >> 8), (uint8_t)(bits & 0xff)};
766
0
    add(hdr, 2);
767
0
    add(val.data() + idx, val.size() - idx);
768
0
}
769
770
void
771
pgp_packet_body_t::add_subpackets(const pgp::pkt::Signature &sig, bool hashed)
772
0
{
773
0
    pgp_packet_body_t spbody(PGP_PKT_RESERVED);
774
775
0
    for (auto &subpkt : sig.subpkts) {
776
0
        if (subpkt->hashed() != hashed) {
777
0
            continue;
778
0
        }
779
780
0
        uint8_t splen[6];
781
0
        size_t  lenlen = write_packet_len(splen, subpkt->data().size() + 1);
782
0
        spbody.add(splen, lenlen);
783
0
        spbody.add_byte(subpkt->raw_type() | (subpkt->critical() << 7));
784
0
        spbody.add(subpkt->data().data(), subpkt->data().size());
785
0
    }
786
787
0
    if (spbody.data_.size() > 0xffff) {
788
0
        throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
789
0
    }
790
0
    switch (sig.version) {
791
0
    case PGP_V4:
792
0
    case PGP_V5:
793
0
        add_uint16(spbody.data_.size());
794
0
        break;
795
0
#if defined(ENABLE_CRYPTO_REFRESH)
796
0
    case PGP_V6:
797
0
        add_uint32(spbody.data_.size());
798
0
        break;
799
0
#endif
800
0
    default:
801
0
        RNP_LOG("should not reach this code");
802
0
        throw rnp::rnp_exception(RNP_ERROR_BAD_STATE);
803
0
    }
804
0
    add(spbody.data_.data(), spbody.data_.size());
805
0
}
806
807
void
808
pgp_packet_body_t::add(const pgp_curve_t curve)
809
0
{
810
0
    auto desc = pgp::ec::Curve::get(curve);
811
0
    if (!desc) {
812
0
        throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
813
0
    }
814
0
    add_byte((uint8_t) desc->OID.size());
815
0
    add(desc->OID.data(), desc->OID.size());
816
0
}
817
818
void
819
pgp_packet_body_t::add(const pgp_s2k_t &s2k)
820
0
{
821
0
    add_byte(s2k.specifier);
822
0
    add_byte(s2k.hash_alg);
823
824
0
    switch (s2k.specifier) {
825
0
    case PGP_S2KS_SIMPLE:
826
0
        return;
827
0
    case PGP_S2KS_SALTED:
828
0
        add(s2k.salt, PGP_SALT_SIZE);
829
0
        return;
830
0
    case PGP_S2KS_ITERATED_AND_SALTED: {
831
0
        unsigned iter = s2k.iterations;
832
0
        if (iter > 255) {
833
0
            iter = pgp_s2k_encode_iterations(iter);
834
0
        }
835
0
        add(s2k.salt, PGP_SALT_SIZE);
836
0
        add_byte(iter);
837
0
        return;
838
0
    }
839
0
    case PGP_S2KS_EXPERIMENTAL: {
840
0
        if ((s2k.gpg_ext_num != PGP_S2K_GPG_NO_SECRET) &&
841
0
            (s2k.gpg_ext_num != PGP_S2K_GPG_SMARTCARD)) {
842
0
            RNP_LOG("Unknown experimental s2k.");
843
0
            add(s2k.experimental.data(), s2k.experimental.size());
844
0
            return;
845
0
        }
846
0
        add("GNU", 3);
847
0
        add_byte(s2k.gpg_ext_num);
848
0
        if (s2k.gpg_ext_num == PGP_S2K_GPG_SMARTCARD) {
849
0
            static_assert(sizeof(s2k.gpg_serial) == 16, "invalid gpg serial length");
850
0
            size_t slen = s2k.gpg_serial_len > 16 ? 16 : s2k.gpg_serial_len;
851
0
            add_byte(s2k.gpg_serial_len);
852
0
            add(s2k.gpg_serial, slen);
853
0
        }
854
0
        return;
855
0
    }
856
0
    default:
857
0
        RNP_LOG("unknown s2k specifier");
858
0
        throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
859
0
    }
860
0
}
861
862
rnp_result_t
863
pgp_packet_body_t::read(pgp_source_t &src) noexcept
864
0
{
865
    /* Make sure we have enough data for packet header */
866
0
    if (!src.peek_eq(hdr_, 2)) {
867
0
        return RNP_ERROR_READ;
868
0
    }
869
870
    /* Read the packet header and length */
871
0
    size_t len = 0;
872
0
    if (!stream_pkt_hdr_len(src, len)) {
873
0
        return RNP_ERROR_BAD_FORMAT;
874
0
    }
875
0
    if (!src.peek_eq(hdr_, len)) {
876
0
        return RNP_ERROR_READ;
877
0
    }
878
0
    hdr_len_ = len;
879
880
0
    int ptag = get_packet_type(hdr_[0]);
881
0
    if ((ptag < 0) || ((tag_ != PGP_PKT_RESERVED) && (tag_ != ptag))) {
882
0
        RNP_LOG("tag mismatch: %d vs %d", (int) tag_, ptag);
883
0
        return RNP_ERROR_BAD_FORMAT;
884
0
    }
885
0
    tag_ = (pgp_pkt_type_t) ptag;
886
887
0
    if (!stream_read_pkt_len(src, &len)) {
888
0
        return RNP_ERROR_READ;
889
0
    }
890
891
    /* early exit for the empty packet */
892
0
    if (!len) {
893
0
        return RNP_SUCCESS;
894
0
    }
895
896
0
    if (len > PGP_MAX_PKT_SIZE) {
897
0
        RNP_LOG("too large packet");
898
0
        return RNP_ERROR_BAD_FORMAT;
899
0
    }
900
901
    /* Read the packet contents */
902
0
    try {
903
0
        data_.resize(len);
904
0
    } catch (const std::exception &e) {
905
0
        RNP_LOG("malloc of %d bytes failed, %s", (int) len, e.what());
906
0
        return RNP_ERROR_OUT_OF_MEMORY;
907
0
    }
908
909
0
    size_t read = 0;
910
0
    if (!src.read(data_.data(), len, &read) || (read != len)) {
911
0
        RNP_LOG("read %d instead of %d", (int) read, (int) len);
912
0
        return RNP_ERROR_READ;
913
0
    }
914
0
    pos_ = 0;
915
0
    return RNP_SUCCESS;
916
0
}
917
918
void
919
pgp_packet_body_t::write(pgp_dest_t &dst, bool hdr) noexcept
920
0
{
921
0
    if (hdr) {
922
0
        uint8_t hdrbt[6] = {
923
0
          (uint8_t)(tag_ | PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT), 0, 0, 0, 0, 0};
924
0
        size_t hlen = 1 + write_packet_len(&hdrbt[1], data_.size());
925
0
        dst_write(&dst, hdrbt, hlen);
926
0
    }
927
0
    dst_write(&dst, data_.data(), data_.size());
928
0
}
929
930
void
931
pgp_packet_body_t::mark_secure(bool secure) noexcept
932
0
{
933
0
    secure_ = secure;
934
0
}
935
936
void
937
pgp_sk_sesskey_t::write(pgp_dest_t &dst) const
938
0
{
939
0
    pgp_packet_body_t pktbody(PGP_PKT_SK_SESSION_KEY);
940
    /* version and algorithm fields */
941
0
    pktbody.add_byte(version);
942
0
    pktbody.add_byte(alg);
943
0
    if (version == PGP_SKSK_V5) {
944
0
        pktbody.add_byte(aalg);
945
0
    }
946
    /* S2K specifier */
947
0
    pktbody.add_byte(s2k.specifier);
948
0
    pktbody.add_byte(s2k.hash_alg);
949
950
0
    switch (s2k.specifier) {
951
0
    case PGP_S2KS_SIMPLE:
952
0
        break;
953
0
    case PGP_S2KS_SALTED:
954
0
        pktbody.add(s2k.salt, sizeof(s2k.salt));
955
0
        break;
956
0
    case PGP_S2KS_ITERATED_AND_SALTED:
957
0
        pktbody.add(s2k.salt, sizeof(s2k.salt));
958
0
        pktbody.add_byte(s2k.iterations);
959
0
        break;
960
0
    default:
961
0
        RNP_LOG("Unexpected s2k specifier: %d", (int) s2k.specifier);
962
0
        throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
963
0
    }
964
    /* v5 : iv */
965
0
    if (version == PGP_SKSK_V5) {
966
0
        pktbody.add(iv, ivlen);
967
0
    }
968
    /* encrypted key and auth tag for v5 */
969
0
    if (enckeylen) {
970
0
        pktbody.add(enckey, enckeylen);
971
0
    }
972
    /* write packet */
973
0
    pktbody.write(dst);
974
0
}
975
976
rnp_result_t
977
pgp_sk_sesskey_t::parse(pgp_source_t &src)
978
0
{
979
0
    pgp_packet_body_t pkt(PGP_PKT_SK_SESSION_KEY);
980
0
    rnp_result_t      res = pkt.read(src);
981
0
    if (res) {
982
0
        return res;
983
0
    }
984
985
    /* version */
986
0
    uint8_t bt;
987
0
    if (!pkt.get(bt) || ((bt != PGP_SKSK_V4) && (bt != PGP_SKSK_V5))) {
988
0
        RNP_LOG("wrong packet version");
989
0
        return RNP_ERROR_BAD_FORMAT;
990
0
    }
991
0
    version = bt;
992
    /* symmetric algorithm */
993
0
    if (!pkt.get(bt)) {
994
0
        RNP_LOG("failed to get symm alg");
995
0
        return RNP_ERROR_BAD_FORMAT;
996
0
    }
997
0
    alg = (pgp_symm_alg_t) bt;
998
999
0
    if (version == PGP_SKSK_V5) {
1000
        /* aead algorithm */
1001
0
        if (!pkt.get(bt)) {
1002
0
            RNP_LOG("failed to get aead alg");
1003
0
            return RNP_ERROR_BAD_FORMAT;
1004
0
        }
1005
0
        aalg = (pgp_aead_alg_t) bt;
1006
0
        if ((aalg != PGP_AEAD_EAX) && (aalg != PGP_AEAD_OCB)) {
1007
0
            RNP_LOG("unsupported AEAD algorithm : %d", (int) aalg);
1008
0
            return RNP_ERROR_BAD_PARAMETERS;
1009
0
        }
1010
0
    }
1011
1012
    /* s2k */
1013
0
    if (!pkt.get(s2k)) {
1014
0
        RNP_LOG("failed to parse s2k");
1015
0
        return RNP_ERROR_BAD_FORMAT;
1016
0
    }
1017
1018
    /* v4 key */
1019
0
    if (version == PGP_SKSK_V4) {
1020
        /* encrypted session key if present */
1021
0
        size_t keylen = pkt.left();
1022
0
        if (keylen) {
1023
0
            if (keylen > PGP_MAX_KEY_SIZE + 1) {
1024
0
                RNP_LOG("too long esk");
1025
0
                return RNP_ERROR_BAD_FORMAT;
1026
0
            }
1027
0
            if (!pkt.get(enckey, keylen)) {
1028
0
                RNP_LOG("failed to get key");
1029
0
                return RNP_ERROR_BAD_FORMAT;
1030
0
            }
1031
0
        }
1032
0
        enckeylen = keylen;
1033
0
        return RNP_SUCCESS;
1034
0
    }
1035
1036
    /* v5: iv + esk + tag. For both EAX and OCB ivlen and taglen are 16 octets */
1037
0
    size_t noncelen = pgp_cipher_aead_nonce_len(aalg);
1038
0
    size_t taglen = pgp_cipher_aead_tag_len(aalg);
1039
0
    size_t keylen = 0;
1040
1041
0
    if (pkt.left() > noncelen + taglen + PGP_MAX_KEY_SIZE) {
1042
0
        RNP_LOG("too long esk");
1043
0
        return RNP_ERROR_BAD_FORMAT;
1044
0
    }
1045
0
    if (pkt.left() < noncelen + taglen + 8) {
1046
0
        RNP_LOG("too short esk");
1047
0
        return RNP_ERROR_BAD_FORMAT;
1048
0
    }
1049
    /* iv */
1050
0
    if (!pkt.get(iv, noncelen)) {
1051
0
        RNP_LOG("failed to get iv");
1052
0
        return RNP_ERROR_BAD_FORMAT;
1053
0
    }
1054
0
    ivlen = noncelen;
1055
1056
    /* key */
1057
0
    keylen = pkt.left();
1058
0
    if (!pkt.get(enckey, keylen)) {
1059
0
        RNP_LOG("failed to get key");
1060
0
        return RNP_ERROR_BAD_FORMAT;
1061
0
    }
1062
0
    enckeylen = keylen;
1063
0
    return RNP_SUCCESS;
1064
0
}
1065
1066
void
1067
pgp_pk_sesskey_t::write(pgp_dest_t &dst) const
1068
0
{
1069
0
    pgp_packet_body_t pktbody(PGP_PKT_PK_SESSION_KEY);
1070
0
    pktbody.add_byte(version);
1071
0
#if defined(ENABLE_CRYPTO_REFRESH)
1072
0
    if (version == PGP_PKSK_V3) {
1073
0
#endif
1074
0
        pktbody.add(key_id);
1075
0
#if defined(ENABLE_CRYPTO_REFRESH)
1076
0
    } else {                             // PGP_PKSK_V6
1077
0
        pktbody.add_byte(1 + fp.size()); // A one-octet size of the following two fields.
1078
0
        pktbody.add_byte((fp.size() == PGP_FINGERPRINT_V6_SIZE) ? PGP_V6 : PGP_V4);
1079
0
        pktbody.add(fp.vec());
1080
0
    }
1081
0
#endif
1082
0
    pktbody.add_byte(alg);
1083
0
    pktbody.add(material_buf.data(), material_buf.size());
1084
0
    pktbody.write(dst);
1085
0
}
1086
1087
rnp_result_t
1088
pgp_pk_sesskey_t::parse(pgp_source_t &src)
1089
0
{
1090
0
    pgp_packet_body_t pkt(PGP_PKT_PK_SESSION_KEY);
1091
0
    rnp_result_t      res = pkt.read(src);
1092
0
    if (res) {
1093
0
        return res;
1094
0
    }
1095
    /* version */
1096
0
    uint8_t bt = 0;
1097
0
    if (!pkt.get(bt)) {
1098
0
        RNP_LOG("Error when reading packet version");
1099
0
        return RNP_ERROR_BAD_FORMAT;
1100
0
    }
1101
0
#if defined(ENABLE_CRYPTO_REFRESH)
1102
0
    if ((bt != PGP_PKSK_V3) && (bt != PGP_PKSK_V6)) {
1103
#else
1104
    if ((bt != PGP_PKSK_V3)) {
1105
#endif
1106
0
        RNP_LOG("wrong packet version");
1107
0
        return RNP_ERROR_BAD_FORMAT;
1108
0
    }
1109
0
    version = (pgp_pkesk_version_t) bt;
1110
1111
0
#if defined(ENABLE_CRYPTO_REFRESH)
1112
0
    if (version == PGP_PKSK_V3)
1113
0
#endif
1114
0
    {
1115
        /* key id */
1116
0
        if (!pkt.get(key_id)) {
1117
0
            RNP_LOG("failed to get key id");
1118
0
            return RNP_ERROR_BAD_FORMAT;
1119
0
        }
1120
0
    }
1121
0
#if defined(ENABLE_CRYPTO_REFRESH)
1122
0
    else {                          // PGP_PKSK_V6
1123
0
        uint8_t fp_and_key_ver_len; // A one-octet size of the following two fields.
1124
0
        if (!pkt.get(fp_and_key_ver_len)) {
1125
0
            RNP_LOG("Error when reading length of next two fields");
1126
0
            return RNP_ERROR_BAD_FORMAT;
1127
0
        }
1128
0
        if ((fp_and_key_ver_len != 1 + PGP_FINGERPRINT_V4_SIZE) &&
1129
0
            (fp_and_key_ver_len != 1 + PGP_FINGERPRINT_V6_SIZE)) {
1130
0
            RNP_LOG("Invalid size for key version + length field");
1131
0
            return RNP_ERROR_BAD_FORMAT;
1132
0
        }
1133
1134
0
        size_t  fp_len;
1135
0
        uint8_t fp_key_version;
1136
0
        if (!pkt.get(fp_key_version)) {
1137
0
            RNP_LOG("Error when reading key version");
1138
0
            return RNP_ERROR_BAD_FORMAT;
1139
0
        }
1140
0
        switch (fp_key_version) {
1141
0
        case 0: // anonymous
1142
0
            fp_len = 0;
1143
0
            break;
1144
0
        case PGP_V4:
1145
0
            fp_len = PGP_FINGERPRINT_V4_SIZE;
1146
0
            break;
1147
0
        case PGP_V6:
1148
0
            fp_len = PGP_FINGERPRINT_V6_SIZE;
1149
0
            break;
1150
0
        default:
1151
0
            RNP_LOG("wrong key version used with PKESK v6");
1152
0
            return RNP_ERROR_BAD_FORMAT;
1153
0
        }
1154
0
        if (fp_len && (fp_len + 1 != fp_and_key_ver_len)) {
1155
0
            RNP_LOG("size mismatch (fingerprint size and fp+key version length field)");
1156
0
            return RNP_ERROR_BAD_FORMAT;
1157
0
        }
1158
0
        std::vector<uint8_t> vec(fp_len, 0);
1159
0
        if (!pkt.get(vec.data(), vec.size())) {
1160
0
            RNP_LOG("Error when reading fingerprint");
1161
0
            return RNP_ERROR_BAD_FORMAT;
1162
0
        }
1163
0
        fp = pgp::Fingerprint(vec.data(), vec.size());
1164
0
    }
1165
0
#endif
1166
1167
    /* public key algorithm */
1168
0
    if (!pkt.get(bt)) {
1169
0
        RNP_LOG("failed to get palg");
1170
0
        return RNP_ERROR_BAD_FORMAT;
1171
0
    }
1172
0
    alg = (pgp_pubkey_alg_t) bt;
1173
1174
    /* symmetric algorithm */
1175
0
    salg = PGP_SA_UNKNOWN;
1176
1177
    /* raw encrypted material */
1178
0
    if (!pkt.left()) {
1179
0
        RNP_LOG("No encrypted material");
1180
0
        return RNP_ERROR_BAD_FORMAT;
1181
0
    }
1182
0
    try {
1183
0
        material_buf.resize(pkt.left());
1184
0
    } catch (const std::exception &e) {
1185
0
        RNP_LOG("%s", e.what());
1186
0
        return RNP_ERROR_OUT_OF_MEMORY;
1187
0
    }
1188
    /* we cannot fail here */
1189
0
    pkt.get(material_buf.data(), material_buf.size());
1190
    /* check whether it can be parsed */
1191
0
    if (!parse_material()) {
1192
0
        return RNP_ERROR_BAD_FORMAT;
1193
0
    }
1194
0
    return RNP_SUCCESS;
1195
0
}
1196
1197
std::unique_ptr<pgp::EncMaterial>
1198
pgp_pk_sesskey_t::parse_material() const
1199
0
{
1200
0
    auto enc = pgp::EncMaterial::create(alg);
1201
0
    if (!enc) {
1202
0
        return nullptr;
1203
0
    }
1204
0
#if defined(ENABLE_CRYPTO_REFRESH)
1205
0
    enc->version = version;
1206
0
#endif
1207
0
    pgp_packet_body_t pkt(material_buf);
1208
0
    if (!enc->parse(pkt)) {
1209
0
        return nullptr;
1210
0
    }
1211
0
    if (pkt.left()) {
1212
0
        RNP_LOG("extra %zu bytes in pk packet", pkt.left());
1213
0
        return nullptr;
1214
0
    }
1215
0
    return enc;
1216
0
}
1217
1218
void
1219
pgp_pk_sesskey_t::write_material(const pgp::EncMaterial &material)
1220
0
{
1221
0
    pgp_packet_body_t pktbody(PGP_PKT_PK_SESSION_KEY);
1222
0
    material.write(pktbody);
1223
0
    material_buf.assign(pktbody.data(), pktbody.data() + pktbody.size());
1224
0
}
1225
1226
void
1227
pgp_one_pass_sig_t::write(pgp_dest_t &dst) const
1228
0
{
1229
0
    pgp_packet_body_t pktbody(PGP_PKT_ONE_PASS_SIG);
1230
0
    pktbody.add_byte(version);
1231
0
    pktbody.add_byte(type);
1232
0
    pktbody.add_byte(halg);
1233
0
    pktbody.add_byte(palg);
1234
0
    pktbody.add(keyid);
1235
0
    pktbody.add_byte(nested);
1236
0
    pktbody.write(dst);
1237
0
}
1238
1239
rnp_result_t
1240
pgp_one_pass_sig_t::parse(pgp_source_t &src)
1241
0
{
1242
0
    pgp_packet_body_t pkt(PGP_PKT_ONE_PASS_SIG);
1243
    /* Read the packet into memory */
1244
0
    rnp_result_t res = pkt.read(src);
1245
0
    if (res) {
1246
0
        return res;
1247
0
    }
1248
1249
0
    uint8_t buf[13] = {0};
1250
0
    if ((pkt.size() != 13) || !pkt.get(buf, 13)) {
1251
0
        return RNP_ERROR_BAD_FORMAT;
1252
0
    }
1253
    /* version */
1254
0
    if (buf[0] != 3) {
1255
0
        RNP_LOG("wrong packet version");
1256
0
        return RNP_ERROR_BAD_FORMAT;
1257
0
    }
1258
0
    version = buf[0];
1259
    /* signature type */
1260
0
    type = (pgp_sig_type_t) buf[1];
1261
    /* hash algorithm */
1262
0
    halg = (pgp_hash_alg_t) buf[2];
1263
    /* pk algorithm */
1264
0
    palg = (pgp_pubkey_alg_t) buf[3];
1265
    /* key id */
1266
0
    static_assert(std::tuple_size<decltype(keyid)>::value == PGP_KEY_ID_SIZE,
1267
0
                  "pgp_one_pass_sig_t.keyid size mismatch");
1268
0
    memcpy(keyid.data(), &buf[4], PGP_KEY_ID_SIZE);
1269
    /* nested flag */
1270
0
    nested = buf[12];
1271
0
    return RNP_SUCCESS;
1272
0
}