blob: 9e06ec893f6ebdfdc1d6f54f2fa5e168c74b1db5 [file] [log] [blame]
David Benjamin443a1f62015-09-04 15:05:05 -04001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57/* ====================================================================
58 * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 6. Redistributions of any form whatsoever must retain the following
87 * acknowledgment:
88 * "This product includes software developed by the OpenSSL Project
89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90 *
91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102 * OF THE POSSIBILITY OF SUCH DAMAGE.
103 * ====================================================================
104 *
105 * This product includes cryptographic software written by Eric Young
106 * (eay@cryptsoft.com). This product includes software written by Tim
107 * Hudson (tjh@cryptsoft.com).
108 *
109 */
110
111#include <openssl/ssl.h>
112
113#include <errno.h>
114#include <string.h>
115
David Benjamin72279902015-10-17 22:15:37 -0400116#include <openssl/asn1.h>
David Benjamin443a1f62015-09-04 15:05:05 -0400117#include <openssl/bio.h>
118#include <openssl/err.h>
119#include <openssl/mem.h>
120#include <openssl/pem.h>
121#include <openssl/stack.h>
122#include <openssl/x509.h>
123
David Benjamin443a1f62015-09-04 15:05:05 -0400124#include "internal.h"
125
126
David Benjaminaf0739f2023-01-09 10:03:02 -0800127static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) {
David Benjamin443a1f62015-09-04 15:05:05 -0400128 return X509_NAME_cmp(*a, *b);
129}
130
David Benjamin4da5a942022-08-02 14:39:44 -0700131static int add_bio_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, BIO *bio,
132 bool allow_empty) {
David Benjamin955ef792022-06-13 13:16:43 -0400133 // This function historically sorted |out| after every addition and skipped
134 // duplicates. This implementation preserves that behavior, but only sorts at
135 // the end, to avoid a quadratic running time. Existing duplicates in |out|
136 // are preserved, but do not introduce new duplicates.
137 bssl::UniquePtr<STACK_OF(X509_NAME)> to_append(sk_X509_NAME_new(xname_cmp));
138 if (to_append == nullptr) {
139 return 0;
David Benjamin443a1f62015-09-04 15:05:05 -0400140 }
141
David Benjamin955ef792022-06-13 13:16:43 -0400142 // Temporarily switch the comparison function for |out|.
143 struct RestoreCmpFunc {
144 ~RestoreCmpFunc() { sk_X509_NAME_set_cmp_func(stack, old_cmp); }
145 STACK_OF(X509_NAME) *stack;
David Benjaminaf0739f2023-01-09 10:03:02 -0800146 int (*old_cmp)(const X509_NAME *const *, const X509_NAME *const *);
David Benjamin955ef792022-06-13 13:16:43 -0400147 };
148 RestoreCmpFunc restore = {out, sk_X509_NAME_set_cmp_func(out, xname_cmp)};
David Benjamin443a1f62015-09-04 15:05:05 -0400149
David Benjamin955ef792022-06-13 13:16:43 -0400150 sk_X509_NAME_sort(out);
David Benjamin4da5a942022-08-02 14:39:44 -0700151 bool first = true;
David Benjamin443a1f62015-09-04 15:05:05 -0400152 for (;;) {
David Benjamin955ef792022-06-13 13:16:43 -0400153 bssl::UniquePtr<X509> x509(
154 PEM_read_bio_X509(bio, nullptr, nullptr, nullptr));
155 if (x509 == nullptr) {
David Benjamin4da5a942022-08-02 14:39:44 -0700156 if (first && !allow_empty) {
157 return 0;
158 }
David Benjamin955ef792022-06-13 13:16:43 -0400159 // TODO(davidben): This ignores PEM syntax errors. It should only succeed
160 // on |PEM_R_NO_START_LINE|.
161 ERR_clear_error();
David Benjamin443a1f62015-09-04 15:05:05 -0400162 break;
163 }
David Benjamin4da5a942022-08-02 14:39:44 -0700164 first = false;
David Benjamin1eeb0b02016-09-27 01:20:31 -0400165
David Benjamin955ef792022-06-13 13:16:43 -0400166 X509_NAME *subject = X509_get_subject_name(x509.get());
167 // Skip if already present in |out|. Duplicates in |to_append| will be
168 // handled separately.
169 if (sk_X509_NAME_find(out, /*out_index=*/NULL, subject)) {
David Benjamin1eeb0b02016-09-27 01:20:31 -0400170 continue;
171 }
172
David Benjamin955ef792022-06-13 13:16:43 -0400173 bssl::UniquePtr<X509_NAME> copy(X509_NAME_dup(subject));
174 if (copy == nullptr ||
175 !bssl::PushToStack(to_append.get(), std::move(copy))) {
176 return 0;
David Benjamin443a1f62015-09-04 15:05:05 -0400177 }
178 }
179
David Benjamin955ef792022-06-13 13:16:43 -0400180 // Append |to_append| to |stack|, skipping any duplicates.
181 sk_X509_NAME_sort(to_append.get());
182 size_t num = sk_X509_NAME_num(to_append.get());
183 for (size_t i = 0; i < num; i++) {
184 bssl::UniquePtr<X509_NAME> name(sk_X509_NAME_value(to_append.get(), i));
185 sk_X509_NAME_set(to_append.get(), i, nullptr);
186 if (i + 1 < num &&
187 X509_NAME_cmp(name.get(), sk_X509_NAME_value(to_append.get(), i + 1)) ==
188 0) {
189 continue;
190 }
191 if (!bssl::PushToStack(out, std::move(name))) {
192 return 0;
193 }
194 }
David Benjamin443a1f62015-09-04 15:05:05 -0400195
David Benjamin955ef792022-06-13 13:16:43 -0400196 // Sort |out| one last time, to preserve the historical behavior of
197 // maintaining the sorted list.
198 sk_X509_NAME_sort(out);
199 return 1;
David Benjamin443a1f62015-09-04 15:05:05 -0400200}
201
David Benjamin4da5a942022-08-02 14:39:44 -0700202STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) {
203 bssl::UniquePtr<BIO> in(BIO_new_file(file, "r"));
204 if (in == nullptr) {
205 return nullptr;
206 }
207 bssl::UniquePtr<STACK_OF(X509_NAME)> ret(sk_X509_NAME_new_null());
208 if (ret == nullptr || //
209 !add_bio_cert_subjects_to_stack(ret.get(), in.get(),
210 /*allow_empty=*/false)) {
211 return nullptr;
212 }
213 return ret.release();
214}
215
216int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
217 const char *file) {
218 bssl::UniquePtr<BIO> in(BIO_new_file(file, "r"));
219 if (in == nullptr) {
220 return 0;
221 }
222 return SSL_add_bio_cert_subjects_to_stack(out, in.get());
223}
224
225int SSL_add_bio_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, BIO *bio) {
226 return add_bio_cert_subjects_to_stack(out, bio, /*allow_empty=*/true);
227}
228
David Benjamin443a1f62015-09-04 15:05:05 -0400229int SSL_use_certificate_file(SSL *ssl, const char *file, int type) {
230 int reason_code;
231 BIO *in;
232 int ret = 0;
233 X509 *x = NULL;
234
235 in = BIO_new(BIO_s_file());
236 if (in == NULL) {
237 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
238 goto end;
239 }
240
241 if (BIO_read_filename(in, file) <= 0) {
242 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
243 goto end;
244 }
245
246 if (type == SSL_FILETYPE_ASN1) {
247 reason_code = ERR_R_ASN1_LIB;
248 x = d2i_X509_bio(in, NULL);
249 } else if (type == SSL_FILETYPE_PEM) {
250 reason_code = ERR_R_PEM_LIB;
251 x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback,
252 ssl->ctx->default_passwd_callback_userdata);
253 } else {
254 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
255 goto end;
256 }
257
258 if (x == NULL) {
259 OPENSSL_PUT_ERROR(SSL, reason_code);
260 goto end;
261 }
262
263 ret = SSL_use_certificate(ssl, x);
264
265end:
266 X509_free(x);
267 BIO_free(in);
268
269 return ret;
270}
271
272int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) {
273 int reason_code, ret = 0;
274 BIO *in;
275 RSA *rsa = NULL;
276
277 in = BIO_new(BIO_s_file());
278 if (in == NULL) {
279 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
280 goto end;
281 }
282
283 if (BIO_read_filename(in, file) <= 0) {
284 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
285 goto end;
286 }
287
288 if (type == SSL_FILETYPE_ASN1) {
289 reason_code = ERR_R_ASN1_LIB;
290 rsa = d2i_RSAPrivateKey_bio(in, NULL);
291 } else if (type == SSL_FILETYPE_PEM) {
292 reason_code = ERR_R_PEM_LIB;
293 rsa =
294 PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
295 ssl->ctx->default_passwd_callback_userdata);
296 } else {
297 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
298 goto end;
299 }
300
301 if (rsa == NULL) {
302 OPENSSL_PUT_ERROR(SSL, reason_code);
303 goto end;
304 }
305 ret = SSL_use_RSAPrivateKey(ssl, rsa);
306 RSA_free(rsa);
307
308end:
309 BIO_free(in);
310 return ret;
311}
312
313int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) {
314 int reason_code, ret = 0;
315 BIO *in;
316 EVP_PKEY *pkey = NULL;
317
318 in = BIO_new(BIO_s_file());
319 if (in == NULL) {
320 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
321 goto end;
322 }
323
324 if (BIO_read_filename(in, file) <= 0) {
325 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
326 goto end;
327 }
328
329 if (type == SSL_FILETYPE_PEM) {
330 reason_code = ERR_R_PEM_LIB;
331 pkey = PEM_read_bio_PrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
332 ssl->ctx->default_passwd_callback_userdata);
333 } else if (type == SSL_FILETYPE_ASN1) {
334 reason_code = ERR_R_ASN1_LIB;
335 pkey = d2i_PrivateKey_bio(in, NULL);
336 } else {
337 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
338 goto end;
339 }
340
341 if (pkey == NULL) {
342 OPENSSL_PUT_ERROR(SSL, reason_code);
343 goto end;
344 }
345 ret = SSL_use_PrivateKey(ssl, pkey);
346 EVP_PKEY_free(pkey);
347
348end:
349 BIO_free(in);
350 return ret;
351}
352
353int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) {
354 int reason_code;
355 BIO *in;
356 int ret = 0;
357 X509 *x = NULL;
358
359 in = BIO_new(BIO_s_file());
360 if (in == NULL) {
361 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
362 goto end;
363 }
364
365 if (BIO_read_filename(in, file) <= 0) {
366 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
367 goto end;
368 }
369
370 if (type == SSL_FILETYPE_ASN1) {
371 reason_code = ERR_R_ASN1_LIB;
372 x = d2i_X509_bio(in, NULL);
373 } else if (type == SSL_FILETYPE_PEM) {
374 reason_code = ERR_R_PEM_LIB;
375 x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
376 ctx->default_passwd_callback_userdata);
377 } else {
378 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
379 goto end;
380 }
381
382 if (x == NULL) {
383 OPENSSL_PUT_ERROR(SSL, reason_code);
384 goto end;
385 }
386
387 ret = SSL_CTX_use_certificate(ctx, x);
388
389end:
390 X509_free(x);
391 BIO_free(in);
392 return ret;
393}
394
395int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
396 int reason_code, ret = 0;
397 BIO *in;
398 RSA *rsa = NULL;
399
400 in = BIO_new(BIO_s_file());
401 if (in == NULL) {
402 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
403 goto end;
404 }
405
406 if (BIO_read_filename(in, file) <= 0) {
407 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
408 goto end;
409 }
410
411 if (type == SSL_FILETYPE_ASN1) {
412 reason_code = ERR_R_ASN1_LIB;
413 rsa = d2i_RSAPrivateKey_bio(in, NULL);
414 } else if (type == SSL_FILETYPE_PEM) {
415 reason_code = ERR_R_PEM_LIB;
416 rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback,
417 ctx->default_passwd_callback_userdata);
418 } else {
419 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
420 goto end;
421 }
422
423 if (rsa == NULL) {
424 OPENSSL_PUT_ERROR(SSL, reason_code);
425 goto end;
426 }
427 ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
428 RSA_free(rsa);
429
430end:
431 BIO_free(in);
432 return ret;
433}
434
435int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
436 int reason_code, ret = 0;
437 BIO *in;
438 EVP_PKEY *pkey = NULL;
439
440 in = BIO_new(BIO_s_file());
441 if (in == NULL) {
442 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
443 goto end;
444 }
445
446 if (BIO_read_filename(in, file) <= 0) {
447 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
448 goto end;
449 }
450
451 if (type == SSL_FILETYPE_PEM) {
452 reason_code = ERR_R_PEM_LIB;
453 pkey = PEM_read_bio_PrivateKey(in, NULL, ctx->default_passwd_callback,
454 ctx->default_passwd_callback_userdata);
455 } else if (type == SSL_FILETYPE_ASN1) {
456 reason_code = ERR_R_ASN1_LIB;
457 pkey = d2i_PrivateKey_bio(in, NULL);
458 } else {
459 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
460 goto end;
461 }
462
463 if (pkey == NULL) {
464 OPENSSL_PUT_ERROR(SSL, reason_code);
465 goto end;
466 }
467 ret = SSL_CTX_use_PrivateKey(ctx, pkey);
468 EVP_PKEY_free(pkey);
469
470end:
471 BIO_free(in);
472 return ret;
473}
474
David Benjaminc11ea9422017-08-29 16:33:21 -0400475// Read a file that contains our certificate in "PEM" format, possibly followed
476// by a sequence of CA certificates that should be sent to the peer in the
477// Certificate message.
David Benjamin443a1f62015-09-04 15:05:05 -0400478int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) {
479 BIO *in;
480 int ret = 0;
481 X509 *x = NULL;
482
David Benjaminc11ea9422017-08-29 16:33:21 -0400483 ERR_clear_error(); // clear error stack for SSL_CTX_use_certificate()
David Benjamin443a1f62015-09-04 15:05:05 -0400484
485 in = BIO_new(BIO_s_file());
486 if (in == NULL) {
487 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
488 goto end;
489 }
490
491 if (BIO_read_filename(in, file) <= 0) {
492 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
493 goto end;
494 }
495
496 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
497 ctx->default_passwd_callback_userdata);
498 if (x == NULL) {
499 OPENSSL_PUT_ERROR(SSL, ERR_R_PEM_LIB);
500 goto end;
501 }
502
503 ret = SSL_CTX_use_certificate(ctx, x);
504
505 if (ERR_peek_error() != 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400506 ret = 0; // Key/certificate mismatch doesn't imply ret==0 ...
David Benjamin443a1f62015-09-04 15:05:05 -0400507 }
508
509 if (ret) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400510 // If we could set up our certificate, now proceed to the CA
511 // certificates.
David Benjamin443a1f62015-09-04 15:05:05 -0400512 X509 *ca;
513 int r;
514 uint32_t err;
515
516 SSL_CTX_clear_chain_certs(ctx);
517
518 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
519 ctx->default_passwd_callback_userdata)) !=
520 NULL) {
521 r = SSL_CTX_add0_chain_cert(ctx, ca);
522 if (!r) {
523 X509_free(ca);
524 ret = 0;
525 goto end;
526 }
David Benjaminc11ea9422017-08-29 16:33:21 -0400527 // Note that we must not free r if it was successfully added to the chain
528 // (while we must free the main certificate, since its reference count is
529 // increased by SSL_CTX_use_certificate).
David Benjamin443a1f62015-09-04 15:05:05 -0400530 }
531
David Benjaminc11ea9422017-08-29 16:33:21 -0400532 // When the while loop ends, it's usually just EOF.
David Benjamin443a1f62015-09-04 15:05:05 -0400533 err = ERR_peek_last_error();
534 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
535 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
536 ERR_clear_error();
537 } else {
David Benjaminc11ea9422017-08-29 16:33:21 -0400538 ret = 0; // some real error
David Benjamin443a1f62015-09-04 15:05:05 -0400539 }
540 }
541
542end:
543 X509_free(x);
544 BIO_free(in);
545 return ret;
546}
547
David Benjamin42fea372015-09-19 01:22:44 -0400548void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) {
549 ctx->default_passwd_callback = cb;
550}
551
David Benjamin81f030b2016-08-12 14:48:19 -0400552pem_password_cb *SSL_CTX_get_default_passwd_cb(const SSL_CTX *ctx) {
553 return ctx->default_passwd_callback;
554}
555
David Benjamin42fea372015-09-19 01:22:44 -0400556void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data) {
557 ctx->default_passwd_callback_userdata = data;
558}
David Benjamin81f030b2016-08-12 14:48:19 -0400559
560void *SSL_CTX_get_default_passwd_cb_userdata(const SSL_CTX *ctx) {
561 return ctx->default_passwd_callback_userdata;
562}