aboutsummaryrefslogtreecommitdiff
path: root/ssl
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2016-02-06 03:17:23 +0000
committerDr. Stephen Henson <steve@openssl.org>2016-02-06 18:18:28 +0000
commit696178edff89f8df0382af0edbd0f723790a86cc (patch)
tree78902d2aab053ab4df3d4b56db74cc07d8f289af /ssl
parentf3ac50038df0e0739d3bc3da11fdce0dc2939e22 (diff)
downloadopenssl-696178edff89f8df0382af0edbd0f723790a86cc.zip
openssl-696178edff89f8df0382af0edbd0f723790a86cc.tar.gz
openssl-696178edff89f8df0382af0edbd0f723790a86cc.tar.bz2
Add SSL_get0_verified_chain() to return verified chain of peer
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Diffstat (limited to 'ssl')
-rw-r--r--ssl/ssl_cert.c9
-rw-r--r--ssl/ssl_lib.c8
-rw-r--r--ssl/ssl_locl.h6
3 files changed, 21 insertions, 2 deletions
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 2aaf99c..68c8924 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -541,6 +541,15 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
}
s->verify_result = ctx.error;
+ sk_X509_pop_free(s->verified_chain, X509_free);
+ s->verified_chain = NULL;
+ if (X509_STORE_CTX_get_chain(&ctx) != NULL) {
+ s->verified_chain = X509_STORE_CTX_get1_chain(&ctx);
+ if (s->verified_chain == NULL) {
+ SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_MALLOC_FAILURE);
+ i = 0;
+ }
+ }
/* Move peername from the store context params to the SSL handle's */
X509_VERIFY_PARAM_move_peername(s->param, param);
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 1154b71..197a37c 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -715,6 +715,7 @@ SSL *SSL_new(SSL_CTX *ctx)
s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
}
+ s->verified_chain = NULL;
s->verify_result = X509_V_OK;
s->default_passwd_callback = ctx->default_passwd_callback;
@@ -1052,6 +1053,8 @@ void SSL_free(SSL *s)
sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
+ sk_X509_pop_free(s->verified_chain, X509_free);
+
if (s->method != NULL)
s->method->ssl_free(s);
@@ -3822,4 +3825,9 @@ unsigned long SSL_clear_options(SSL *s, unsigned long op)
return s->options &= ~op;
}
+STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s)
+{
+ return s->verified_chain;
+}
+
IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 9a30598..b505309 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -614,7 +614,7 @@ struct ssl_session_st {
/* This is the cert and type for the other end. */
X509 *peer;
int peer_type;
- /* Certificate chain of peer */
+ /* Certificate chain peer sent */
STACK_OF(X509) *peer_chain;
/*
* when app_verify_callback accepts a session where the peer's
@@ -1058,8 +1058,10 @@ struct ssl_st {
unsigned int max_psk_len);
# endif
SSL_CTX *ctx;
- /* extra application data */
+ /* Verified chain of peer */
+ STACK_OF(X509) *verified_chain;
long verify_result;
+ /* extra application data */
CRYPTO_EX_DATA ex_data;
/* for server side, keep the list of CA_dn we can use */
STACK_OF(X509_NAME) *client_CA;