Skip to content

Commit

Permalink
Add support for use certificate chain for cmd_SignCertificate and cmd…
Browse files Browse the repository at this point in the history
…_EncCertificate of SSL_CONF_cmd
  • Loading branch information
daipingh committed Mar 4, 2024
1 parent b833382 commit f29f483
Showing 1 changed file with 121 additions and 12 deletions.
133 changes: 121 additions & 12 deletions ssl/ssl_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,21 +465,130 @@ static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
}

#ifndef OPENSSL_NO_NTLS
/*
* Read a file that contains our certificate in "PEM" format, possibly
* followed by a sequence of CA certificates that should be sent to the peer
* in the Certificate message.
*/
static int use_ntls_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, int sign, const char *file)
{
BIO *in;
int ret = 0;
X509 *x = NULL;
pem_password_cb *passwd_callback;
void *passwd_callback_userdata;

ERR_clear_error(); /* clear error stack for
* SSL_CTX_use_certificate() */

if (ctx != NULL) {
passwd_callback = ctx->default_passwd_callback;
passwd_callback_userdata = ctx->default_passwd_callback_userdata;
} else {
passwd_callback = ssl->default_passwd_callback;
passwd_callback_userdata = ssl->default_passwd_callback_userdata;
}

in = BIO_new(BIO_s_file());
if (in == NULL) {
//SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
goto end;
}

if (BIO_read_filename(in, file) <= 0) {
//SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB);
goto end;
}

x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback,
passwd_callback_userdata);
if (x == NULL) {
//SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
goto end;
}

if (sign) {
if (ctx)
ret = SSL_CTX_use_sign_certificate(ctx, x);
else
ret = SSL_use_sign_certificate(ssl, x);
} else {
if (ctx)
ret = SSL_CTX_use_enc_certificate(ctx, x);
else
ret = SSL_use_enc_certificate(ssl, x);
}

if (ERR_peek_error() != 0)
ret = 0; /* Key/certificate mismatch doesn't imply
* ret==0 ... */
if (ret) {
/*
* If we could set up our certificate, now proceed to the CA
* certificates.
*/
X509 *ca;
int r;
unsigned long err;

if (ctx)
r = SSL_CTX_clear_chain_certs(ctx);
else
r = SSL_clear_chain_certs(ssl);

if (r == 0) {
ret = 0;
goto end;
}

while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback,
passwd_callback_userdata))
!= NULL) {
if (ctx)
r = SSL_CTX_add0_chain_cert(ctx, ca);
else
r = SSL_add0_chain_cert(ssl, ca);
/*
* Note that we must not free ca if it was successfully added to
* the chain (while we must free the main certificate, since its
* reference count is increased by SSL_CTX_use_certificate).
*/
if (!r) {
X509_free(ca);
ret = 0;
goto end;
}
}
/* When the while loop ends, it's usually just EOF. */
err = ERR_peek_last_error();
if (ERR_GET_LIB(err) == ERR_LIB_PEM
&& ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
ERR_clear_error();
else
ret = 0; /* some real error */
}

end:
X509_free(x);
BIO_free(in);
return ret;
}

static int cmd_EncCertificate(SSL_CONF_CTX *cctx, const char *value)
{
int rv = 1;
CERT *c = NULL;

if (cctx->ctx) {
/* FIXME: currently we assume all SM2 certs in PEM format */
rv = SSL_CTX_use_enc_certificate_file(cctx->ctx, value,
SSL_FILETYPE_PEM);
rv = use_ntls_certificate_chain_file(cctx->ctx, NULL, 0,
value);
c = cctx->ctx->cert;
}

if (cctx->ssl) {
/* FIXME: setting certificates for SSL is not supported yet */
rv = 0;
rv = use_ntls_certificate_chain_file(NULL, cctx->ssl, 0,
value);
c = cctx->ssl->cert;
}

if (rv > 0 && c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
Expand All @@ -501,7 +610,7 @@ static int cmd_EncPrivateKey(SSL_CONF_CTX *cctx, const char *value)
if (cctx->ctx)
rv = SSL_CTX_use_enc_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
if (cctx->ssl)
rv = 0;
rv = SSL_use_enc_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
return rv > 0;
}

Expand All @@ -511,15 +620,15 @@ static int cmd_SignCertificate(SSL_CONF_CTX *cctx, const char *value)
CERT *c = NULL;

if (cctx->ctx) {
/* FIXME: currently we assume all sign certs in PEM format */
rv = SSL_CTX_use_sign_certificate_file(cctx->ctx, value,
SSL_FILETYPE_PEM);
rv = use_ntls_certificate_chain_file(cctx->ctx, NULL, 1,
value);
c = cctx->ctx->cert;
}

if (cctx->ssl) {
/* FIXME: setting certificates for SSL is not supported yet */
rv = 0;
rv = use_ntls_certificate_chain_file(NULL, cctx->ssl, 1,
value);
c = cctx->ssl->cert;
}

if (rv > 0 && c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
Expand All @@ -542,7 +651,7 @@ static int cmd_SignPrivateKey(SSL_CONF_CTX *cctx, const char *value)
rv = SSL_CTX_use_sign_PrivateKey_file(cctx->ctx, value,
SSL_FILETYPE_PEM);
if (cctx->ssl)
rv = 0;
rv = SSL_use_sign_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
return rv > 0;
}
#endif
Expand Down

0 comments on commit f29f483

Please sign in to comment.