/* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" #include "lib/encoding/pem.h" #include "lib/cc/compat_compiler.h" #include "lib/malloc/malloc.h" #include "test/test.h" #include #include #include static const char example_pre[] = "Lest you get the wrong impression, we wombats " "are not in the habit of tunneling madly about, without any supplies " "or even a map."; /* -- Ursula Vernon, _Digger_ */ static const char expected[] = "-----BEGIN WOMBAT QUOTE-----\n" "TGVzdCB5b3UgZ2V0IHRoZSB3cm9uZyBpbXByZXNzaW9uLCB3ZSB3b21iYXRzIGFy\n" "ZSBub3QgaW4gdGhlIGhhYml0IG9mIHR1bm5lbGluZyBtYWRseSBhYm91dCwgd2l0\n" "aG91dCBhbnkgc3VwcGxpZXMgb3IgZXZlbiBhIG1hcC4=\n" "-----END WOMBAT QUOTE-----\n"; static void test_crypto_pem_encode(void *arg) { (void)arg; char buf[4096]; int n = (int) pem_encoded_size(strlen(example_pre), "WOMBAT QUOTE"); int n2 = pem_encode(buf, sizeof(buf), (const unsigned char *)example_pre, strlen(example_pre), "WOMBAT QUOTE"); tt_int_op(strlen(buf)+1, OP_EQ, n); tt_int_op(n2, OP_EQ, 0); tt_str_op(buf, OP_EQ, expected); /* Now make sure it succeeds if the buffer is exactly the length we want. */ memset(buf, 0, sizeof(buf)); n2 = pem_encode(buf, n, (const unsigned char *)example_pre, strlen(example_pre), "WOMBAT QUOTE"); tt_int_op(n2, OP_EQ, 0); tt_str_op(buf, OP_EQ, expected); /* Make sure it fails if the buffer is too short. */ memset(buf, 0, sizeof(buf)); n2 = pem_encode(buf, n - 1, (const unsigned char *)example_pre, strlen(example_pre), "WOMBAT QUOTE"); tt_int_op(n2, OP_EQ, -1); done: ; } static void test_crypto_pem_decode(void *arg) { (void)arg; unsigned char buf[4096]; /* Try a straightforward decoding. */ int n = pem_decode(buf, sizeof(buf), expected, strlen(expected), "WOMBAT QUOTE"); tt_int_op(n, OP_EQ, strlen(example_pre)); tt_mem_op(buf, OP_EQ, example_pre, n); /* Succeed if the buffer is exactly the right size. */ memset(buf, 0xff, sizeof(buf)); n = pem_decode(buf, strlen(example_pre), expected, strlen(expected), "WOMBAT QUOTE"); tt_int_op(n, OP_EQ, strlen(example_pre)); tt_mem_op(buf, OP_EQ, example_pre, n); tt_int_op(buf[n], OP_EQ, 0xff); /* Verify that it fails if the buffer is too small. */ memset(buf, 0xff, sizeof(buf)); n = pem_decode(buf, strlen(example_pre) - 1, expected, strlen(expected), "WOMBAT QUOTE"); tt_int_op(n, OP_EQ, -1); /* Verify that it fails with an incorrect tag. */ memset(buf, 0xff, sizeof(buf)); n = pem_decode(buf, sizeof(buf), expected, strlen(expected), "QUOKKA VOTE"); tt_int_op(n, OP_EQ, -1); /* Try truncated buffers of different sizes. */ size_t i; for (i = 0; i <= strlen(expected); ++i) { char *truncated = tor_memdup(expected, i); n = pem_decode(buf, sizeof(buf), truncated, i, "WOMBAT QUOTE"); tor_free(truncated); if (i < strlen(expected) - 1) { tt_int_op(n, OP_EQ, -1); } else { tt_int_op(n, OP_EQ, strlen(example_pre)); } } done: ; } struct testcase_t pem_tests[] = { { "encode", test_crypto_pem_encode, 0, NULL, NULL }, { "decode", test_crypto_pem_decode, 0, NULL, NULL }, END_OF_TESTCASES };