Line data Source code
1 : #include <openssl/pem.h>
2 : #include <vppinfra/error.h>
3 : #include "certs.h"
4 :
5 : int
6 0 : ptls_compare_separator_line (const char *line, const char *begin_or_end,
7 : const char *label)
8 : {
9 0 : int ret = strncmp (line, "-----", 5);
10 0 : size_t text_index = 5;
11 :
12 0 : if (ret == 0)
13 : {
14 0 : size_t begin_or_end_length = strlen (begin_or_end);
15 0 : ret = strncmp (line + text_index, begin_or_end, begin_or_end_length);
16 0 : text_index += begin_or_end_length;
17 : }
18 :
19 0 : if (ret == 0)
20 : {
21 0 : ret = line[text_index] - ' ';
22 0 : text_index++;
23 : }
24 :
25 0 : if (ret == 0)
26 : {
27 0 : size_t label_length = strlen (label);
28 0 : ret = strncmp (line + text_index, label, label_length);
29 0 : text_index += label_length;
30 : }
31 :
32 0 : if (ret == 0)
33 : {
34 0 : ret = strncmp (line + text_index, "-----", 5);
35 : }
36 :
37 0 : return ret;
38 : }
39 :
40 : int
41 0 : ptls_get_bio_pem_object (BIO * bio, const char *label, ptls_buffer_t * buf)
42 : {
43 0 : 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 0 : while (BIO_gets (bio, line, 256))
49 : {
50 0 : if (ptls_compare_separator_line (line, "BEGIN", label) == 0)
51 : {
52 0 : ret = 0;
53 0 : ptls_base64_decode_init (&state);
54 0 : break;
55 : }
56 : }
57 : /* Get the data in the buffer */
58 0 : while (ret == 0 && BIO_gets (bio, line, 256))
59 : {
60 0 : if (ptls_compare_separator_line (line, "END", label) == 0)
61 : {
62 0 : if (state.status == PTLS_BASE64_DECODE_DONE
63 0 : || (state.status == PTLS_BASE64_DECODE_IN_PROGRESS
64 0 : && state.nbc == 0))
65 : {
66 0 : ret = 0;
67 : }
68 : else
69 : {
70 0 : ret = PTLS_ERROR_INCORRECT_BASE64;
71 : }
72 0 : break;
73 : }
74 : else
75 : {
76 0 : ret = ptls_base64_decode (line, &state, buf);
77 : }
78 : }
79 :
80 0 : return ret;
81 : }
82 :
83 : int
84 0 : 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 0 : int ret = 0;
88 0 : size_t count = 0;
89 :
90 0 : *nb_objects = 0;
91 :
92 0 : if (ret == 0)
93 : {
94 0 : while (count < list_max)
95 : {
96 : ptls_buffer_t buf;
97 :
98 0 : ptls_buffer_init (&buf, "", 0);
99 :
100 0 : ret = ptls_get_bio_pem_object (bio, label, &buf);
101 :
102 0 : if (ret == 0)
103 : {
104 0 : if (buf.off > 0 && buf.is_allocated)
105 : {
106 0 : list[count].base = buf.base;
107 0 : list[count].len = buf.off;
108 0 : count++;
109 : }
110 : else
111 : {
112 0 : ptls_buffer_dispose (&buf);
113 : }
114 : }
115 : else
116 : {
117 0 : ptls_buffer_dispose (&buf);
118 0 : break;
119 : }
120 : }
121 : }
122 :
123 0 : if (ret == PTLS_ERROR_PEM_LABEL_NOT_FOUND && count > 0)
124 : {
125 0 : ret = 0;
126 : }
127 :
128 0 : *nb_objects = count;
129 :
130 0 : return ret;
131 : }
132 :
133 : #define PTLS_MAX_CERTS_IN_CONTEXT 16
134 :
135 : int
136 0 : ptls_load_bio_certificates (ptls_context_t * ctx, BIO * bio)
137 : {
138 0 : int ret = 0;
139 :
140 0 : ctx->certificates.list =
141 0 : (ptls_iovec_t *) malloc (PTLS_MAX_CERTS_IN_CONTEXT *
142 : sizeof (ptls_iovec_t));
143 :
144 0 : if (ctx->certificates.list == NULL)
145 : {
146 0 : ret = PTLS_ERROR_NO_MEMORY;
147 : }
148 : else
149 : {
150 : ret =
151 0 : ptls_load_bio_pem_objects (bio, "CERTIFICATE", ctx->certificates.list,
152 : PTLS_MAX_CERTS_IN_CONTEXT,
153 : &ctx->certificates.count);
154 : }
155 :
156 0 : return ret;
157 : }
158 :
159 : int
160 0 : load_bio_certificate_chain (ptls_context_t * ctx, const char *cert_data)
161 : {
162 : BIO *cert_bio;
163 0 : cert_bio = BIO_new_mem_buf (cert_data, -1);
164 0 : if (ptls_load_bio_certificates (ctx, cert_bio) != 0)
165 : {
166 0 : BIO_free (cert_bio);
167 0 : return -1;
168 : }
169 0 : BIO_free (cert_bio);
170 0 : return 0;
171 : }
172 :
173 : int
174 0 : 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 0 : key_bio = BIO_new_mem_buf (pk_data, -1);
181 0 : pkey = PEM_read_bio_PrivateKey (key_bio, NULL, NULL, NULL);
182 0 : BIO_free (key_bio);
183 :
184 0 : if (pkey == NULL)
185 0 : return -1;
186 :
187 0 : ptls_openssl_init_sign_certificate (&sc, pkey);
188 0 : EVP_PKEY_free (pkey);
189 :
190 0 : ctx->sign_certificate = &sc.super;
191 0 : 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 : */
|