FD.io VPP  v20.05-21-gb1500e9ff
Vector Packet Processing
certs.c
Go to the documentation of this file.
1 #include <openssl/pem.h>
2 #include <vppinfra/error.h>
3 #include "certs.h"
4 
5 int
6 ptls_compare_separator_line (const char *line, const char *begin_or_end,
7  const char *label)
8 {
9  int ret = strncmp (line, "-----", 5);
10  size_t text_index = 5;
11 
12  if (ret == 0)
13  {
14  size_t begin_or_end_length = strlen (begin_or_end);
15  ret = strncmp (line + text_index, begin_or_end, begin_or_end_length);
16  text_index += begin_or_end_length;
17  }
18 
19  if (ret == 0)
20  {
21  ret = line[text_index] - ' ';
22  text_index++;
23  }
24 
25  if (ret == 0)
26  {
27  size_t label_length = strlen (label);
28  ret = strncmp (line + text_index, label, label_length);
29  text_index += label_length;
30  }
31 
32  if (ret == 0)
33  {
34  ret = strncmp (line + text_index, "-----", 5);
35  }
36 
37  return ret;
38 }
39 
40 int
41 ptls_get_bio_pem_object (BIO * bio, const char *label, ptls_buffer_t * buf)
42 {
43  int ret = PTLS_ERROR_PEM_LABEL_NOT_FOUND;
44  char line[256];
45  ptls_base64_decode_state_t state;
46 
47  /* Get the label on a line by itself */
48  while (BIO_gets (bio, line, 256))
49  {
50  if (ptls_compare_separator_line (line, "BEGIN", label) == 0)
51  {
52  ret = 0;
53  ptls_base64_decode_init (&state);
54  break;
55  }
56  }
57  /* Get the data in the buffer */
58  while (ret == 0 && BIO_gets (bio, line, 256))
59  {
60  if (ptls_compare_separator_line (line, "END", label) == 0)
61  {
62  if (state.status == PTLS_BASE64_DECODE_DONE
63  || (state.status == PTLS_BASE64_DECODE_IN_PROGRESS
64  && state.nbc == 0))
65  {
66  ret = 0;
67  }
68  else
69  {
70  ret = PTLS_ERROR_INCORRECT_BASE64;
71  }
72  break;
73  }
74  else
75  {
76  ret = ptls_base64_decode (line, &state, buf);
77  }
78  }
79 
80  return ret;
81 }
82 
83 int
84 ptls_load_bio_pem_objects (BIO * bio, const char *label, ptls_iovec_t * list,
85  size_t list_max, size_t * nb_objects)
86 {
87  int ret = 0;
88  size_t count = 0;
89 
90  *nb_objects = 0;
91 
92  if (ret == 0)
93  {
94  while (count < list_max)
95  {
96  ptls_buffer_t buf;
97 
98  ptls_buffer_init (&buf, "", 0);
99 
100  ret = ptls_get_bio_pem_object (bio, label, &buf);
101 
102  if (ret == 0)
103  {
104  if (buf.off > 0 && buf.is_allocated)
105  {
106  list[count].base = buf.base;
107  list[count].len = buf.off;
108  count++;
109  }
110  else
111  {
112  ptls_buffer_dispose (&buf);
113  }
114  }
115  else
116  {
117  ptls_buffer_dispose (&buf);
118  break;
119  }
120  }
121  }
122 
123  if (ret == PTLS_ERROR_PEM_LABEL_NOT_FOUND && count > 0)
124  {
125  ret = 0;
126  }
127 
128  *nb_objects = count;
129 
130  return ret;
131 }
132 
133 #define PTLS_MAX_CERTS_IN_CONTEXT 16
134 
135 int
136 ptls_load_bio_certificates (ptls_context_t * ctx, BIO * bio)
137 {
138  int ret = 0;
139 
140  ctx->certificates.list =
141  (ptls_iovec_t *) malloc (PTLS_MAX_CERTS_IN_CONTEXT *
142  sizeof (ptls_iovec_t));
143 
144  if (ctx->certificates.list == NULL)
145  {
146  ret = PTLS_ERROR_NO_MEMORY;
147  }
148  else
149  {
150  ret =
151  ptls_load_bio_pem_objects (bio, "CERTIFICATE", ctx->certificates.list,
153  &ctx->certificates.count);
154  }
155 
156  return ret;
157 }
158 
159 int
160 load_bio_certificate_chain (ptls_context_t * ctx, const char *cert_data)
161 {
162  BIO *cert_bio;
163  cert_bio = BIO_new_mem_buf (cert_data, -1);
164  if (ptls_load_bio_certificates (ctx, cert_bio) != 0)
165  {
166  BIO_free (cert_bio);
167  return -1;
168  }
169  BIO_free (cert_bio);
170  return 0;
171 }
172 
173 int
174 load_bio_private_key (ptls_context_t * ctx, const char *pk_data)
175 {
176  static ptls_openssl_sign_certificate_t sc;
177  EVP_PKEY *pkey;
178  BIO *key_bio;
179 
180  key_bio = BIO_new_mem_buf (pk_data, -1);
181  pkey = PEM_read_bio_PrivateKey (key_bio, NULL, NULL, NULL);
182  BIO_free (key_bio);
183 
184  if (pkey == NULL)
185  return -1;
186 
187  ptls_openssl_init_sign_certificate (&sc, pkey);
188  EVP_PKEY_free (pkey);
189 
190  ctx->sign_certificate = &sc.super;
191  return 0;
192 }
193 
194 /*
195  * fd.io coding-style-patch-verification: ON
196  *
197  * Local Variables:
198  * eval: (c-set-style "gnu")
199  * End:
200  */
u8 count
Definition: dhcp.api:208
int ptls_compare_separator_line(const char *line, const char *begin_or_end, const char *label)
Definition: certs.c:24
#define PTLS_MAX_CERTS_IN_CONTEXT
Definition: certs.c:133
int ptls_get_bio_pem_object(BIO *bio, const char *label, ptls_buffer_t *buf)
Definition: certs.c:59
int ptls_load_bio_certificates(ptls_context_t *ctx, BIO *bio)
Definition: certs.c:154
long ctx[MAX_CONNS]
Definition: main.c:144
u32 label
Definition: fib_types.api:25
int load_bio_certificate_chain(ptls_context_t *ctx, const char *cert_data)
Definition: certs.c:178
vl_api_dhcp_client_state_t state
Definition: dhcp.api:201
int ptls_load_bio_pem_objects(BIO *bio, const char *label, ptls_iovec_t *list, size_t list_max, size_t *nb_objects)
Definition: certs.c:102
int load_bio_private_key(ptls_context_t *ctx, const char *pk_data)
Definition: certs.c:192