mirror of
https://github.com/openssl/openssl.git
synced 2025-03-19 19:50:42 +08:00
Add SSL_get0_verified_chain() to return verified chain of peer
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
This commit is contained in:
parent
f3ac50038d
commit
696178edff
@ -2,31 +2,45 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SSL_get_peer_cert_chain - get the X509 certificate chain of the peer
|
||||
SSL_get_peer_cert_chain, SSL_get0_verified_chain - get the X509 certificate
|
||||
chain of the peer
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl);
|
||||
STACK_OF(X509) *SSL_get0_verified_chain(const SSL *ssl);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
SSL_get_peer_cert_chain() returns a pointer to STACK_OF(X509) certificates
|
||||
forming the certificate chain of the peer. If called on the client side,
|
||||
forming the certificate chain sent by the peer. If called on the client side,
|
||||
the stack also contains the peer's certificate; if called on the server
|
||||
side, the peer's certificate must be obtained separately using
|
||||
L<SSL_get_peer_certificate(3)>.
|
||||
If the peer did not present a certificate, NULL is returned.
|
||||
|
||||
NB: SSL_get_peer_chain() returns the peer chain as sent by the peer: it
|
||||
only consists of certificates the peer has sent (in the order the peer
|
||||
has sent them) it is B<not> a verified chain.
|
||||
|
||||
SSL_get0_verified_chain() returns the B<verified> certificate chain
|
||||
of the peer including the peer's end entity certificate. It must be called
|
||||
after a session has been successfully established. If peer verification was
|
||||
not successful (as indicated by SSL_get_verify_result() not returning
|
||||
X509_V_OK) the chain may be incomplete or invalid.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
The peer certificate chain is not necessarily available after reusing
|
||||
a session, in which case a NULL pointer is returned.
|
||||
|
||||
The reference count of the STACK_OF(X509) object is not incremented.
|
||||
If the corresponding session is freed, the pointer must not be used
|
||||
any longer.
|
||||
The reference count of each certificate in the returned STACK_OF(X509) object
|
||||
is not incremented and the returned stack may be invalidated by renegotiation.
|
||||
If applications wish to use any certificates in the returned chain
|
||||
indefinitely they must increase the reference counts using X509_up_ref() or
|
||||
obtain a copy of the whole chain with X509_chain_up_ref().
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
@ -47,6 +61,7 @@ The return value points to the certificate chain presented by the peer.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<ssl(3)>, L<SSL_get_peer_certificate(3)>
|
||||
L<ssl(3)>, L<SSL_get_peer_certificate(3)>, L<X509_up_ref(3)>,
|
||||
L<X509_chain_up_ref(3)>
|
||||
|
||||
=cut
|
||||
|
@ -1716,6 +1716,7 @@ __owur OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl);
|
||||
|
||||
void SSL_set_verify_result(SSL *ssl, long v);
|
||||
__owur long SSL_get_verify_result(const SSL *ssl);
|
||||
__owur STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s);
|
||||
|
||||
__owur size_t SSL_get_client_random(const SSL *ssl, unsigned char *out,
|
||||
size_t outlen);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user