2018-07-19 21:47:48 +02:00
|
|
|
/* Copyright (c) 2001-2004, Roger Dingledine.
|
|
|
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
2020-01-09 00:39:17 +01:00
|
|
|
* Copyright (c) 2007-2020, The Tor Project, Inc. */
|
2018-07-19 21:47:48 +02:00
|
|
|
/* 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 <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
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:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2020-03-11 14:40:04 +01:00
|
|
|
static void
|
|
|
|
test_crypto_pem_decode_crlf(void *arg)
|
|
|
|
{
|
|
|
|
(void)arg;
|
|
|
|
char crlf_version[4096];
|
|
|
|
uint8_t buf[4096];
|
|
|
|
|
|
|
|
/* Convert 'expected' to a version with CRLF instead of LF. */
|
|
|
|
const char *inp = expected;
|
|
|
|
char *outp = crlf_version;
|
|
|
|
while (*inp) {
|
|
|
|
if (*inp == '\n') {
|
|
|
|
*outp++ = '\r';
|
|
|
|
}
|
|
|
|
*outp++ = *inp++;
|
|
|
|
}
|
|
|
|
*outp = 0;
|
|
|
|
|
|
|
|
/* Decoding should succeed (or else we have bug 33032 again) */
|
|
|
|
int n = pem_decode(buf, sizeof(buf),
|
|
|
|
crlf_version, strlen(crlf_version),
|
|
|
|
"WOMBAT QUOTE");
|
|
|
|
tt_int_op(n, OP_EQ, strlen(example_pre));
|
|
|
|
tt_mem_op(buf, OP_EQ, example_pre, n);
|
|
|
|
|
|
|
|
done:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2018-07-19 21:47:48 +02:00
|
|
|
struct testcase_t pem_tests[] = {
|
|
|
|
{ "encode", test_crypto_pem_encode, 0, NULL, NULL },
|
|
|
|
{ "decode", test_crypto_pem_decode, 0, NULL, NULL },
|
2020-03-11 14:40:04 +01:00
|
|
|
{ "decode_crlf", test_crypto_pem_decode_crlf, 0, NULL, NULL },
|
2018-07-19 21:47:48 +02:00
|
|
|
END_OF_TESTCASES
|
|
|
|
};
|