/*
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <stdio.h>
#include "ssl_local.h"
#include "internal/packet.h"
#include <openssl/bio.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pem.h>
static int ssl_set_cert(CERT *c, X509 *x509);
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
#define SYNTHV1CONTEXT (SSL_EXT_TLS1_2_AND_BELOW_ONLY \
| SSL_EXT_CLIENT_HELLO \
| SSL_EXT_TLS1_2_SERVER_HELLO \
| SSL_EXT_IGNORE_ON_RESUMPTION)
int SSL_use_certificate(SSL *ssl, X509 *x)
{
int rv;
if (x == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
rv = ssl_security_cert(ssl, NULL, x, 0, 1);
if (rv != 1) {
ERR_raise(ERR_LIB_SSL, rv);
return 0;
}
return ssl_set_cert(ssl->cert, x);
}
int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
{
int j;
BIO *in;
int ret = 0;
X509 *cert = NULL, *x = NULL;
in = BIO_new(BIO_s_file());
if (in == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
goto end;
}
if (BIO_read_filename(in, file) <= 0) {
ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB);
goto end;
}
if (type != SSL_FILETYPE_ASN1 && type != SSL_FILETYPE_PEM) {
ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE);
goto end;
}
x = X509_new_ex(ssl->ctx->libctx, ssl->ctx->propq);
if (x == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
goto end;
}
if (type == SSL_FILETYPE_ASN1) {
j = ERR_R_ASN1_LIB;
cert = d2i_X509_bio(in, &x);
} else if (type == SSL_FILETYPE_PEM) {
j = ERR_R_PEM_LIB;
cert = PEM_read_bio_X509(in, &x, ssl->default_passwd_callback,
ssl->default_passwd_callback_userdata);
} else {
ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE);
goto end;
}
if (cert == NULL) {
ERR_raise(ERR_LIB_SSL, j);
goto end;
}
ret = SSL_use_certificate(ssl, x);
end:
X509_free(x);
BIO_free(in);
return ret;
}
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
{
X509 *x;
int ret;
x = X509_new_ex(ssl->ctx->libctx, ssl->ctx->propq);
if (x == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
if (d2i_X509(&x, &d, (long)len)== NULL) {
X509_free(x);
ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB);
return 0;
}
ret = SSL_use_certificate(ssl, x);
X509_free(x);
return ret;
}
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
{
size_t i;
if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
return 0;
}
if (c->pkeys[i].x509 != NULL
&& !X509_check_private_key(c->pkeys[i].x509, pkey))
return 0;
<