test_pem.c (4353B)
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 test_crypto_pem_encode(void *arg) 31 { 32 (void)arg; 33 34 char buf[4096]; 35 36 int n = (int) pem_encoded_size(strlen(example_pre), "WOMBAT QUOTE"); 37 38 int n2 = pem_encode(buf, sizeof(buf), 39 (const unsigned char *)example_pre, strlen(example_pre), 40 "WOMBAT QUOTE"); 41 tt_int_op(strlen(buf)+1, OP_EQ, n); 42 tt_int_op(n2, OP_EQ, 0); 43 tt_str_op(buf, OP_EQ, expected); 44 45 /* Now make sure it succeeds if the buffer is exactly the length we want. */ 46 memset(buf, 0, sizeof(buf)); 47 n2 = pem_encode(buf, n, (const unsigned char *)example_pre, 48 strlen(example_pre), "WOMBAT QUOTE"); 49 tt_int_op(n2, OP_EQ, 0); 50 tt_str_op(buf, OP_EQ, expected); 51 52 /* Make sure it fails if the buffer is too short. */ 53 memset(buf, 0, sizeof(buf)); 54 n2 = pem_encode(buf, n - 1, (const unsigned char *)example_pre, 55 strlen(example_pre), "WOMBAT QUOTE"); 56 tt_int_op(n2, OP_EQ, -1); 57 58 done: 59 ; 60 } 61 62 static void 63 test_crypto_pem_decode(void *arg) 64 { 65 (void)arg; 66 67 unsigned char buf[4096]; 68 69 /* Try a straightforward decoding. */ 70 int n = pem_decode(buf, sizeof(buf), 71 expected, strlen(expected), 72 "WOMBAT QUOTE"); 73 tt_int_op(n, OP_EQ, strlen(example_pre)); 74 tt_mem_op(buf, OP_EQ, example_pre, n); 75 76 /* Succeed if the buffer is exactly the right size. */ 77 memset(buf, 0xff, sizeof(buf)); 78 n = pem_decode(buf, strlen(example_pre), 79 expected, strlen(expected), 80 "WOMBAT QUOTE"); 81 tt_int_op(n, OP_EQ, strlen(example_pre)); 82 tt_mem_op(buf, OP_EQ, example_pre, n); 83 tt_int_op(buf[n], OP_EQ, 0xff); 84 85 /* Verify that it fails if the buffer is too small. */ 86 memset(buf, 0xff, sizeof(buf)); 87 n = pem_decode(buf, strlen(example_pre) - 1, 88 expected, strlen(expected), 89 "WOMBAT QUOTE"); 90 tt_int_op(n, OP_EQ, -1); 91 92 /* Verify that it fails with an incorrect tag. */ 93 memset(buf, 0xff, sizeof(buf)); 94 n = pem_decode(buf, sizeof(buf), 95 expected, strlen(expected), 96 "QUOKKA VOTE"); 97 tt_int_op(n, OP_EQ, -1); 98 99 /* Try truncated buffers of different sizes. */ 100 size_t i; 101 for (i = 0; i <= strlen(expected); ++i) { 102 char *truncated = tor_memdup(expected, i); 103 n = pem_decode(buf, sizeof(buf), 104 truncated, i, 105 "WOMBAT QUOTE"); 106 tor_free(truncated); 107 if (i < strlen(expected) - 1) { 108 tt_int_op(n, OP_EQ, -1); 109 } else { 110 tt_int_op(n, OP_EQ, strlen(example_pre)); 111 } 112 } 113 114 done: 115 ; 116 } 117 118 static void 119 test_crypto_pem_decode_crlf(void *arg) 120 { 121 (void)arg; 122 char crlf_version[4096]; 123 uint8_t buf[4096]; 124 125 /* Convert 'expected' to a version with CRLF instead of LF. */ 126 const char *inp = expected; 127 char *outp = crlf_version; 128 while (*inp) { 129 if (*inp == '\n') { 130 *outp++ = '\r'; 131 } 132 *outp++ = *inp++; 133 } 134 *outp = 0; 135 136 /* Decoding should succeed (or else we have bug 33032 again) */ 137 int n = pem_decode(buf, sizeof(buf), 138 crlf_version, strlen(crlf_version), 139 "WOMBAT QUOTE"); 140 tt_int_op(n, OP_EQ, strlen(example_pre)); 141 tt_mem_op(buf, OP_EQ, example_pre, n); 142 143 done: 144 ; 145 } 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 };