tor  0.4.0.1-alpha
pem.c
Go to the documentation of this file.
1 /* Copyright (c) 2001, Matej Pfajfar.
2  * Copyright (c) 2001-2004, Roger Dingledine.
3  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4  * Copyright (c) 2007-2019, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
15 #include "orconfig.h"
16 
17 #include "lib/encoding/pem.h"
18 
19 #include "lib/ctime/di_ops.h"
20 #include "lib/encoding/binascii.h"
21 #include "lib/log/util_bug.h"
22 #include "lib/malloc/malloc.h"
23 #include "lib/string/printf.h"
24 #include "lib/string/util_string.h"
25 
26 #include <string.h>
27 
32 size_t
33 pem_encoded_size(size_t src_len, const char *objtype)
34 {
35  return
36  strlen("-----BEGIN -----\n") +
37  strlen("-----END -----\n") +
38  strlen(objtype) * 2 +
39  base64_encode_size(src_len, BASE64_ENCODE_MULTILINE)
40  + 1;
41 }
42 
48 int
49 pem_encode(char *dest, size_t destlen, const uint8_t *src, size_t srclen,
50  const char *objtype)
51 {
52  if (tor_snprintf(dest, destlen, "-----BEGIN %s-----\n", objtype) < 0)
53  return -1;
54 
55  size_t offset = strlen(dest);
56 
57  int n = base64_encode(dest + offset, destlen - offset,
58  (const char *)src, srclen, BASE64_ENCODE_MULTILINE);
59  if (n < 0)
60  return -1;
61  offset += n;
62  if (BUG(offset > destlen))
63  return -1;
64 
65  if (tor_snprintf(dest + offset, destlen - offset,
66  "-----END %s-----\n", objtype) < 0)
67  return -1;
68 
69  tor_assert(strlen(dest) + 1 <= pem_encoded_size(srclen, objtype));
70  return 0;
71 }
72 
79 int
80 pem_decode(uint8_t *dest, size_t destlen, const char *src, size_t srclen,
81  const char *objtype)
82 {
83  const char *eos = src + srclen;
84 
85  src = eat_whitespace_eos(src, eos);
86 
87  char *tag = NULL;
88  tor_asprintf(&tag, "-----BEGIN %s-----\n", objtype);
89  if ((size_t)(eos-src) < strlen(tag) || fast_memneq(src, tag, strlen(tag))) {
90  tor_free(tag);
91  return -1;
92  }
93  src += strlen(tag);
94  tor_free(tag);
95 
96  // NOTE lack of trailing \n. We do not enforce its presence.
97  tor_asprintf(&tag, "\n-----END %s-----", objtype);
98  const char *end_of_base64 = tor_memstr(src, eos-src, tag);
99  tor_free(tag);
100  if (end_of_base64 == NULL)
101  return -1;
102 
103  /* Should we actually allow extra stuff at the end? */
104 
105  return base64_decode((char*)dest, destlen, src, end_of_base64-src);
106 }
Header for printf.c.
Headers for di_ops.c.
size_t base64_encode_size(size_t srclen, int flags)
Definition: binascii.c:166
#define tor_free(p)
Definition: malloc.h:52
Header for util_string.c.
int pem_encode(char *dest, size_t destlen, const uint8_t *src, size_t srclen, const char *objtype)
Definition: pem.c:49
Headers for util_malloc.c.
int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen, int flags)
Definition: binascii.c:215
Header for pem.c.
tor_assert(buffer)
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
Header for binascii.c.
int pem_decode(uint8_t *dest, size_t destlen, const char *src, size_t srclen, const char *objtype)
Definition: pem.c:80
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:394
size_t pem_encoded_size(size_t src_len, const char *objtype)
Definition: pem.c:33
Macros to manage assertions, fatal and non-fatal.
const char * eat_whitespace_eos(const char *s, const char *eos)
Definition: util_string.c:298