提交 2011b169 编写于 作者: D Dr. Stephen Henson

Support key loading from certificate file

Support loading of key and certificate from the same file if
SSL_CONF_FLAG_REQUIRE_PRIVATE is set. This is done by remembering the
filename used for each certificate type and attempting to load a private
key from the file when SSL_CONF_CTX_finish is called.

Update docs.
Reviewed-by: NRichard Levitte <levitte@openssl.org>
上级 9837bfbf
...@@ -40,6 +40,13 @@ both of these flags must be set. ...@@ -40,6 +40,13 @@ both of these flags must be set.
recognise certificate and private key options. recognise certificate and private key options.
=item SSL_CONF_FLAG_REQUIRE_PRIVATE
If this option is set then if a private key is not specified for a certificate
it will attempt to load a private key from the certificate file when
SSL_CONF_CTX_finish() is called. If a key cannot be loaded from the certificate
file an error occurs.
=item SSL_CONF_FLAG_SHOW_ERRORS =item SSL_CONF_FLAG_SHOW_ERRORS
indicate errors relating to unrecognised options or missing arguments in indicate errors relating to unrecognised options or missing arguments in
......
...@@ -101,7 +101,7 @@ are permitted. ...@@ -101,7 +101,7 @@ are permitted.
Attempts to use the file B<value> as the private key for the appropriate Attempts to use the file B<value> as the private key for the appropriate
context. This option is only supported if certificate operations context. This option is only supported if certificate operations
are permitted. Note: if no B<-key> option is set then a private key is are permitted. Note: if no B<-key> option is set then a private key is
not loaded: it does not currently use the B<-cert> file. not loaded unless the flag B<SSL_CONF_FLAG_REQUIRE_PRIVATE> is set.
=item B<-dhparam> =item B<-dhparam>
...@@ -192,8 +192,8 @@ are permitted. ...@@ -192,8 +192,8 @@ are permitted.
Attempts to use the file B<value> as the private key for the appropriate Attempts to use the file B<value> as the private key for the appropriate
context. This option is only supported if certificate operations context. This option is only supported if certificate operations
are permitted. Note: if no B<-key> option is set then a private key is are permitted. Note: if no B<PrivateKey> option is set then a private key is
not loaded: it does not currently use the B<Certificate> file. not loaded unless the B<SSL_CONF_FLAG_REQUIRE_PRIVATE> is set.
=item B<ServerInfoFile> =item B<ServerInfoFile>
......
...@@ -588,6 +588,7 @@ typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type, ...@@ -588,6 +588,7 @@ typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type,
# define SSL_CONF_FLAG_SERVER 0x8 # define SSL_CONF_FLAG_SERVER 0x8
# define SSL_CONF_FLAG_SHOW_ERRORS 0x10 # define SSL_CONF_FLAG_SHOW_ERRORS 0x10
# define SSL_CONF_FLAG_CERTIFICATE 0x20 # define SSL_CONF_FLAG_CERTIFICATE 0x20
# define SSL_CONF_FLAG_REQUIRE_PRIVATE 0x40
/* Configuration value types */ /* Configuration value types */
# define SSL_CONF_TYPE_UNKNOWN 0x0 # define SSL_CONF_TYPE_UNKNOWN 0x0
# define SSL_CONF_TYPE_STRING 0x1 # define SSL_CONF_TYPE_STRING 0x1
......
...@@ -119,6 +119,8 @@ struct ssl_conf_ctx_st { ...@@ -119,6 +119,8 @@ struct ssl_conf_ctx_st {
SSL *ssl; SSL *ssl;
/* Pointer to SSL or SSL_CTX options field or NULL if none */ /* Pointer to SSL or SSL_CTX options field or NULL if none */
unsigned long *poptions; 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 */ /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */
unsigned int *pcert_flags; unsigned int *pcert_flags;
/* Current flag table being worked on */ /* Current flag table being worked on */
...@@ -364,12 +366,26 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) ...@@ -364,12 +366,26 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value) static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
{ {
int rv = 1; int rv = 1;
CERT *c = NULL;
if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
return -2; return -2;
if (cctx->ctx) if (cctx->ctx) {
rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value); 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); 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];
if (*pfilename)
OPENSSL_free(*pfilename);
*pfilename = BUF_strdup(value);
if (!*pfilename)
rv = 0;
}
return rv > 0; return rv > 0;
} }
...@@ -595,6 +611,7 @@ int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd) ...@@ -595,6 +611,7 @@ int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
SSL_CONF_CTX *SSL_CONF_CTX_new(void) SSL_CONF_CTX *SSL_CONF_CTX_new(void)
{ {
SSL_CONF_CTX *ret; SSL_CONF_CTX *ret;
size_t i;
ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX)); ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX));
if (ret) { if (ret) {
ret->flags = 0; ret->flags = 0;
...@@ -606,18 +623,44 @@ SSL_CONF_CTX *SSL_CONF_CTX_new(void) ...@@ -606,18 +623,44 @@ SSL_CONF_CTX *SSL_CONF_CTX_new(void)
ret->pcert_flags = NULL; ret->pcert_flags = NULL;
ret->tbl = NULL; ret->tbl = NULL;
ret->ntbl = 0; ret->ntbl = 0;
for (i = 0; i < SSL_PKEY_NUM; i++)
ret->cert_filename[i] = NULL;
} }
return ret; return ret;
} }
int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx) 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; return 1;
} }
void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx) void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
{ {
if (cctx) { if (cctx) {
size_t i;
for (i = 0; i < SSL_PKEY_NUM; i++) {
if (cctx->cert_filename[i])
OPENSSL_free(cctx->cert_filename[i]);
}
if (cctx->prefix) if (cctx->prefix)
OPENSSL_free(cctx->prefix); OPENSSL_free(cctx->prefix);
OPENSSL_free(cctx); OPENSSL_free(cctx);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册