diff --git a/src/librekey/key_store_kbx.cpp b/src/librekey/key_store_kbx.cpp index 1af49190c..1679b473a 100644 --- a/src/librekey/key_store_kbx.cpp +++ b/src/librekey/key_store_kbx.cpp @@ -389,8 +389,8 @@ rnp_key_store_kbx_from_src(rnp_key_store_t * key_store, uint8_t * buf = (uint8_t *) mem.memory(); if (has_bytes < BLOB_FIRST_SIZE) { - RNP_LOG("Too few bytes for valid KBX"); - return false; + RNP_LOG("Too few bytes for valid KBX"); + return false; } while (has_bytes > 4) { size_t blob_length = read_uint32(buf); diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 502d0f630..56605b598 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -121,6 +121,7 @@ add_executable(rnp_tests large-mpi.cpp load-g10.cpp load-g23.cpp + load-kbx.cpp load-pgp.cpp log-switch.cpp partial-length.cpp diff --git a/src/tests/data/test_invalid_g10/private-keys-v1.d/63E59092E4B1AE9F8E675B2F98AA2B8BD9F4EA59.key b/src/tests/data/test_invalid_g10/private-keys-v1.d/63E59092E4B1AE9F8E675B2F98AA2B8BD9F4EA59.key new file mode 100644 index 000000000..7b0132d16 Binary files /dev/null and b/src/tests/data/test_invalid_g10/private-keys-v1.d/63E59092E4B1AE9F8E675B2F98AA2B8BD9F4EA59.key differ diff --git a/src/tests/data/test_invalid_g10/private-keys-v1.d/7EAB41A2F46257C36F2892696F5A2F0432499AD3.key b/src/tests/data/test_invalid_g10/private-keys-v1.d/7EAB41A2F46257C36F2892696F5A2F0432499AD3.key new file mode 100644 index 000000000..9dad7e560 Binary files /dev/null and b/src/tests/data/test_invalid_g10/private-keys-v1.d/7EAB41A2F46257C36F2892696F5A2F0432499AD3.key differ diff --git a/src/tests/load-g10.cpp b/src/tests/load-g10.cpp index 4f0e25b3c..3e2c2c014 100644 --- a/src/tests/load-g10.cpp +++ b/src/tests/load-g10.cpp @@ -30,6 +30,27 @@ #include "rnp_tests.h" #include "support.h" +TEST_F(rnp_tests, test_invalid_g10) +{ + rnp_key_store_t * pub_store = NULL; + rnp_key_store_t * sec_store = NULL; + pgp_key_provider_t key_provider(rnp_key_provider_store); + // load pubring + pub_store = + new rnp_key_store_t(PGP_KEY_STORE_KBX, "data/keyrings/3/pubring.kbx", global_ctx); + assert_true(rnp_key_store_load_from_path(pub_store, NULL)); + // trigger "Unsupported public key algorithm:" error message + sec_store = new rnp_key_store_t( + PGP_KEY_STORE_G10, "data/test_invalid_g10/private-keys-v1.d", global_ctx); + key_provider.userdata = pub_store; + assert_true(rnp_key_store_load_from_path(sec_store, &key_provider)); + // NULL key_provider + assert_true(rnp_key_store_load_from_path(sec_store, NULL)); + + delete pub_store; + delete sec_store; +} + /* This test loads G10 keyrings and verifies certain properties * of the keys are correct. */ diff --git a/src/tests/load-kbx.cpp b/src/tests/load-kbx.cpp new file mode 100644 index 000000000..7b0b107ad --- /dev/null +++ b/src/tests/load-kbx.cpp @@ -0,0 +1,550 @@ +/* + * Copyright (c) 2017-2023 [Ribose Inc](https://www.ribose.com). + * 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 OWNER 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 "../librekey/key_store_pgp.h" +#include "../librekey/key_store_kbx.h" +#include "pgp-key.h" + +#include "rnp_tests.h" +#include "support.h" + +#include + +#define BLOB_HEADER_SIZE 0x5 +#define BLOB_SIZE_LIMIT (5 * 1024 * 1024) +#define BLOB_FIRST_SIZE 0x20 +#define BLOB_KEY_SIZE 0x1C +#define BLOB_UID_SIZE 0x0C +#define BLOB_SIG_SIZE 0x04 + +static void +w32(uint8_t *dst, uint32_t val) +{ + dst[0] = val >> 24; + dst[1] = val >> 16; + dst[2] = val >> 8; + dst[3] = val & 0xFF; +} + +static void +make_valid_header_blob(uint8_t *buf) +{ + memset(buf, 0, BLOB_FIRST_SIZE); + /* Length of this blob */ + w32(buf, BLOB_FIRST_SIZE); + /* Blob type */ + buf[4] = KBX_HEADER_BLOB; + /* Version */ + buf[5] = 1; + /* Flags */ + buf[6] = 0; + buf[7] = 0; + memcpy(buf + 8, "KBXf", 4); +} + +/* See kbx/keybox-blob.c in the gnupg sources for the KBX format spec. */ +TEST_F(rnp_tests, test_invalid_kbx) +{ + rnp_ffi_t ffi = NULL; + rnp_input_t mem_input = NULL; + uint8_t buf[1024]; + + memset(buf, 0, sizeof buf); + assert_rnp_success(rnp_ffi_create(&ffi, "KBX", "GPG")); + /* Available blob bytes < first blob min size */ + w32(buf, BLOB_FIRST_SIZE); + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE - 1, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* Stored blob size < BLOB_HEADER_SIZE */ + w32(buf, BLOB_HEADER_SIZE - 1); + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* Stored blob size exceeds BLOB_SIZE_LIMIT */ + w32(buf, BLOB_SIZE_LIMIT + 1); + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* Stored blob size > available blob bytes */ + w32(buf, BLOB_SIZE_LIMIT - 1); + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* Unsupported blob type */ + w32(buf, BLOB_FIRST_SIZE); + buf[4] = 0xFF; + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* The first blob has wrong length */ + w32(buf, BLOB_FIRST_SIZE + 1); + buf[4] = KBX_HEADER_BLOB; + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 1, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* Wrong version */ + w32(buf, BLOB_FIRST_SIZE); + buf[4] = KBX_HEADER_BLOB; + buf[5] = 0xFF; + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* The first blob hasn't got a KBXf magic string */ + w32(buf, BLOB_FIRST_SIZE); + buf[4] = KBX_HEADER_BLOB; + buf[5] = 1; + /* Flags */ + buf[6] = 0; + buf[7] = 0; + buf[8] = 0xFF; + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* Valid header blob + empty blob + excess trailing bytes */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, BLOB_HEADER_SIZE); + buf[BLOB_FIRST_SIZE + 4] = KBX_EMPTY_BLOB; + assert_rnp_success( + rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + BLOB_HEADER_SIZE + 3, false)); + assert_rnp_success(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* Valid header blob + too small PGP blob */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 19); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 19, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* Valid header blob + wrong version in the PGP blob */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 0xFF; + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* Wrong keyblock offset in the PGP blob */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + /* Flags */ + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + /* Keyblock offset */ + w32(buf + BLOB_FIRST_SIZE + 8, UINT32_MAX); + /* Keyblock length */ + w32(buf + BLOB_FIRST_SIZE + 12, UINT32_MAX); + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* 0 keys in the PGP blob */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + /* Flags */ + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + /* Keyblock offset */ + w32(buf + BLOB_FIRST_SIZE + 8, 0); + /* Keyblock length */ + w32(buf + BLOB_FIRST_SIZE + 12, 0); + /* NKEYS MSB */ + buf[BLOB_FIRST_SIZE + 16] = 0; + /* NKEYS LSB */ + buf[BLOB_FIRST_SIZE + 17] = 0; + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* Too many keys in the PGP blob */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + /* Flags */ + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + /* Keyblock offset */ + w32(buf + BLOB_FIRST_SIZE + 8, 0); + /* Keyblock length */ + w32(buf + BLOB_FIRST_SIZE + 12, 0); + /* NKEYS MSB */ + buf[BLOB_FIRST_SIZE + 16] = 0x80; + /* NKEYS LSB */ + buf[BLOB_FIRST_SIZE + 17] = 1; + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* Size of the key information structure < 28 */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + /* Flags */ + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + /* Keyblock offset */ + w32(buf + BLOB_FIRST_SIZE + 8, 0); + /* Keyblock length */ + w32(buf + BLOB_FIRST_SIZE + 12, 0); + /* NKEYS MSB */ + buf[BLOB_FIRST_SIZE + 16] = 0; + /* NKEYS LSB */ + buf[BLOB_FIRST_SIZE + 17] = 1; + /* Size of the key information structure MSB */ + buf[BLOB_FIRST_SIZE + 18] = 0; + /* Size of the key information structure LSB */ + buf[BLOB_FIRST_SIZE + 19] = BLOB_KEY_SIZE - 1; + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* "Too few bytes left for key blob" */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + w32(buf + BLOB_FIRST_SIZE + 8, 0); + w32(buf + BLOB_FIRST_SIZE + 12, 0); + buf[BLOB_FIRST_SIZE + 16] = 0; + buf[BLOB_FIRST_SIZE + 17] = 1; + /* Size of the key information structure MSB */ + buf[BLOB_FIRST_SIZE + 18] = 0; + /* Size of the key information structure LSB */ + buf[BLOB_FIRST_SIZE + 19] = BLOB_KEY_SIZE; + assert_rnp_success(rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* "No data for sn_size" */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20 + 28); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + w32(buf + BLOB_FIRST_SIZE + 8, 0); + w32(buf + BLOB_FIRST_SIZE + 12, 0); + buf[BLOB_FIRST_SIZE + 16] = 0; + buf[BLOB_FIRST_SIZE + 17] = 1; + buf[BLOB_FIRST_SIZE + 18] = 0; + buf[BLOB_FIRST_SIZE + 19] = BLOB_KEY_SIZE; + assert_rnp_success( + rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* SN size exceeds available bytes */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20 + BLOB_KEY_SIZE + 2); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + w32(buf + BLOB_FIRST_SIZE + 8, 0); + w32(buf + BLOB_FIRST_SIZE + 12, 0); + buf[BLOB_FIRST_SIZE + 16] = 0; + buf[BLOB_FIRST_SIZE + 17] = 1; + buf[BLOB_FIRST_SIZE + 18] = 0; + buf[BLOB_FIRST_SIZE + 19] = 28; + /* Size of the serial number MSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE] = 0xFF; + /* Size of the serial number LSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 1] = 0xFF; + assert_rnp_success( + rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20 + 28 + 2, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* "Too few data for uids" */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20 + BLOB_KEY_SIZE + 2); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + w32(buf + BLOB_FIRST_SIZE + 8, 0); + w32(buf + BLOB_FIRST_SIZE + 12, 0); + buf[BLOB_FIRST_SIZE + 16] = 0; + buf[BLOB_FIRST_SIZE + 17] = 1; + buf[BLOB_FIRST_SIZE + 18] = 0; + buf[BLOB_FIRST_SIZE + 19] = 28; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 1] = 0; + assert_rnp_success( + rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20 + 28 + 2, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* "Too many uids in the PGP blob" */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20 + BLOB_KEY_SIZE + 2 + 4); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + w32(buf + BLOB_FIRST_SIZE + 8, 0); + w32(buf + BLOB_FIRST_SIZE + 12, 0); + buf[BLOB_FIRST_SIZE + 16] = 0; + buf[BLOB_FIRST_SIZE + 17] = 1; + buf[BLOB_FIRST_SIZE + 18] = 0; + buf[BLOB_FIRST_SIZE + 19] = 28; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 1] = 0; + /* Number of user IDs MSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 2] = 0x80; + /* Number of user IDs LSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 3] = 1; + assert_rnp_success( + rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20 + 28 + 2 + 4, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* "Too few bytes for uid struct" */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20 + BLOB_KEY_SIZE + 2 + 4); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + w32(buf + BLOB_FIRST_SIZE + 8, 0); + w32(buf + BLOB_FIRST_SIZE + 12, 0); + buf[BLOB_FIRST_SIZE + 16] = 0; + buf[BLOB_FIRST_SIZE + 17] = 1; + buf[BLOB_FIRST_SIZE + 18] = 0; + buf[BLOB_FIRST_SIZE + 19] = 28; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 1] = 0; + /* Number of user IDs MSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 2] = 0; + /* Number of user IDs LSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 3] = 1; + /* Size of user ID information structure MSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 4] = 0; + /* Size of user ID information structure LSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 5] = BLOB_UID_SIZE - 1; + assert_rnp_success( + rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20 + 28 + 2 + 4, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* "Too few bytes to read uid struct." */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20 + BLOB_KEY_SIZE + 2 + 4); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + w32(buf + BLOB_FIRST_SIZE + 8, 0); + w32(buf + BLOB_FIRST_SIZE + 12, 0); + buf[BLOB_FIRST_SIZE + 16] = 0; + buf[BLOB_FIRST_SIZE + 17] = 1; + buf[BLOB_FIRST_SIZE + 18] = 0; + buf[BLOB_FIRST_SIZE + 19] = 28; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 1] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 2] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 3] = 1; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 4] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 5] = BLOB_UID_SIZE; + assert_rnp_success( + rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20 + 28 + 2 + 4, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* "No data left for sigs" */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20 + BLOB_KEY_SIZE + 2 + 4 + BLOB_UID_SIZE); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + w32(buf + BLOB_FIRST_SIZE + 8, 0); + w32(buf + BLOB_FIRST_SIZE + 12, 0); + buf[BLOB_FIRST_SIZE + 16] = 0; + buf[BLOB_FIRST_SIZE + 17] = 1; + buf[BLOB_FIRST_SIZE + 18] = 0; + buf[BLOB_FIRST_SIZE + 19] = 28; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 1] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 2] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 3] = 1; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 4] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 5] = BLOB_UID_SIZE; + assert_rnp_success(rnp_input_from_memory( + &mem_input, buf, BLOB_FIRST_SIZE + 20 + 28 + 2 + 4 + BLOB_UID_SIZE, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* "Too many sigs in the PGP blob" */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20 + BLOB_KEY_SIZE + 2 + 4 + 4); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + w32(buf + BLOB_FIRST_SIZE + 8, 0); + w32(buf + BLOB_FIRST_SIZE + 12, 0); + buf[BLOB_FIRST_SIZE + 16] = 0; + buf[BLOB_FIRST_SIZE + 17] = 1; + buf[BLOB_FIRST_SIZE + 18] = 0; + buf[BLOB_FIRST_SIZE + 19] = 28; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 1] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 2] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 3] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 4] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 5] = BLOB_UID_SIZE; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 6] = 0x80; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 7] = 1; + assert_rnp_success( + rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20 + 28 + 2 + 4 + 4, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* "Too small SIGN structure" */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20 + BLOB_KEY_SIZE + 2 + 4 + 4); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + w32(buf + BLOB_FIRST_SIZE + 8, 0); + w32(buf + BLOB_FIRST_SIZE + 12, 0); + buf[BLOB_FIRST_SIZE + 16] = 0; + buf[BLOB_FIRST_SIZE + 17] = 1; + buf[BLOB_FIRST_SIZE + 18] = 0; + buf[BLOB_FIRST_SIZE + 19] = 28; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 1] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 2] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 3] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 4] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 5] = BLOB_UID_SIZE; + /* [NSIGS] Number of signatures MSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 6] = 0; + /* [NSIGS] Number of signatures LSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 7] = 1; + /* Size of signature information MSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 8] = 0; + /* Size of signature information LSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 9] = BLOB_SIG_SIZE - 1; + assert_rnp_success( + rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20 + 28 + 2 + 4 + 4, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* "Too few data for sig" */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20 + BLOB_KEY_SIZE + 2 + 4 + 4); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + buf[BLOB_FIRST_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 7] = 0; + w32(buf + BLOB_FIRST_SIZE + 8, 0); + w32(buf + BLOB_FIRST_SIZE + 12, 0); + buf[BLOB_FIRST_SIZE + 16] = 0; + buf[BLOB_FIRST_SIZE + 17] = 1; + buf[BLOB_FIRST_SIZE + 18] = 0; + buf[BLOB_FIRST_SIZE + 19] = 28; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 1] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 2] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 3] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 4] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 5] = BLOB_UID_SIZE; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 7] = 1; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 8] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 9] = BLOB_SIG_SIZE; + assert_rnp_success( + rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20 + 28 + 2 + 4 + 4, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + /* "Too few data for trust/validities" */ + make_valid_header_blob(buf); + w32(buf + BLOB_FIRST_SIZE, 20 + BLOB_KEY_SIZE + 2 + 4 + 4); + buf[BLOB_FIRST_SIZE + 4] = KBX_PGP_BLOB; + buf[BLOB_FIRST_SIZE + 5] = 1; + /* flags MSB */ + buf[BLOB_FIRST_SIZE + 6] = 0; + /* flags LSB */ + buf[BLOB_FIRST_SIZE + 7] = 0; + /* keyblock offset */ + w32(buf + BLOB_FIRST_SIZE + 8, 0); + /* keyblock length */ + w32(buf + BLOB_FIRST_SIZE + 12, 0); + /* NKEYS MSB */ + buf[BLOB_FIRST_SIZE + 16] = 0; + /* NKEYS LSB */ + buf[BLOB_FIRST_SIZE + 17] = 1; + /* Size of the key information structure MSB */ + buf[BLOB_FIRST_SIZE + 18] = 0; + /* Size of the key information structure LSB */ + buf[BLOB_FIRST_SIZE + 19] = 28; + /* Size of the serial number MSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE] = 0; + /* Size of the serial number LSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 1] = 0; + /* Number of user IDs MSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 2] = 0; + /* Number of user IDs LSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 3] = 0; + /* Size of user ID information structure MSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 4] = 0; + /* Size of user ID information structure LSB */ + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 5] = BLOB_UID_SIZE; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 6] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 7] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 8] = 0; + buf[BLOB_FIRST_SIZE + 20 + BLOB_KEY_SIZE + 9] = BLOB_SIG_SIZE; + assert_rnp_success( + rnp_input_from_memory(&mem_input, buf, BLOB_FIRST_SIZE + 20 + 28 + 2 + 4 + 4, false)); + assert_rnp_failure(rnp_load_keys( + ffi, "KBX", mem_input, RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS)); + assert_rnp_success(rnp_input_destroy(mem_input)); + + rnp_ffi_destroy(ffi); +}