Commit 5721ec22 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

pem_decode(): Tolerate CRLF line endings

Fixes bug 33032; bugfix on 0.3.5.1-alpha when we introduced our own
PEM decoder.
parent b9c7c61e
Loading
Loading
Loading
Loading

changes/bug33032

0 → 100644
+6 −0
Original line number Diff line number Diff line
  o Minor bugfixes (key portability):
    - When reading PEM-encoded key data, tolerate CRLF line-endings even if
      we are not running on Windows. Previously, non-Windows hosts
      would reject these line-endings in certain positions, making
      certain key files hard to move from one host to another.
      Fixes bug 33032; bugfix on 0.3.5.1-alpha.
+7 −1
Original line number Diff line number Diff line
@@ -85,13 +85,19 @@ pem_decode(uint8_t *dest, size_t destlen, const char *src, size_t srclen,
  src = eat_whitespace_eos(src, eos);

  char *tag = NULL;
  tor_asprintf(&tag, "-----BEGIN %s-----\n", objtype);
  tor_asprintf(&tag, "-----BEGIN %s-----", objtype);
  if ((size_t)(eos-src) < strlen(tag) || fast_memneq(src, tag, strlen(tag))) {
    tor_free(tag);
    return -1;
  }
  src += strlen(tag);
  tor_free(tag);
  /* At this point we insist on spaces (including CR), then an LF. */
  src = eat_whitespace_eos_no_nl(src, eos);
  if (src == eos || *src != '\n') {
    /* Extra junk at end of line: this isn't valid. */
    return -1;
  }

  // NOTE lack of trailing \n.  We do not enforce its presence.
  tor_asprintf(&tag, "\n-----END %s-----", objtype);
+30 −0
Original line number Diff line number Diff line
@@ -115,8 +115,38 @@ test_crypto_pem_decode(void *arg)
  ;
}

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

struct testcase_t pem_tests[] = {
  { "encode", test_crypto_pem_encode, 0, NULL, NULL },
  { "decode", test_crypto_pem_decode, 0, NULL, NULL },
  { "decode_crlf", test_crypto_pem_decode_crlf, 0, NULL, NULL },
  END_OF_TESTCASES
};