Line data Source code
1 : /* Copyright (c) 2001-2004, Roger Dingledine.
2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 : /* See LICENSE for licensing information */
5 :
6 : #include "orconfig.h"
7 :
8 : #include "lib/encoding/pem.h"
9 : #include "lib/cc/compat_compiler.h"
10 : #include "lib/malloc/malloc.h"
11 :
12 : #include "test/test.h"
13 :
14 : #include <string.h>
15 : #include <stdio.h>
16 : #include <stdlib.h>
17 :
18 : static const char example_pre[] =
19 : "Lest you get the wrong impression, we wombats "
20 : "are not in the habit of tunneling madly about, without any supplies "
21 : "or even a map."; /* -- Ursula Vernon, _Digger_ */
22 : static const char expected[] =
23 : "-----BEGIN WOMBAT QUOTE-----\n"
24 : "TGVzdCB5b3UgZ2V0IHRoZSB3cm9uZyBpbXByZXNzaW9uLCB3ZSB3b21iYXRzIGFy\n"
25 : "ZSBub3QgaW4gdGhlIGhhYml0IG9mIHR1bm5lbGluZyBtYWRseSBhYm91dCwgd2l0\n"
26 : "aG91dCBhbnkgc3VwcGxpZXMgb3IgZXZlbiBhIG1hcC4=\n"
27 : "-----END WOMBAT QUOTE-----\n";
28 :
29 : static void
30 1 : test_crypto_pem_encode(void *arg)
31 : {
32 1 : (void)arg;
33 :
34 1 : char buf[4096];
35 :
36 1 : int n = (int) pem_encoded_size(strlen(example_pre), "WOMBAT QUOTE");
37 :
38 1 : int n2 = pem_encode(buf, sizeof(buf),
39 : (const unsigned char *)example_pre, strlen(example_pre),
40 : "WOMBAT QUOTE");
41 1 : tt_int_op(strlen(buf)+1, OP_EQ, n);
42 1 : tt_int_op(n2, OP_EQ, 0);
43 1 : tt_str_op(buf, OP_EQ, expected);
44 :
45 : /* Now make sure it succeeds if the buffer is exactly the length we want. */
46 1 : memset(buf, 0, sizeof(buf));
47 1 : n2 = pem_encode(buf, n, (const unsigned char *)example_pre,
48 : strlen(example_pre), "WOMBAT QUOTE");
49 1 : tt_int_op(n2, OP_EQ, 0);
50 1 : tt_str_op(buf, OP_EQ, expected);
51 :
52 : /* Make sure it fails if the buffer is too short. */
53 1 : memset(buf, 0, sizeof(buf));
54 1 : n2 = pem_encode(buf, n - 1, (const unsigned char *)example_pre,
55 : strlen(example_pre), "WOMBAT QUOTE");
56 1 : tt_int_op(n2, OP_EQ, -1);
57 :
58 1 : done:
59 1 : ;
60 1 : }
61 :
62 : static void
63 1 : test_crypto_pem_decode(void *arg)
64 : {
65 1 : (void)arg;
66 :
67 1 : unsigned char buf[4096];
68 :
69 : /* Try a straightforward decoding. */
70 1 : int n = pem_decode(buf, sizeof(buf),
71 : expected, strlen(expected),
72 : "WOMBAT QUOTE");
73 1 : tt_int_op(n, OP_EQ, strlen(example_pre));
74 1 : tt_mem_op(buf, OP_EQ, example_pre, n);
75 :
76 : /* Succeed if the buffer is exactly the right size. */
77 1 : memset(buf, 0xff, sizeof(buf));
78 1 : n = pem_decode(buf, strlen(example_pre),
79 : expected, strlen(expected),
80 : "WOMBAT QUOTE");
81 1 : tt_int_op(n, OP_EQ, strlen(example_pre));
82 1 : tt_mem_op(buf, OP_EQ, example_pre, n);
83 1 : tt_int_op(buf[n], OP_EQ, 0xff);
84 :
85 : /* Verify that it fails if the buffer is too small. */
86 1 : memset(buf, 0xff, sizeof(buf));
87 1 : n = pem_decode(buf, strlen(example_pre) - 1,
88 : expected, strlen(expected),
89 : "WOMBAT QUOTE");
90 1 : tt_int_op(n, OP_EQ, -1);
91 :
92 : /* Verify that it fails with an incorrect tag. */
93 1 : memset(buf, 0xff, sizeof(buf));
94 1 : n = pem_decode(buf, sizeof(buf),
95 : expected, strlen(expected),
96 : "QUOKKA VOTE");
97 1 : tt_int_op(n, OP_EQ, -1);
98 :
99 : /* Try truncated buffers of different sizes. */
100 : size_t i;
101 233 : for (i = 0; i <= strlen(expected); ++i) {
102 232 : char *truncated = tor_memdup(expected, i);
103 232 : n = pem_decode(buf, sizeof(buf),
104 : truncated, i,
105 : "WOMBAT QUOTE");
106 232 : tor_free(truncated);
107 232 : if (i < strlen(expected) - 1) {
108 230 : tt_int_op(n, OP_EQ, -1);
109 : } else {
110 232 : tt_int_op(n, OP_EQ, strlen(example_pre));
111 : }
112 : }
113 :
114 1 : done:
115 1 : ;
116 1 : }
117 :
118 : static void
119 1 : test_crypto_pem_decode_crlf(void *arg)
120 : {
121 1 : (void)arg;
122 1 : char crlf_version[4096];
123 1 : uint8_t buf[4096];
124 :
125 : /* Convert 'expected' to a version with CRLF instead of LF. */
126 1 : const char *inp = expected;
127 1 : char *outp = crlf_version;
128 232 : while (*inp) {
129 231 : if (*inp == '\n') {
130 5 : *outp++ = '\r';
131 : }
132 231 : *outp++ = *inp++;
133 : }
134 1 : *outp = 0;
135 :
136 : /* Decoding should succeed (or else we have bug 33032 again) */
137 1 : int n = pem_decode(buf, sizeof(buf),
138 : crlf_version, strlen(crlf_version),
139 : "WOMBAT QUOTE");
140 1 : tt_int_op(n, OP_EQ, strlen(example_pre));
141 1 : tt_mem_op(buf, OP_EQ, example_pre, n);
142 :
143 1 : done:
144 1 : ;
145 1 : }
146 :
147 : struct testcase_t pem_tests[] = {
148 : { "encode", test_crypto_pem_encode, 0, NULL, NULL },
149 : { "decode", test_crypto_pem_decode, 0, NULL, NULL },
150 : { "decode_crlf", test_crypto_pem_decode_crlf, 0, NULL, NULL },
151 : END_OF_TESTCASES
152 : };
|