2 * Copyright (c) 2019 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include <openssl/pem.h>
18 #include <vppinfra/error.h>
20 #include <quic/certs.h>
24 ptls_compare_separator_line (const char *line, const char *begin_or_end,
27 int ret = strncmp (line, "-----", 5);
28 size_t text_index = 5;
32 size_t begin_or_end_length = strlen (begin_or_end);
33 ret = strncmp (line + text_index, begin_or_end, begin_or_end_length);
34 text_index += begin_or_end_length;
39 ret = line[text_index] - ' ';
45 size_t label_length = strlen (label);
46 ret = strncmp (line + text_index, label, label_length);
47 text_index += label_length;
52 ret = strncmp (line + text_index, "-----", 5);
59 ptls_get_bio_pem_object (BIO * bio, const char *label, ptls_buffer_t * buf)
61 int ret = PTLS_ERROR_PEM_LABEL_NOT_FOUND;
63 ptls_base64_decode_state_t state;
65 /* Get the label on a line by itself */
66 while (BIO_gets (bio, line, 256))
68 if (ptls_compare_separator_line (line, "BEGIN", label) == 0)
71 ptls_base64_decode_init (&state);
75 /* Get the data in the buffer */
76 while (ret == 0 && BIO_gets (bio, line, 256))
78 if (ptls_compare_separator_line (line, "END", label) == 0)
80 if (state.status == PTLS_BASE64_DECODE_DONE
81 || (state.status == PTLS_BASE64_DECODE_IN_PROGRESS
88 ret = PTLS_ERROR_INCORRECT_BASE64;
94 ret = ptls_base64_decode (line, &state, buf);
102 ptls_load_bio_pem_objects (BIO * bio, const char *label, ptls_iovec_t * list,
103 size_t list_max, size_t * nb_objects)
112 while (count < list_max)
116 ptls_buffer_init (&buf, "", 0);
118 ret = ptls_get_bio_pem_object (bio, label, &buf);
122 if (buf.off > 0 && buf.is_allocated)
124 list[count].base = buf.base;
125 list[count].len = buf.off;
130 ptls_buffer_dispose (&buf);
135 ptls_buffer_dispose (&buf);
141 if (ret == PTLS_ERROR_PEM_LABEL_NOT_FOUND && count > 0)
151 #define PTLS_MAX_CERTS_IN_CONTEXT 16
154 ptls_load_bio_certificates (ptls_context_t * ctx, BIO * bio)
158 ctx->certificates.list =
159 (ptls_iovec_t *) malloc (PTLS_MAX_CERTS_IN_CONTEXT *
160 sizeof (ptls_iovec_t));
162 if (ctx->certificates.list == NULL)
164 ret = PTLS_ERROR_NO_MEMORY;
169 ptls_load_bio_pem_objects (bio, "CERTIFICATE", ctx->certificates.list,
170 PTLS_MAX_CERTS_IN_CONTEXT,
171 &ctx->certificates.count);
178 load_bio_certificate_chain (ptls_context_t * ctx, const char *cert_data)
181 cert_bio = BIO_new_mem_buf (cert_data, -1);
182 if (ptls_load_bio_certificates (ctx, cert_bio) != 0)
192 load_bio_private_key (ptls_context_t * ctx, const char *pk_data)
194 static ptls_openssl_sign_certificate_t sc;
198 key_bio = BIO_new_mem_buf (pk_data, -1);
199 pkey = PEM_read_bio_PrivateKey (key_bio, NULL, NULL, NULL);
205 ptls_openssl_init_sign_certificate (&sc, pkey);
206 EVP_PKEY_free (pkey);
208 ctx->sign_certificate = &sc.super;