SSL *ssl;
/* Pointer to SSL or SSL_CTX options field or NULL if none */
unsigned long *poptions;
+ /* Certificate filenames for each type */
+ char *cert_filename[SSL_PKEY_NUM];
/* Pointer to SSL or SSL_CTX cert_flags or NULL if none */
unsigned int *pcert_flags;
/* Current flag table being worked on */
/* Single command line switches with no argument e.g. -no_ssl3 */
static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd)
{
+ /* See apps/apps.h if you change this table. */
static const ssl_flag_tbl ssl_option_single[] = {
SSL_FLAG_TBL("no_ssl3", SSL_OP_NO_SSLv3),
SSL_FLAG_TBL("no_tls1", SSL_OP_NO_TLSv1),
#endif
};
cctx->tbl = ssl_option_single;
- cctx->ntbl = sizeof(ssl_option_single) / sizeof(ssl_flag_tbl);
+ cctx->ntbl = OSSL_NELEM(ssl_option_single);
return ssl_set_option_list(cmd, -1, cctx);
}
if (!(cctx->flags & SSL_CONF_FLAG_FILE))
return -2;
cctx->tbl = ssl_protocol_list;
- cctx->ntbl = sizeof(ssl_protocol_list) / sizeof(ssl_flag_tbl);
+ cctx->ntbl = OSSL_NELEM(ssl_protocol_list);
return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
}
if (value == NULL)
return -3;
cctx->tbl = ssl_option_list;
- cctx->ntbl = sizeof(ssl_option_list) / sizeof(ssl_flag_tbl);
+ cctx->ntbl = OSSL_NELEM(ssl_option_list);
return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
}
static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
{
int rv = 1;
+ CERT *c = NULL;
if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
return -2;
- if (cctx->ctx)
+ if (cctx->ctx) {
rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
- if (cctx->ssl)
+ c = cctx->ctx->cert;
+ }
+ if (cctx->ssl) {
rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM);
+ c = cctx->ssl->cert;
+ }
+ if (rv > 0 && c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
+ char **pfilename = &cctx->cert_filename[c->key - c->pkeys];
+ OPENSSL_free(*pfilename);
+ *pfilename = BUF_strdup(value);
+ if (!*pfilename)
+ rv = 0;
+ }
+
return rv > 0;
}
if (cctx->ssl)
rv = SSL_set_tmp_dh(cctx->ssl, dh);
end:
- if (dh)
- DH_free(dh);
- if (in)
- BIO_free(in);
+ DH_free(dh);
+ BIO_free(in);
return rv > 0;
}
#endif
#define SSL_CONF_CMD_STRING(name, cmdopt) \
SSL_CONF_CMD(name, cmdopt, SSL_CONF_TYPE_STRING)
+/* See apps/apps.h if you change this table. */
static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs"),
SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs"),
return NULL;
/* Look for matching parameter name in table */
- for (i = 0, t = ssl_conf_cmds;
- i < sizeof(ssl_conf_cmds) / sizeof(ssl_conf_cmd_tbl); i++, t++) {
+ for (i = 0, t = ssl_conf_cmds; i < OSSL_NELEM(ssl_conf_cmds); i++, t++) {
if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
if (t->str_cmdline && !strcmp(t->str_cmdline, cmd))
return t;
SSL_CONF_CTX *SSL_CONF_CTX_new(void)
{
- SSL_CONF_CTX *ret;
- ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX));
+ SSL_CONF_CTX *ret = OPENSSL_malloc(sizeof(*ret));
+ size_t i;
+
if (ret) {
ret->flags = 0;
ret->prefix = NULL;
ret->pcert_flags = NULL;
ret->tbl = NULL;
ret->ntbl = 0;
+ for (i = 0; i < SSL_PKEY_NUM; i++)
+ ret->cert_filename[i] = NULL;
}
return ret;
}
int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
{
+ /* See if any certificates are missing private keys */
+ size_t i;
+ CERT *c = NULL;
+ if (cctx->ctx)
+ c = cctx->ctx->cert;
+ else if (cctx->ssl)
+ c = cctx->ssl->cert;
+ if (c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
+ for (i = 0; i < SSL_PKEY_NUM; i++) {
+ const char *p = cctx->cert_filename[i];
+ /*
+ * If missing private key try to load one from certificate file
+ */
+ if (p && !c->pkeys[i].privatekey) {
+ if (!cmd_PrivateKey(cctx, p))
+ return 0;
+ }
+ }
+ }
return 1;
}
void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
{
if (cctx) {
- if (cctx->prefix)
- OPENSSL_free(cctx->prefix);
+ size_t i;
+ for (i = 0; i < SSL_PKEY_NUM; i++) {
+ OPENSSL_free(cctx->cert_filename[i]);
+ }
+ OPENSSL_free(cctx->prefix);
OPENSSL_free(cctx);
}
}
if (tmp == NULL)
return 0;
}
- if (cctx->prefix)
- OPENSSL_free(cctx->prefix);
+ OPENSSL_free(cctx->prefix);
cctx->prefix = tmp;
if (tmp)
cctx->prefixlen = strlen(tmp);