1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include <stdio.h>
11e1051a39Sopenharmony_ci#include "ssl_local.h"
12e1051a39Sopenharmony_ci#include "internal/packet.h"
13e1051a39Sopenharmony_ci#include <openssl/bio.h>
14e1051a39Sopenharmony_ci#include <openssl/objects.h>
15e1051a39Sopenharmony_ci#include <openssl/evp.h>
16e1051a39Sopenharmony_ci#include <openssl/x509.h>
17e1051a39Sopenharmony_ci#include <openssl/x509v3.h>
18e1051a39Sopenharmony_ci#include <openssl/pem.h>
19e1051a39Sopenharmony_ci
20e1051a39Sopenharmony_cistatic int ssl_set_cert(CERT *c, X509 *x509);
21e1051a39Sopenharmony_cistatic int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_ci#define  SYNTHV1CONTEXT     (SSL_EXT_TLS1_2_AND_BELOW_ONLY \
24e1051a39Sopenharmony_ci                             | SSL_EXT_CLIENT_HELLO \
25e1051a39Sopenharmony_ci                             | SSL_EXT_TLS1_2_SERVER_HELLO \
26e1051a39Sopenharmony_ci                             | SSL_EXT_IGNORE_ON_RESUMPTION)
27e1051a39Sopenharmony_ci
28e1051a39Sopenharmony_ciint SSL_use_certificate(SSL *ssl, X509 *x)
29e1051a39Sopenharmony_ci{
30e1051a39Sopenharmony_ci    int rv;
31e1051a39Sopenharmony_ci    if (x == NULL) {
32e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
33e1051a39Sopenharmony_ci        return 0;
34e1051a39Sopenharmony_ci    }
35e1051a39Sopenharmony_ci
36e1051a39Sopenharmony_ci    rv = ssl_security_cert(ssl, NULL, x, 0, 1);
37e1051a39Sopenharmony_ci    if (rv != 1) {
38e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, rv);
39e1051a39Sopenharmony_ci        return 0;
40e1051a39Sopenharmony_ci    }
41e1051a39Sopenharmony_ci
42e1051a39Sopenharmony_ci    return ssl_set_cert(ssl->cert, x);
43e1051a39Sopenharmony_ci}
44e1051a39Sopenharmony_ci
45e1051a39Sopenharmony_ciint SSL_use_certificate_file(SSL *ssl, const char *file, int type)
46e1051a39Sopenharmony_ci{
47e1051a39Sopenharmony_ci    int j;
48e1051a39Sopenharmony_ci    BIO *in;
49e1051a39Sopenharmony_ci    int ret = 0;
50e1051a39Sopenharmony_ci    X509 *cert = NULL, *x = NULL;
51e1051a39Sopenharmony_ci
52e1051a39Sopenharmony_ci    in = BIO_new(BIO_s_file());
53e1051a39Sopenharmony_ci    if (in == NULL) {
54e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
55e1051a39Sopenharmony_ci        goto end;
56e1051a39Sopenharmony_ci    }
57e1051a39Sopenharmony_ci
58e1051a39Sopenharmony_ci    if (BIO_read_filename(in, file) <= 0) {
59e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB);
60e1051a39Sopenharmony_ci        goto end;
61e1051a39Sopenharmony_ci    }
62e1051a39Sopenharmony_ci
63e1051a39Sopenharmony_ci    if (type != SSL_FILETYPE_ASN1 && type != SSL_FILETYPE_PEM) {
64e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE);
65e1051a39Sopenharmony_ci        goto end;
66e1051a39Sopenharmony_ci    }
67e1051a39Sopenharmony_ci    x = X509_new_ex(ssl->ctx->libctx, ssl->ctx->propq);
68e1051a39Sopenharmony_ci    if (x == NULL) {
69e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
70e1051a39Sopenharmony_ci        goto end;
71e1051a39Sopenharmony_ci    }
72e1051a39Sopenharmony_ci    if (type == SSL_FILETYPE_ASN1) {
73e1051a39Sopenharmony_ci        j = ERR_R_ASN1_LIB;
74e1051a39Sopenharmony_ci        cert = d2i_X509_bio(in, &x);
75e1051a39Sopenharmony_ci    } else if (type == SSL_FILETYPE_PEM) {
76e1051a39Sopenharmony_ci        j = ERR_R_PEM_LIB;
77e1051a39Sopenharmony_ci        cert = PEM_read_bio_X509(in, &x, ssl->default_passwd_callback,
78e1051a39Sopenharmony_ci                                 ssl->default_passwd_callback_userdata);
79e1051a39Sopenharmony_ci    } else {
80e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE);
81e1051a39Sopenharmony_ci        goto end;
82e1051a39Sopenharmony_ci    }
83e1051a39Sopenharmony_ci
84e1051a39Sopenharmony_ci    if (cert == NULL) {
85e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, j);
86e1051a39Sopenharmony_ci        goto end;
87e1051a39Sopenharmony_ci    }
88e1051a39Sopenharmony_ci
89e1051a39Sopenharmony_ci    ret = SSL_use_certificate(ssl, x);
90e1051a39Sopenharmony_ci end:
91e1051a39Sopenharmony_ci    X509_free(x);
92e1051a39Sopenharmony_ci    BIO_free(in);
93e1051a39Sopenharmony_ci    return ret;
94e1051a39Sopenharmony_ci}
95e1051a39Sopenharmony_ci
96e1051a39Sopenharmony_ciint SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
97e1051a39Sopenharmony_ci{
98e1051a39Sopenharmony_ci    X509 *x;
99e1051a39Sopenharmony_ci    int ret;
100e1051a39Sopenharmony_ci
101e1051a39Sopenharmony_ci    x = X509_new_ex(ssl->ctx->libctx, ssl->ctx->propq);
102e1051a39Sopenharmony_ci    if (x == NULL) {
103e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
104e1051a39Sopenharmony_ci        return 0;
105e1051a39Sopenharmony_ci    }
106e1051a39Sopenharmony_ci
107e1051a39Sopenharmony_ci    if (d2i_X509(&x, &d, (long)len)== NULL) {
108e1051a39Sopenharmony_ci        X509_free(x);
109e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB);
110e1051a39Sopenharmony_ci        return 0;
111e1051a39Sopenharmony_ci    }
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_ci    ret = SSL_use_certificate(ssl, x);
114e1051a39Sopenharmony_ci    X509_free(x);
115e1051a39Sopenharmony_ci    return ret;
116e1051a39Sopenharmony_ci}
117e1051a39Sopenharmony_ci
118e1051a39Sopenharmony_cistatic int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
119e1051a39Sopenharmony_ci{
120e1051a39Sopenharmony_ci    size_t i;
121e1051a39Sopenharmony_ci
122e1051a39Sopenharmony_ci    if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) {
123e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
124e1051a39Sopenharmony_ci        return 0;
125e1051a39Sopenharmony_ci    }
126e1051a39Sopenharmony_ci
127e1051a39Sopenharmony_ci    if (c->pkeys[i].x509 != NULL
128e1051a39Sopenharmony_ci            && !X509_check_private_key(c->pkeys[i].x509, pkey))
129e1051a39Sopenharmony_ci        return 0;
130e1051a39Sopenharmony_ci
131e1051a39Sopenharmony_ci    EVP_PKEY_free(c->pkeys[i].privatekey);
132e1051a39Sopenharmony_ci    EVP_PKEY_up_ref(pkey);
133e1051a39Sopenharmony_ci    c->pkeys[i].privatekey = pkey;
134e1051a39Sopenharmony_ci    c->key = &c->pkeys[i];
135e1051a39Sopenharmony_ci    return 1;
136e1051a39Sopenharmony_ci}
137e1051a39Sopenharmony_ci
138e1051a39Sopenharmony_ciint SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
139e1051a39Sopenharmony_ci{
140e1051a39Sopenharmony_ci    int ret;
141e1051a39Sopenharmony_ci
142e1051a39Sopenharmony_ci    if (pkey == NULL) {
143e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
144e1051a39Sopenharmony_ci        return 0;
145e1051a39Sopenharmony_ci    }
146e1051a39Sopenharmony_ci    ret = ssl_set_pkey(ssl->cert, pkey);
147e1051a39Sopenharmony_ci    return ret;
148e1051a39Sopenharmony_ci}
149e1051a39Sopenharmony_ci
150e1051a39Sopenharmony_ciint SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
151e1051a39Sopenharmony_ci{
152e1051a39Sopenharmony_ci    int j, ret = 0;
153e1051a39Sopenharmony_ci    BIO *in;
154e1051a39Sopenharmony_ci    EVP_PKEY *pkey = NULL;
155e1051a39Sopenharmony_ci
156e1051a39Sopenharmony_ci    in = BIO_new(BIO_s_file());
157e1051a39Sopenharmony_ci    if (in == NULL) {
158e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
159e1051a39Sopenharmony_ci        goto end;
160e1051a39Sopenharmony_ci    }
161e1051a39Sopenharmony_ci
162e1051a39Sopenharmony_ci    if (BIO_read_filename(in, file) <= 0) {
163e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB);
164e1051a39Sopenharmony_ci        goto end;
165e1051a39Sopenharmony_ci    }
166e1051a39Sopenharmony_ci    if (type == SSL_FILETYPE_PEM) {
167e1051a39Sopenharmony_ci        j = ERR_R_PEM_LIB;
168e1051a39Sopenharmony_ci        pkey = PEM_read_bio_PrivateKey_ex(in, NULL,
169e1051a39Sopenharmony_ci                                          ssl->default_passwd_callback,
170e1051a39Sopenharmony_ci                                          ssl->default_passwd_callback_userdata,
171e1051a39Sopenharmony_ci                                          ssl->ctx->libctx,
172e1051a39Sopenharmony_ci                                          ssl->ctx->propq);
173e1051a39Sopenharmony_ci    } else if (type == SSL_FILETYPE_ASN1) {
174e1051a39Sopenharmony_ci        j = ERR_R_ASN1_LIB;
175e1051a39Sopenharmony_ci        pkey = d2i_PrivateKey_ex_bio(in, NULL, ssl->ctx->libctx,
176e1051a39Sopenharmony_ci                                     ssl->ctx->propq);
177e1051a39Sopenharmony_ci    } else {
178e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE);
179e1051a39Sopenharmony_ci        goto end;
180e1051a39Sopenharmony_ci    }
181e1051a39Sopenharmony_ci    if (pkey == NULL) {
182e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, j);
183e1051a39Sopenharmony_ci        goto end;
184e1051a39Sopenharmony_ci    }
185e1051a39Sopenharmony_ci    ret = SSL_use_PrivateKey(ssl, pkey);
186e1051a39Sopenharmony_ci    EVP_PKEY_free(pkey);
187e1051a39Sopenharmony_ci end:
188e1051a39Sopenharmony_ci    BIO_free(in);
189e1051a39Sopenharmony_ci    return ret;
190e1051a39Sopenharmony_ci}
191e1051a39Sopenharmony_ci
192e1051a39Sopenharmony_ciint SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d,
193e1051a39Sopenharmony_ci                            long len)
194e1051a39Sopenharmony_ci{
195e1051a39Sopenharmony_ci    int ret;
196e1051a39Sopenharmony_ci    const unsigned char *p;
197e1051a39Sopenharmony_ci    EVP_PKEY *pkey;
198e1051a39Sopenharmony_ci
199e1051a39Sopenharmony_ci    p = d;
200e1051a39Sopenharmony_ci    if ((pkey = d2i_PrivateKey_ex(type, NULL, &p, (long)len, ssl->ctx->libctx,
201e1051a39Sopenharmony_ci                                  ssl->ctx->propq)) == NULL) {
202e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB);
203e1051a39Sopenharmony_ci        return 0;
204e1051a39Sopenharmony_ci    }
205e1051a39Sopenharmony_ci
206e1051a39Sopenharmony_ci    ret = SSL_use_PrivateKey(ssl, pkey);
207e1051a39Sopenharmony_ci    EVP_PKEY_free(pkey);
208e1051a39Sopenharmony_ci    return ret;
209e1051a39Sopenharmony_ci}
210e1051a39Sopenharmony_ci
211e1051a39Sopenharmony_ciint SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
212e1051a39Sopenharmony_ci{
213e1051a39Sopenharmony_ci    int rv;
214e1051a39Sopenharmony_ci    if (x == NULL) {
215e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
216e1051a39Sopenharmony_ci        return 0;
217e1051a39Sopenharmony_ci    }
218e1051a39Sopenharmony_ci
219e1051a39Sopenharmony_ci    rv = ssl_security_cert(NULL, ctx, x, 0, 1);
220e1051a39Sopenharmony_ci    if (rv != 1) {
221e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, rv);
222e1051a39Sopenharmony_ci        return 0;
223e1051a39Sopenharmony_ci    }
224e1051a39Sopenharmony_ci    return ssl_set_cert(ctx->cert, x);
225e1051a39Sopenharmony_ci}
226e1051a39Sopenharmony_ci
227e1051a39Sopenharmony_cistatic int ssl_set_cert(CERT *c, X509 *x)
228e1051a39Sopenharmony_ci{
229e1051a39Sopenharmony_ci    EVP_PKEY *pkey;
230e1051a39Sopenharmony_ci    size_t i;
231e1051a39Sopenharmony_ci
232e1051a39Sopenharmony_ci    pkey = X509_get0_pubkey(x);
233e1051a39Sopenharmony_ci    if (pkey == NULL) {
234e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_X509_LIB);
235e1051a39Sopenharmony_ci        return 0;
236e1051a39Sopenharmony_ci    }
237e1051a39Sopenharmony_ci
238e1051a39Sopenharmony_ci    if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) {
239e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
240e1051a39Sopenharmony_ci        return 0;
241e1051a39Sopenharmony_ci    }
242e1051a39Sopenharmony_ci
243e1051a39Sopenharmony_ci    if (i == SSL_PKEY_ECC && !EVP_PKEY_can_sign(pkey)) {
244e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
245e1051a39Sopenharmony_ci        return 0;
246e1051a39Sopenharmony_ci    }
247e1051a39Sopenharmony_ci
248e1051a39Sopenharmony_ci    if (c->pkeys[i].privatekey != NULL) {
249e1051a39Sopenharmony_ci        /*
250e1051a39Sopenharmony_ci         * The return code from EVP_PKEY_copy_parameters is deliberately
251e1051a39Sopenharmony_ci         * ignored. Some EVP_PKEY types cannot do this.
252e1051a39Sopenharmony_ci         */
253e1051a39Sopenharmony_ci        EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
254e1051a39Sopenharmony_ci        ERR_clear_error();
255e1051a39Sopenharmony_ci
256e1051a39Sopenharmony_ci        if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
257e1051a39Sopenharmony_ci            /*
258e1051a39Sopenharmony_ci             * don't fail for a cert/key mismatch, just free current private
259e1051a39Sopenharmony_ci             * key (when switching to a different cert & key, first this
260e1051a39Sopenharmony_ci             * function should be used, then ssl_set_pkey
261e1051a39Sopenharmony_ci             */
262e1051a39Sopenharmony_ci            EVP_PKEY_free(c->pkeys[i].privatekey);
263e1051a39Sopenharmony_ci            c->pkeys[i].privatekey = NULL;
264e1051a39Sopenharmony_ci            /* clear error queue */
265e1051a39Sopenharmony_ci            ERR_clear_error();
266e1051a39Sopenharmony_ci        }
267e1051a39Sopenharmony_ci    }
268e1051a39Sopenharmony_ci
269e1051a39Sopenharmony_ci    X509_free(c->pkeys[i].x509);
270e1051a39Sopenharmony_ci    X509_up_ref(x);
271e1051a39Sopenharmony_ci    c->pkeys[i].x509 = x;
272e1051a39Sopenharmony_ci    c->key = &(c->pkeys[i]);
273e1051a39Sopenharmony_ci
274e1051a39Sopenharmony_ci    return 1;
275e1051a39Sopenharmony_ci}
276e1051a39Sopenharmony_ci
277e1051a39Sopenharmony_ciint SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
278e1051a39Sopenharmony_ci{
279e1051a39Sopenharmony_ci    int j = SSL_R_BAD_VALUE;
280e1051a39Sopenharmony_ci    BIO *in;
281e1051a39Sopenharmony_ci    int ret = 0;
282e1051a39Sopenharmony_ci    X509 *x = NULL, *cert = NULL;
283e1051a39Sopenharmony_ci
284e1051a39Sopenharmony_ci    in = BIO_new(BIO_s_file());
285e1051a39Sopenharmony_ci    if (in == NULL) {
286e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
287e1051a39Sopenharmony_ci        goto end;
288e1051a39Sopenharmony_ci    }
289e1051a39Sopenharmony_ci
290e1051a39Sopenharmony_ci    if (BIO_read_filename(in, file) <= 0) {
291e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB);
292e1051a39Sopenharmony_ci        goto end;
293e1051a39Sopenharmony_ci    }
294e1051a39Sopenharmony_ci    if (type != SSL_FILETYPE_ASN1 && type != SSL_FILETYPE_PEM) {
295e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE);
296e1051a39Sopenharmony_ci        goto end;
297e1051a39Sopenharmony_ci    }
298e1051a39Sopenharmony_ci    x = X509_new_ex(ctx->libctx, ctx->propq);
299e1051a39Sopenharmony_ci    if (x == NULL) {
300e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
301e1051a39Sopenharmony_ci        goto end;
302e1051a39Sopenharmony_ci    }
303e1051a39Sopenharmony_ci    if (type == SSL_FILETYPE_ASN1) {
304e1051a39Sopenharmony_ci        j = ERR_R_ASN1_LIB;
305e1051a39Sopenharmony_ci        cert = d2i_X509_bio(in, &x);
306e1051a39Sopenharmony_ci    } else if (type == SSL_FILETYPE_PEM) {
307e1051a39Sopenharmony_ci        j = ERR_R_PEM_LIB;
308e1051a39Sopenharmony_ci        cert = PEM_read_bio_X509(in, &x, ctx->default_passwd_callback,
309e1051a39Sopenharmony_ci                                 ctx->default_passwd_callback_userdata);
310e1051a39Sopenharmony_ci    }
311e1051a39Sopenharmony_ci    if (cert == NULL) {
312e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, j);
313e1051a39Sopenharmony_ci        goto end;
314e1051a39Sopenharmony_ci    }
315e1051a39Sopenharmony_ci
316e1051a39Sopenharmony_ci    ret = SSL_CTX_use_certificate(ctx, x);
317e1051a39Sopenharmony_ci end:
318e1051a39Sopenharmony_ci    X509_free(x);
319e1051a39Sopenharmony_ci    BIO_free(in);
320e1051a39Sopenharmony_ci    return ret;
321e1051a39Sopenharmony_ci}
322e1051a39Sopenharmony_ci
323e1051a39Sopenharmony_ciint SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
324e1051a39Sopenharmony_ci{
325e1051a39Sopenharmony_ci    X509 *x;
326e1051a39Sopenharmony_ci    int ret;
327e1051a39Sopenharmony_ci
328e1051a39Sopenharmony_ci    x = X509_new_ex(ctx->libctx, ctx->propq);
329e1051a39Sopenharmony_ci    if (x == NULL) {
330e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
331e1051a39Sopenharmony_ci        return 0;
332e1051a39Sopenharmony_ci    }
333e1051a39Sopenharmony_ci
334e1051a39Sopenharmony_ci    if (d2i_X509(&x, &d, (long)len) == NULL) {
335e1051a39Sopenharmony_ci        X509_free(x);
336e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB);
337e1051a39Sopenharmony_ci        return 0;
338e1051a39Sopenharmony_ci    }
339e1051a39Sopenharmony_ci
340e1051a39Sopenharmony_ci    ret = SSL_CTX_use_certificate(ctx, x);
341e1051a39Sopenharmony_ci    X509_free(x);
342e1051a39Sopenharmony_ci    return ret;
343e1051a39Sopenharmony_ci}
344e1051a39Sopenharmony_ci
345e1051a39Sopenharmony_ciint SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
346e1051a39Sopenharmony_ci{
347e1051a39Sopenharmony_ci    if (pkey == NULL) {
348e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
349e1051a39Sopenharmony_ci        return 0;
350e1051a39Sopenharmony_ci    }
351e1051a39Sopenharmony_ci    return ssl_set_pkey(ctx->cert, pkey);
352e1051a39Sopenharmony_ci}
353e1051a39Sopenharmony_ci
354e1051a39Sopenharmony_ciint SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
355e1051a39Sopenharmony_ci{
356e1051a39Sopenharmony_ci    int j, ret = 0;
357e1051a39Sopenharmony_ci    BIO *in;
358e1051a39Sopenharmony_ci    EVP_PKEY *pkey = NULL;
359e1051a39Sopenharmony_ci
360e1051a39Sopenharmony_ci    in = BIO_new(BIO_s_file());
361e1051a39Sopenharmony_ci    if (in == NULL) {
362e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
363e1051a39Sopenharmony_ci        goto end;
364e1051a39Sopenharmony_ci    }
365e1051a39Sopenharmony_ci
366e1051a39Sopenharmony_ci    if (BIO_read_filename(in, file) <= 0) {
367e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB);
368e1051a39Sopenharmony_ci        goto end;
369e1051a39Sopenharmony_ci    }
370e1051a39Sopenharmony_ci    if (type == SSL_FILETYPE_PEM) {
371e1051a39Sopenharmony_ci        j = ERR_R_PEM_LIB;
372e1051a39Sopenharmony_ci        pkey = PEM_read_bio_PrivateKey_ex(in, NULL,
373e1051a39Sopenharmony_ci                                       ctx->default_passwd_callback,
374e1051a39Sopenharmony_ci                                       ctx->default_passwd_callback_userdata,
375e1051a39Sopenharmony_ci                                       ctx->libctx, ctx->propq);
376e1051a39Sopenharmony_ci    } else if (type == SSL_FILETYPE_ASN1) {
377e1051a39Sopenharmony_ci        j = ERR_R_ASN1_LIB;
378e1051a39Sopenharmony_ci        pkey = d2i_PrivateKey_ex_bio(in, NULL, ctx->libctx, ctx->propq);
379e1051a39Sopenharmony_ci    } else {
380e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE);
381e1051a39Sopenharmony_ci        goto end;
382e1051a39Sopenharmony_ci    }
383e1051a39Sopenharmony_ci    if (pkey == NULL) {
384e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, j);
385e1051a39Sopenharmony_ci        goto end;
386e1051a39Sopenharmony_ci    }
387e1051a39Sopenharmony_ci    ret = SSL_CTX_use_PrivateKey(ctx, pkey);
388e1051a39Sopenharmony_ci    EVP_PKEY_free(pkey);
389e1051a39Sopenharmony_ci end:
390e1051a39Sopenharmony_ci    BIO_free(in);
391e1051a39Sopenharmony_ci    return ret;
392e1051a39Sopenharmony_ci}
393e1051a39Sopenharmony_ci
394e1051a39Sopenharmony_ciint SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
395e1051a39Sopenharmony_ci                                const unsigned char *d, long len)
396e1051a39Sopenharmony_ci{
397e1051a39Sopenharmony_ci    int ret;
398e1051a39Sopenharmony_ci    const unsigned char *p;
399e1051a39Sopenharmony_ci    EVP_PKEY *pkey;
400e1051a39Sopenharmony_ci
401e1051a39Sopenharmony_ci    p = d;
402e1051a39Sopenharmony_ci    if ((pkey = d2i_PrivateKey_ex(type, NULL, &p, (long)len, ctx->libctx,
403e1051a39Sopenharmony_ci                                  ctx->propq)) == NULL) {
404e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB);
405e1051a39Sopenharmony_ci        return 0;
406e1051a39Sopenharmony_ci    }
407e1051a39Sopenharmony_ci
408e1051a39Sopenharmony_ci    ret = SSL_CTX_use_PrivateKey(ctx, pkey);
409e1051a39Sopenharmony_ci    EVP_PKEY_free(pkey);
410e1051a39Sopenharmony_ci    return ret;
411e1051a39Sopenharmony_ci}
412e1051a39Sopenharmony_ci
413e1051a39Sopenharmony_ci/*
414e1051a39Sopenharmony_ci * Read a file that contains our certificate in "PEM" format, possibly
415e1051a39Sopenharmony_ci * followed by a sequence of CA certificates that should be sent to the peer
416e1051a39Sopenharmony_ci * in the Certificate message.
417e1051a39Sopenharmony_ci */
418e1051a39Sopenharmony_cistatic int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file)
419e1051a39Sopenharmony_ci{
420e1051a39Sopenharmony_ci    BIO *in;
421e1051a39Sopenharmony_ci    int ret = 0;
422e1051a39Sopenharmony_ci    X509 *x = NULL;
423e1051a39Sopenharmony_ci    pem_password_cb *passwd_callback;
424e1051a39Sopenharmony_ci    void *passwd_callback_userdata;
425e1051a39Sopenharmony_ci    SSL_CTX *real_ctx = (ssl == NULL) ? ctx : ssl->ctx;
426e1051a39Sopenharmony_ci
427e1051a39Sopenharmony_ci    if (ctx == NULL && ssl == NULL)
428e1051a39Sopenharmony_ci        return 0;
429e1051a39Sopenharmony_ci
430e1051a39Sopenharmony_ci    ERR_clear_error();          /* clear error stack for
431e1051a39Sopenharmony_ci                                 * SSL_CTX_use_certificate() */
432e1051a39Sopenharmony_ci
433e1051a39Sopenharmony_ci    if (ctx != NULL) {
434e1051a39Sopenharmony_ci        passwd_callback = ctx->default_passwd_callback;
435e1051a39Sopenharmony_ci        passwd_callback_userdata = ctx->default_passwd_callback_userdata;
436e1051a39Sopenharmony_ci    } else {
437e1051a39Sopenharmony_ci        passwd_callback = ssl->default_passwd_callback;
438e1051a39Sopenharmony_ci        passwd_callback_userdata = ssl->default_passwd_callback_userdata;
439e1051a39Sopenharmony_ci    }
440e1051a39Sopenharmony_ci
441e1051a39Sopenharmony_ci    in = BIO_new(BIO_s_file());
442e1051a39Sopenharmony_ci    if (in == NULL) {
443e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
444e1051a39Sopenharmony_ci        goto end;
445e1051a39Sopenharmony_ci    }
446e1051a39Sopenharmony_ci
447e1051a39Sopenharmony_ci    if (BIO_read_filename(in, file) <= 0) {
448e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB);
449e1051a39Sopenharmony_ci        goto end;
450e1051a39Sopenharmony_ci    }
451e1051a39Sopenharmony_ci
452e1051a39Sopenharmony_ci    x = X509_new_ex(real_ctx->libctx, real_ctx->propq);
453e1051a39Sopenharmony_ci    if (x == NULL) {
454e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
455e1051a39Sopenharmony_ci        goto end;
456e1051a39Sopenharmony_ci    }
457e1051a39Sopenharmony_ci    if (PEM_read_bio_X509_AUX(in, &x, passwd_callback,
458e1051a39Sopenharmony_ci                              passwd_callback_userdata) == NULL) {
459e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_PEM_LIB);
460e1051a39Sopenharmony_ci        goto end;
461e1051a39Sopenharmony_ci    }
462e1051a39Sopenharmony_ci
463e1051a39Sopenharmony_ci    if (ctx)
464e1051a39Sopenharmony_ci        ret = SSL_CTX_use_certificate(ctx, x);
465e1051a39Sopenharmony_ci    else
466e1051a39Sopenharmony_ci        ret = SSL_use_certificate(ssl, x);
467e1051a39Sopenharmony_ci
468e1051a39Sopenharmony_ci    if (ERR_peek_error() != 0)
469e1051a39Sopenharmony_ci        ret = 0;                /* Key/certificate mismatch doesn't imply
470e1051a39Sopenharmony_ci                                 * ret==0 ... */
471e1051a39Sopenharmony_ci    if (ret) {
472e1051a39Sopenharmony_ci        /*
473e1051a39Sopenharmony_ci         * If we could set up our certificate, now proceed to the CA
474e1051a39Sopenharmony_ci         * certificates.
475e1051a39Sopenharmony_ci         */
476e1051a39Sopenharmony_ci        X509 *ca;
477e1051a39Sopenharmony_ci        int r;
478e1051a39Sopenharmony_ci        unsigned long err;
479e1051a39Sopenharmony_ci
480e1051a39Sopenharmony_ci        if (ctx)
481e1051a39Sopenharmony_ci            r = SSL_CTX_clear_chain_certs(ctx);
482e1051a39Sopenharmony_ci        else
483e1051a39Sopenharmony_ci            r = SSL_clear_chain_certs(ssl);
484e1051a39Sopenharmony_ci
485e1051a39Sopenharmony_ci        if (r == 0) {
486e1051a39Sopenharmony_ci            ret = 0;
487e1051a39Sopenharmony_ci            goto end;
488e1051a39Sopenharmony_ci        }
489e1051a39Sopenharmony_ci
490e1051a39Sopenharmony_ci        while (1) {
491e1051a39Sopenharmony_ci            ca = X509_new_ex(real_ctx->libctx, real_ctx->propq);
492e1051a39Sopenharmony_ci            if (ca == NULL) {
493e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
494e1051a39Sopenharmony_ci                goto end;
495e1051a39Sopenharmony_ci            }
496e1051a39Sopenharmony_ci            if (PEM_read_bio_X509(in, &ca, passwd_callback,
497e1051a39Sopenharmony_ci                                  passwd_callback_userdata) != NULL) {
498e1051a39Sopenharmony_ci                if (ctx)
499e1051a39Sopenharmony_ci                    r = SSL_CTX_add0_chain_cert(ctx, ca);
500e1051a39Sopenharmony_ci                else
501e1051a39Sopenharmony_ci                    r = SSL_add0_chain_cert(ssl, ca);
502e1051a39Sopenharmony_ci                /*
503e1051a39Sopenharmony_ci                 * Note that we must not free ca if it was successfully added to
504e1051a39Sopenharmony_ci                 * the chain (while we must free the main certificate, since its
505e1051a39Sopenharmony_ci                 * reference count is increased by SSL_CTX_use_certificate).
506e1051a39Sopenharmony_ci                 */
507e1051a39Sopenharmony_ci                if (!r) {
508e1051a39Sopenharmony_ci                    X509_free(ca);
509e1051a39Sopenharmony_ci                    ret = 0;
510e1051a39Sopenharmony_ci                    goto end;
511e1051a39Sopenharmony_ci                }
512e1051a39Sopenharmony_ci            } else {
513e1051a39Sopenharmony_ci                X509_free(ca);
514e1051a39Sopenharmony_ci                break;
515e1051a39Sopenharmony_ci            }
516e1051a39Sopenharmony_ci        }
517e1051a39Sopenharmony_ci        /* When the while loop ends, it's usually just EOF. */
518e1051a39Sopenharmony_ci        err = ERR_peek_last_error();
519e1051a39Sopenharmony_ci        if (ERR_GET_LIB(err) == ERR_LIB_PEM
520e1051a39Sopenharmony_ci            && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
521e1051a39Sopenharmony_ci            ERR_clear_error();
522e1051a39Sopenharmony_ci        else
523e1051a39Sopenharmony_ci            ret = 0;            /* some real error */
524e1051a39Sopenharmony_ci    }
525e1051a39Sopenharmony_ci
526e1051a39Sopenharmony_ci end:
527e1051a39Sopenharmony_ci    X509_free(x);
528e1051a39Sopenharmony_ci    BIO_free(in);
529e1051a39Sopenharmony_ci    return ret;
530e1051a39Sopenharmony_ci}
531e1051a39Sopenharmony_ci
532e1051a39Sopenharmony_ciint SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
533e1051a39Sopenharmony_ci{
534e1051a39Sopenharmony_ci    return use_certificate_chain_file(ctx, NULL, file);
535e1051a39Sopenharmony_ci}
536e1051a39Sopenharmony_ci
537e1051a39Sopenharmony_ciint SSL_use_certificate_chain_file(SSL *ssl, const char *file)
538e1051a39Sopenharmony_ci{
539e1051a39Sopenharmony_ci    return use_certificate_chain_file(NULL, ssl, file);
540e1051a39Sopenharmony_ci}
541e1051a39Sopenharmony_ci
542e1051a39Sopenharmony_cistatic int serverinfo_find_extension(const unsigned char *serverinfo,
543e1051a39Sopenharmony_ci                                     size_t serverinfo_length,
544e1051a39Sopenharmony_ci                                     unsigned int extension_type,
545e1051a39Sopenharmony_ci                                     const unsigned char **extension_data,
546e1051a39Sopenharmony_ci                                     size_t *extension_length)
547e1051a39Sopenharmony_ci{
548e1051a39Sopenharmony_ci    PACKET pkt, data;
549e1051a39Sopenharmony_ci
550e1051a39Sopenharmony_ci    *extension_data = NULL;
551e1051a39Sopenharmony_ci    *extension_length = 0;
552e1051a39Sopenharmony_ci    if (serverinfo == NULL || serverinfo_length == 0)
553e1051a39Sopenharmony_ci        return -1;
554e1051a39Sopenharmony_ci
555e1051a39Sopenharmony_ci    if (!PACKET_buf_init(&pkt, serverinfo, serverinfo_length))
556e1051a39Sopenharmony_ci        return -1;
557e1051a39Sopenharmony_ci
558e1051a39Sopenharmony_ci    for (;;) {
559e1051a39Sopenharmony_ci        unsigned int type = 0;
560e1051a39Sopenharmony_ci        unsigned long context = 0;
561e1051a39Sopenharmony_ci
562e1051a39Sopenharmony_ci        /* end of serverinfo */
563e1051a39Sopenharmony_ci        if (PACKET_remaining(&pkt) == 0)
564e1051a39Sopenharmony_ci            return 0;           /* Extension not found */
565e1051a39Sopenharmony_ci
566e1051a39Sopenharmony_ci        if (!PACKET_get_net_4(&pkt, &context)
567e1051a39Sopenharmony_ci                || !PACKET_get_net_2(&pkt, &type)
568e1051a39Sopenharmony_ci                || !PACKET_get_length_prefixed_2(&pkt, &data))
569e1051a39Sopenharmony_ci            return -1;
570e1051a39Sopenharmony_ci
571e1051a39Sopenharmony_ci        if (type == extension_type) {
572e1051a39Sopenharmony_ci            *extension_data = PACKET_data(&data);
573e1051a39Sopenharmony_ci            *extension_length = PACKET_remaining(&data);;
574e1051a39Sopenharmony_ci            return 1;           /* Success */
575e1051a39Sopenharmony_ci        }
576e1051a39Sopenharmony_ci    }
577e1051a39Sopenharmony_ci    /* Unreachable */
578e1051a39Sopenharmony_ci}
579e1051a39Sopenharmony_ci
580e1051a39Sopenharmony_cistatic int serverinfoex_srv_parse_cb(SSL *s, unsigned int ext_type,
581e1051a39Sopenharmony_ci                                     unsigned int context,
582e1051a39Sopenharmony_ci                                     const unsigned char *in,
583e1051a39Sopenharmony_ci                                     size_t inlen, X509 *x, size_t chainidx,
584e1051a39Sopenharmony_ci                                     int *al, void *arg)
585e1051a39Sopenharmony_ci{
586e1051a39Sopenharmony_ci
587e1051a39Sopenharmony_ci    if (inlen != 0) {
588e1051a39Sopenharmony_ci        *al = SSL_AD_DECODE_ERROR;
589e1051a39Sopenharmony_ci        return 0;
590e1051a39Sopenharmony_ci    }
591e1051a39Sopenharmony_ci
592e1051a39Sopenharmony_ci    return 1;
593e1051a39Sopenharmony_ci}
594e1051a39Sopenharmony_ci
595e1051a39Sopenharmony_cistatic int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type,
596e1051a39Sopenharmony_ci                                   const unsigned char *in,
597e1051a39Sopenharmony_ci                                   size_t inlen, int *al, void *arg)
598e1051a39Sopenharmony_ci{
599e1051a39Sopenharmony_ci    return serverinfoex_srv_parse_cb(s, ext_type, 0, in, inlen, NULL, 0, al,
600e1051a39Sopenharmony_ci                                     arg);
601e1051a39Sopenharmony_ci}
602e1051a39Sopenharmony_ci
603e1051a39Sopenharmony_cistatic int serverinfoex_srv_add_cb(SSL *s, unsigned int ext_type,
604e1051a39Sopenharmony_ci                                   unsigned int context,
605e1051a39Sopenharmony_ci                                   const unsigned char **out,
606e1051a39Sopenharmony_ci                                   size_t *outlen, X509 *x, size_t chainidx,
607e1051a39Sopenharmony_ci                                   int *al, void *arg)
608e1051a39Sopenharmony_ci{
609e1051a39Sopenharmony_ci    const unsigned char *serverinfo = NULL;
610e1051a39Sopenharmony_ci    size_t serverinfo_length = 0;
611e1051a39Sopenharmony_ci
612e1051a39Sopenharmony_ci    /* We only support extensions for the first Certificate */
613e1051a39Sopenharmony_ci    if ((context & SSL_EXT_TLS1_3_CERTIFICATE) != 0 && chainidx > 0)
614e1051a39Sopenharmony_ci        return 0;
615e1051a39Sopenharmony_ci
616e1051a39Sopenharmony_ci    /* Is there serverinfo data for the chosen server cert? */
617e1051a39Sopenharmony_ci    if ((ssl_get_server_cert_serverinfo(s, &serverinfo,
618e1051a39Sopenharmony_ci                                        &serverinfo_length)) != 0) {
619e1051a39Sopenharmony_ci        /* Find the relevant extension from the serverinfo */
620e1051a39Sopenharmony_ci        int retval = serverinfo_find_extension(serverinfo, serverinfo_length,
621e1051a39Sopenharmony_ci                                               ext_type, out, outlen);
622e1051a39Sopenharmony_ci        if (retval == -1) {
623e1051a39Sopenharmony_ci            *al = SSL_AD_INTERNAL_ERROR;
624e1051a39Sopenharmony_ci            return -1;          /* Error */
625e1051a39Sopenharmony_ci        }
626e1051a39Sopenharmony_ci        if (retval == 0)
627e1051a39Sopenharmony_ci            return 0;           /* No extension found, don't send extension */
628e1051a39Sopenharmony_ci        return 1;               /* Send extension */
629e1051a39Sopenharmony_ci    }
630e1051a39Sopenharmony_ci    return 0;                   /* No serverinfo data found, don't send
631e1051a39Sopenharmony_ci                                 * extension */
632e1051a39Sopenharmony_ci}
633e1051a39Sopenharmony_ci
634e1051a39Sopenharmony_cistatic int serverinfo_srv_add_cb(SSL *s, unsigned int ext_type,
635e1051a39Sopenharmony_ci                                 const unsigned char **out, size_t *outlen,
636e1051a39Sopenharmony_ci                                 int *al, void *arg)
637e1051a39Sopenharmony_ci{
638e1051a39Sopenharmony_ci    return serverinfoex_srv_add_cb(s, ext_type, 0, out, outlen, NULL, 0, al,
639e1051a39Sopenharmony_ci                                   arg);
640e1051a39Sopenharmony_ci}
641e1051a39Sopenharmony_ci
642e1051a39Sopenharmony_ci/*
643e1051a39Sopenharmony_ci * With a NULL context, this function just checks that the serverinfo data
644e1051a39Sopenharmony_ci * parses correctly.  With a non-NULL context, it registers callbacks for
645e1051a39Sopenharmony_ci * the included extensions.
646e1051a39Sopenharmony_ci */
647e1051a39Sopenharmony_cistatic int serverinfo_process_buffer(unsigned int version,
648e1051a39Sopenharmony_ci                                     const unsigned char *serverinfo,
649e1051a39Sopenharmony_ci                                     size_t serverinfo_length, SSL_CTX *ctx)
650e1051a39Sopenharmony_ci{
651e1051a39Sopenharmony_ci    PACKET pkt;
652e1051a39Sopenharmony_ci
653e1051a39Sopenharmony_ci    if (serverinfo == NULL || serverinfo_length == 0)
654e1051a39Sopenharmony_ci        return 0;
655e1051a39Sopenharmony_ci
656e1051a39Sopenharmony_ci    if (version != SSL_SERVERINFOV1 && version != SSL_SERVERINFOV2)
657e1051a39Sopenharmony_ci        return 0;
658e1051a39Sopenharmony_ci
659e1051a39Sopenharmony_ci    if (!PACKET_buf_init(&pkt, serverinfo, serverinfo_length))
660e1051a39Sopenharmony_ci        return 0;
661e1051a39Sopenharmony_ci
662e1051a39Sopenharmony_ci    while (PACKET_remaining(&pkt)) {
663e1051a39Sopenharmony_ci        unsigned long context = 0;
664e1051a39Sopenharmony_ci        unsigned int ext_type = 0;
665e1051a39Sopenharmony_ci        PACKET data;
666e1051a39Sopenharmony_ci
667e1051a39Sopenharmony_ci        if ((version == SSL_SERVERINFOV2 && !PACKET_get_net_4(&pkt, &context))
668e1051a39Sopenharmony_ci                || !PACKET_get_net_2(&pkt, &ext_type)
669e1051a39Sopenharmony_ci                || !PACKET_get_length_prefixed_2(&pkt, &data))
670e1051a39Sopenharmony_ci            return 0;
671e1051a39Sopenharmony_ci
672e1051a39Sopenharmony_ci        if (ctx == NULL)
673e1051a39Sopenharmony_ci            continue;
674e1051a39Sopenharmony_ci
675e1051a39Sopenharmony_ci        /*
676e1051a39Sopenharmony_ci         * The old style custom extensions API could be set separately for
677e1051a39Sopenharmony_ci         * server/client, i.e. you could set one custom extension for a client,
678e1051a39Sopenharmony_ci         * and *for the same extension in the same SSL_CTX* you could set a
679e1051a39Sopenharmony_ci         * custom extension for the server as well. It seems quite weird to be
680e1051a39Sopenharmony_ci         * setting a custom extension for both client and server in a single
681e1051a39Sopenharmony_ci         * SSL_CTX - but theoretically possible. This isn't possible in the
682e1051a39Sopenharmony_ci         * new API. Therefore, if we have V1 serverinfo we use the old API. We
683e1051a39Sopenharmony_ci         * also use the old API even if we have V2 serverinfo but the context
684e1051a39Sopenharmony_ci         * looks like an old style <= TLSv1.2 extension.
685e1051a39Sopenharmony_ci         */
686e1051a39Sopenharmony_ci        if (version == SSL_SERVERINFOV1 || context == SYNTHV1CONTEXT) {
687e1051a39Sopenharmony_ci            if (!SSL_CTX_add_server_custom_ext(ctx, ext_type,
688e1051a39Sopenharmony_ci                                               serverinfo_srv_add_cb,
689e1051a39Sopenharmony_ci                                               NULL, NULL,
690e1051a39Sopenharmony_ci                                               serverinfo_srv_parse_cb,
691e1051a39Sopenharmony_ci                                               NULL))
692e1051a39Sopenharmony_ci                return 0;
693e1051a39Sopenharmony_ci        } else {
694e1051a39Sopenharmony_ci            if (!SSL_CTX_add_custom_ext(ctx, ext_type, context,
695e1051a39Sopenharmony_ci                                        serverinfoex_srv_add_cb,
696e1051a39Sopenharmony_ci                                        NULL, NULL,
697e1051a39Sopenharmony_ci                                        serverinfoex_srv_parse_cb,
698e1051a39Sopenharmony_ci                                        NULL))
699e1051a39Sopenharmony_ci                return 0;
700e1051a39Sopenharmony_ci        }
701e1051a39Sopenharmony_ci    }
702e1051a39Sopenharmony_ci
703e1051a39Sopenharmony_ci    return 1;
704e1051a39Sopenharmony_ci}
705e1051a39Sopenharmony_ci
706e1051a39Sopenharmony_cistatic size_t extension_contextoff(unsigned int version)
707e1051a39Sopenharmony_ci{
708e1051a39Sopenharmony_ci    return version == SSL_SERVERINFOV1 ? 4 : 0;
709e1051a39Sopenharmony_ci}
710e1051a39Sopenharmony_ci
711e1051a39Sopenharmony_cistatic size_t extension_append_length(unsigned int version, size_t extension_length)
712e1051a39Sopenharmony_ci{
713e1051a39Sopenharmony_ci    return extension_length + extension_contextoff(version);
714e1051a39Sopenharmony_ci}
715e1051a39Sopenharmony_ci
716e1051a39Sopenharmony_cistatic void extension_append(unsigned int version,
717e1051a39Sopenharmony_ci                             const unsigned char *extension,
718e1051a39Sopenharmony_ci                             const size_t extension_length,
719e1051a39Sopenharmony_ci                             unsigned char *serverinfo)
720e1051a39Sopenharmony_ci{
721e1051a39Sopenharmony_ci    const size_t contextoff = extension_contextoff(version);
722e1051a39Sopenharmony_ci
723e1051a39Sopenharmony_ci    if (contextoff > 0) {
724e1051a39Sopenharmony_ci        /* We know this only uses the last 2 bytes */
725e1051a39Sopenharmony_ci        serverinfo[0] = 0;
726e1051a39Sopenharmony_ci        serverinfo[1] = 0;
727e1051a39Sopenharmony_ci        serverinfo[2] = (SYNTHV1CONTEXT >> 8) & 0xff;
728e1051a39Sopenharmony_ci        serverinfo[3] = SYNTHV1CONTEXT & 0xff;
729e1051a39Sopenharmony_ci    }
730e1051a39Sopenharmony_ci
731e1051a39Sopenharmony_ci    memcpy(serverinfo + contextoff, extension, extension_length);
732e1051a39Sopenharmony_ci}
733e1051a39Sopenharmony_ci
734e1051a39Sopenharmony_ciint SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version,
735e1051a39Sopenharmony_ci                              const unsigned char *serverinfo,
736e1051a39Sopenharmony_ci                              size_t serverinfo_length)
737e1051a39Sopenharmony_ci{
738e1051a39Sopenharmony_ci    unsigned char *new_serverinfo = NULL;
739e1051a39Sopenharmony_ci
740e1051a39Sopenharmony_ci    if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) {
741e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
742e1051a39Sopenharmony_ci        return 0;
743e1051a39Sopenharmony_ci    }
744e1051a39Sopenharmony_ci    if (version == SSL_SERVERINFOV1) {
745e1051a39Sopenharmony_ci        /*
746e1051a39Sopenharmony_ci         * Convert serverinfo version v1 to v2 and call yourself recursively
747e1051a39Sopenharmony_ci         * over the converted serverinfo.
748e1051a39Sopenharmony_ci         */
749e1051a39Sopenharmony_ci        const size_t sinfo_length = extension_append_length(SSL_SERVERINFOV1,
750e1051a39Sopenharmony_ci                                                            serverinfo_length);
751e1051a39Sopenharmony_ci        unsigned char *sinfo;
752e1051a39Sopenharmony_ci        int ret;
753e1051a39Sopenharmony_ci
754e1051a39Sopenharmony_ci        sinfo = OPENSSL_malloc(sinfo_length);
755e1051a39Sopenharmony_ci        if (sinfo == NULL) {
756e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
757e1051a39Sopenharmony_ci            return 0;
758e1051a39Sopenharmony_ci        }
759e1051a39Sopenharmony_ci
760e1051a39Sopenharmony_ci        extension_append(SSL_SERVERINFOV1, serverinfo, serverinfo_length, sinfo);
761e1051a39Sopenharmony_ci
762e1051a39Sopenharmony_ci        ret = SSL_CTX_use_serverinfo_ex(ctx, SSL_SERVERINFOV2, sinfo,
763e1051a39Sopenharmony_ci                                        sinfo_length);
764e1051a39Sopenharmony_ci
765e1051a39Sopenharmony_ci        OPENSSL_free(sinfo);
766e1051a39Sopenharmony_ci        return ret;
767e1051a39Sopenharmony_ci    }
768e1051a39Sopenharmony_ci    if (!serverinfo_process_buffer(version, serverinfo, serverinfo_length,
769e1051a39Sopenharmony_ci                                   NULL)) {
770e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA);
771e1051a39Sopenharmony_ci        return 0;
772e1051a39Sopenharmony_ci    }
773e1051a39Sopenharmony_ci    if (ctx->cert->key == NULL) {
774e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
775e1051a39Sopenharmony_ci        return 0;
776e1051a39Sopenharmony_ci    }
777e1051a39Sopenharmony_ci    new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo,
778e1051a39Sopenharmony_ci                                     serverinfo_length);
779e1051a39Sopenharmony_ci    if (new_serverinfo == NULL) {
780e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
781e1051a39Sopenharmony_ci        return 0;
782e1051a39Sopenharmony_ci    }
783e1051a39Sopenharmony_ci    ctx->cert->key->serverinfo = new_serverinfo;
784e1051a39Sopenharmony_ci    memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length);
785e1051a39Sopenharmony_ci    ctx->cert->key->serverinfo_length = serverinfo_length;
786e1051a39Sopenharmony_ci
787e1051a39Sopenharmony_ci    /*
788e1051a39Sopenharmony_ci     * Now that the serverinfo is validated and stored, go ahead and
789e1051a39Sopenharmony_ci     * register callbacks.
790e1051a39Sopenharmony_ci     */
791e1051a39Sopenharmony_ci    if (!serverinfo_process_buffer(version, serverinfo, serverinfo_length,
792e1051a39Sopenharmony_ci                                   ctx)) {
793e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA);
794e1051a39Sopenharmony_ci        return 0;
795e1051a39Sopenharmony_ci    }
796e1051a39Sopenharmony_ci    return 1;
797e1051a39Sopenharmony_ci}
798e1051a39Sopenharmony_ci
799e1051a39Sopenharmony_ciint SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
800e1051a39Sopenharmony_ci                           size_t serverinfo_length)
801e1051a39Sopenharmony_ci{
802e1051a39Sopenharmony_ci    return SSL_CTX_use_serverinfo_ex(ctx, SSL_SERVERINFOV1, serverinfo,
803e1051a39Sopenharmony_ci                                     serverinfo_length);
804e1051a39Sopenharmony_ci}
805e1051a39Sopenharmony_ci
806e1051a39Sopenharmony_ciint SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
807e1051a39Sopenharmony_ci{
808e1051a39Sopenharmony_ci    unsigned char *serverinfo = NULL;
809e1051a39Sopenharmony_ci    unsigned char *tmp;
810e1051a39Sopenharmony_ci    size_t serverinfo_length = 0;
811e1051a39Sopenharmony_ci    unsigned char *extension = 0;
812e1051a39Sopenharmony_ci    long extension_length = 0;
813e1051a39Sopenharmony_ci    char *name = NULL;
814e1051a39Sopenharmony_ci    char *header = NULL;
815e1051a39Sopenharmony_ci    static const char namePrefix1[] = "SERVERINFO FOR ";
816e1051a39Sopenharmony_ci    static const char namePrefix2[] = "SERVERINFOV2 FOR ";
817e1051a39Sopenharmony_ci    unsigned int name_len;
818e1051a39Sopenharmony_ci    int ret = 0;
819e1051a39Sopenharmony_ci    BIO *bin = NULL;
820e1051a39Sopenharmony_ci    size_t num_extensions = 0;
821e1051a39Sopenharmony_ci
822e1051a39Sopenharmony_ci    if (ctx == NULL || file == NULL) {
823e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
824e1051a39Sopenharmony_ci        goto end;
825e1051a39Sopenharmony_ci    }
826e1051a39Sopenharmony_ci
827e1051a39Sopenharmony_ci    bin = BIO_new(BIO_s_file());
828e1051a39Sopenharmony_ci    if (bin == NULL) {
829e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
830e1051a39Sopenharmony_ci        goto end;
831e1051a39Sopenharmony_ci    }
832e1051a39Sopenharmony_ci    if (BIO_read_filename(bin, file) <= 0) {
833e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB);
834e1051a39Sopenharmony_ci        goto end;
835e1051a39Sopenharmony_ci    }
836e1051a39Sopenharmony_ci
837e1051a39Sopenharmony_ci    for (num_extensions = 0;; num_extensions++) {
838e1051a39Sopenharmony_ci        unsigned int version;
839e1051a39Sopenharmony_ci        size_t append_length;
840e1051a39Sopenharmony_ci
841e1051a39Sopenharmony_ci        if (PEM_read_bio(bin, &name, &header, &extension, &extension_length)
842e1051a39Sopenharmony_ci            == 0) {
843e1051a39Sopenharmony_ci            /*
844e1051a39Sopenharmony_ci             * There must be at least one extension in this file
845e1051a39Sopenharmony_ci             */
846e1051a39Sopenharmony_ci            if (num_extensions == 0) {
847e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_SSL, SSL_R_NO_PEM_EXTENSIONS);
848e1051a39Sopenharmony_ci                goto end;
849e1051a39Sopenharmony_ci            } else              /* End of file, we're done */
850e1051a39Sopenharmony_ci                break;
851e1051a39Sopenharmony_ci        }
852e1051a39Sopenharmony_ci        /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */
853e1051a39Sopenharmony_ci        name_len = strlen(name);
854e1051a39Sopenharmony_ci        if (name_len < sizeof(namePrefix1) - 1) {
855e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT);
856e1051a39Sopenharmony_ci            goto end;
857e1051a39Sopenharmony_ci        }
858e1051a39Sopenharmony_ci        if (strncmp(name, namePrefix1, sizeof(namePrefix1) - 1) == 0) {
859e1051a39Sopenharmony_ci            version = SSL_SERVERINFOV1;
860e1051a39Sopenharmony_ci        } else {
861e1051a39Sopenharmony_ci            if (name_len < sizeof(namePrefix2) - 1) {
862e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT);
863e1051a39Sopenharmony_ci                goto end;
864e1051a39Sopenharmony_ci            }
865e1051a39Sopenharmony_ci            if (strncmp(name, namePrefix2, sizeof(namePrefix2) - 1) != 0) {
866e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_BAD_PREFIX);
867e1051a39Sopenharmony_ci                goto end;
868e1051a39Sopenharmony_ci            }
869e1051a39Sopenharmony_ci            version = SSL_SERVERINFOV2;
870e1051a39Sopenharmony_ci        }
871e1051a39Sopenharmony_ci        /*
872e1051a39Sopenharmony_ci         * Check that the decoded PEM data is plausible (valid length field)
873e1051a39Sopenharmony_ci         */
874e1051a39Sopenharmony_ci        if (version == SSL_SERVERINFOV1) {
875e1051a39Sopenharmony_ci            /* 4 byte header: 2 bytes type, 2 bytes len */
876e1051a39Sopenharmony_ci            if (extension_length < 4
877e1051a39Sopenharmony_ci                    || (extension[2] << 8) + extension[3]
878e1051a39Sopenharmony_ci                       != extension_length - 4) {
879e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_SSL, SSL_R_BAD_DATA);
880e1051a39Sopenharmony_ci                goto end;
881e1051a39Sopenharmony_ci            }
882e1051a39Sopenharmony_ci        } else {
883e1051a39Sopenharmony_ci            /* 8 byte header: 4 bytes context, 2 bytes type, 2 bytes len */
884e1051a39Sopenharmony_ci            if (extension_length < 8
885e1051a39Sopenharmony_ci                    || (extension[6] << 8) + extension[7]
886e1051a39Sopenharmony_ci                       != extension_length - 8) {
887e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_SSL, SSL_R_BAD_DATA);
888e1051a39Sopenharmony_ci                goto end;
889e1051a39Sopenharmony_ci            }
890e1051a39Sopenharmony_ci        }
891e1051a39Sopenharmony_ci        /* Append the decoded extension to the serverinfo buffer */
892e1051a39Sopenharmony_ci        append_length = extension_append_length(version, extension_length);
893e1051a39Sopenharmony_ci        tmp = OPENSSL_realloc(serverinfo, serverinfo_length + append_length);
894e1051a39Sopenharmony_ci        if (tmp == NULL) {
895e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
896e1051a39Sopenharmony_ci            goto end;
897e1051a39Sopenharmony_ci        }
898e1051a39Sopenharmony_ci        serverinfo = tmp;
899e1051a39Sopenharmony_ci        extension_append(version, extension, extension_length,
900e1051a39Sopenharmony_ci                         serverinfo + serverinfo_length);
901e1051a39Sopenharmony_ci        serverinfo_length += append_length;
902e1051a39Sopenharmony_ci
903e1051a39Sopenharmony_ci        OPENSSL_free(name);
904e1051a39Sopenharmony_ci        name = NULL;
905e1051a39Sopenharmony_ci        OPENSSL_free(header);
906e1051a39Sopenharmony_ci        header = NULL;
907e1051a39Sopenharmony_ci        OPENSSL_free(extension);
908e1051a39Sopenharmony_ci        extension = NULL;
909e1051a39Sopenharmony_ci    }
910e1051a39Sopenharmony_ci
911e1051a39Sopenharmony_ci    ret = SSL_CTX_use_serverinfo_ex(ctx, SSL_SERVERINFOV2, serverinfo,
912e1051a39Sopenharmony_ci                                    serverinfo_length);
913e1051a39Sopenharmony_ci end:
914e1051a39Sopenharmony_ci    /* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */
915e1051a39Sopenharmony_ci    OPENSSL_free(name);
916e1051a39Sopenharmony_ci    OPENSSL_free(header);
917e1051a39Sopenharmony_ci    OPENSSL_free(extension);
918e1051a39Sopenharmony_ci    OPENSSL_free(serverinfo);
919e1051a39Sopenharmony_ci    BIO_free(bin);
920e1051a39Sopenharmony_ci    return ret;
921e1051a39Sopenharmony_ci}
922e1051a39Sopenharmony_ci
923e1051a39Sopenharmony_cistatic int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey,
924e1051a39Sopenharmony_ci                                STACK_OF(X509) *chain, int override)
925e1051a39Sopenharmony_ci{
926e1051a39Sopenharmony_ci    int ret = 0;
927e1051a39Sopenharmony_ci    size_t i;
928e1051a39Sopenharmony_ci    int j;
929e1051a39Sopenharmony_ci    int rv;
930e1051a39Sopenharmony_ci    CERT *c = ssl != NULL ? ssl->cert : ctx->cert;
931e1051a39Sopenharmony_ci    STACK_OF(X509) *dup_chain = NULL;
932e1051a39Sopenharmony_ci    EVP_PKEY *pubkey = NULL;
933e1051a39Sopenharmony_ci
934e1051a39Sopenharmony_ci    /* Do all security checks before anything else */
935e1051a39Sopenharmony_ci    rv = ssl_security_cert(ssl, ctx, x509, 0, 1);
936e1051a39Sopenharmony_ci    if (rv != 1) {
937e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, rv);
938e1051a39Sopenharmony_ci        goto out;
939e1051a39Sopenharmony_ci    }
940e1051a39Sopenharmony_ci    for (j = 0; j < sk_X509_num(chain); j++) {
941e1051a39Sopenharmony_ci        rv = ssl_security_cert(ssl, ctx, sk_X509_value(chain, j), 0, 0);
942e1051a39Sopenharmony_ci        if (rv != 1) {
943e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_SSL, rv);
944e1051a39Sopenharmony_ci            goto out;
945e1051a39Sopenharmony_ci        }
946e1051a39Sopenharmony_ci    }
947e1051a39Sopenharmony_ci
948e1051a39Sopenharmony_ci    pubkey = X509_get_pubkey(x509); /* bumps reference */
949e1051a39Sopenharmony_ci    if (pubkey == NULL)
950e1051a39Sopenharmony_ci        goto out;
951e1051a39Sopenharmony_ci    if (privatekey == NULL) {
952e1051a39Sopenharmony_ci        privatekey = pubkey;
953e1051a39Sopenharmony_ci    } else {
954e1051a39Sopenharmony_ci        /* For RSA, which has no parameters, missing returns 0 */
955e1051a39Sopenharmony_ci        if (EVP_PKEY_missing_parameters(privatekey)) {
956e1051a39Sopenharmony_ci            if (EVP_PKEY_missing_parameters(pubkey)) {
957e1051a39Sopenharmony_ci                /* nobody has parameters? - error */
958e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_SSL, SSL_R_MISSING_PARAMETERS);
959e1051a39Sopenharmony_ci                goto out;
960e1051a39Sopenharmony_ci            } else {
961e1051a39Sopenharmony_ci                /* copy to privatekey from pubkey */
962e1051a39Sopenharmony_ci                if (!EVP_PKEY_copy_parameters(privatekey, pubkey)) {
963e1051a39Sopenharmony_ci                    ERR_raise(ERR_LIB_SSL, SSL_R_COPY_PARAMETERS_FAILED);
964e1051a39Sopenharmony_ci                    goto out;
965e1051a39Sopenharmony_ci                }
966e1051a39Sopenharmony_ci            }
967e1051a39Sopenharmony_ci        } else if (EVP_PKEY_missing_parameters(pubkey)) {
968e1051a39Sopenharmony_ci            /* copy to pubkey from privatekey */
969e1051a39Sopenharmony_ci            if (!EVP_PKEY_copy_parameters(pubkey, privatekey)) {
970e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_SSL, SSL_R_COPY_PARAMETERS_FAILED);
971e1051a39Sopenharmony_ci                goto out;
972e1051a39Sopenharmony_ci            }
973e1051a39Sopenharmony_ci        } /* else both have parameters */
974e1051a39Sopenharmony_ci
975e1051a39Sopenharmony_ci        /* check that key <-> cert match */
976e1051a39Sopenharmony_ci        if (EVP_PKEY_eq(pubkey, privatekey) != 1) {
977e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_SSL, SSL_R_PRIVATE_KEY_MISMATCH);
978e1051a39Sopenharmony_ci            goto out;
979e1051a39Sopenharmony_ci        }
980e1051a39Sopenharmony_ci    }
981e1051a39Sopenharmony_ci    if (ssl_cert_lookup_by_pkey(pubkey, &i) == NULL) {
982e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
983e1051a39Sopenharmony_ci        goto out;
984e1051a39Sopenharmony_ci    }
985e1051a39Sopenharmony_ci
986e1051a39Sopenharmony_ci    if (!override && (c->pkeys[i].x509 != NULL
987e1051a39Sopenharmony_ci                      || c->pkeys[i].privatekey != NULL
988e1051a39Sopenharmony_ci                      || c->pkeys[i].chain != NULL)) {
989e1051a39Sopenharmony_ci        /* No override, and something already there */
990e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_NOT_REPLACING_CERTIFICATE);
991e1051a39Sopenharmony_ci        goto out;
992e1051a39Sopenharmony_ci    }
993e1051a39Sopenharmony_ci
994e1051a39Sopenharmony_ci    if (chain != NULL) {
995e1051a39Sopenharmony_ci        dup_chain = X509_chain_up_ref(chain);
996e1051a39Sopenharmony_ci        if  (dup_chain == NULL) {
997e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
998e1051a39Sopenharmony_ci            goto out;
999e1051a39Sopenharmony_ci        }
1000e1051a39Sopenharmony_ci    }
1001e1051a39Sopenharmony_ci
1002e1051a39Sopenharmony_ci    sk_X509_pop_free(c->pkeys[i].chain, X509_free);
1003e1051a39Sopenharmony_ci    c->pkeys[i].chain = dup_chain;
1004e1051a39Sopenharmony_ci
1005e1051a39Sopenharmony_ci    X509_free(c->pkeys[i].x509);
1006e1051a39Sopenharmony_ci    X509_up_ref(x509);
1007e1051a39Sopenharmony_ci    c->pkeys[i].x509 = x509;
1008e1051a39Sopenharmony_ci
1009e1051a39Sopenharmony_ci    EVP_PKEY_free(c->pkeys[i].privatekey);
1010e1051a39Sopenharmony_ci    EVP_PKEY_up_ref(privatekey);
1011e1051a39Sopenharmony_ci    c->pkeys[i].privatekey = privatekey;
1012e1051a39Sopenharmony_ci
1013e1051a39Sopenharmony_ci    c->key = &(c->pkeys[i]);
1014e1051a39Sopenharmony_ci
1015e1051a39Sopenharmony_ci    ret = 1;
1016e1051a39Sopenharmony_ci out:
1017e1051a39Sopenharmony_ci    EVP_PKEY_free(pubkey);
1018e1051a39Sopenharmony_ci    return ret;
1019e1051a39Sopenharmony_ci}
1020e1051a39Sopenharmony_ci
1021e1051a39Sopenharmony_ciint SSL_use_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey,
1022e1051a39Sopenharmony_ci                         STACK_OF(X509) *chain, int override)
1023e1051a39Sopenharmony_ci{
1024e1051a39Sopenharmony_ci    return ssl_set_cert_and_key(ssl, NULL, x509, privatekey, chain, override);
1025e1051a39Sopenharmony_ci}
1026e1051a39Sopenharmony_ci
1027e1051a39Sopenharmony_ciint SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey,
1028e1051a39Sopenharmony_ci                             STACK_OF(X509) *chain, int override)
1029e1051a39Sopenharmony_ci{
1030e1051a39Sopenharmony_ci    return ssl_set_cert_and_key(NULL, ctx, x509, privatekey, chain, override);
1031e1051a39Sopenharmony_ci}
1032