tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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 };