diff options
Diffstat (limited to 'cpp/src/IceSSL/TransceiverI.cpp')
-rw-r--r-- | cpp/src/IceSSL/TransceiverI.cpp | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/cpp/src/IceSSL/TransceiverI.cpp b/cpp/src/IceSSL/TransceiverI.cpp index f2fc567e1e8..28f59e93756 100644 --- a/cpp/src/IceSSL/TransceiverI.cpp +++ b/cpp/src/IceSSL/TransceiverI.cpp @@ -8,6 +8,7 @@ // ********************************************************************** #include <IceSSL/TransceiverI.h> +#include <IceSSL/ConnectionInfo.h> #include <IceSSL/Instance.h> #include <IceSSL/Util.h> #include <Ice/Communicator.h> @@ -777,6 +778,50 @@ IceSSL::TransceiverI::toString() const return _desc; } +Ice::ConnectionInfoPtr +IceSSL::TransceiverI::getInfo() const +{ + assert(_fd != INVALID_SOCKET && _ssl != 0); + + SSLConnectionInfoPtr info = new SSLConnectionInfo(); + IceInternal::fdToAddressAndPort(_fd, info->localAddress, info->localPort, info->remoteAddress, info->remotePort); + + // + // On the client side, SSL_get_peer_cert_chain returns the entire chain of certs. + // On the server side, the peer certificate must be obtained separately. + // + // Since we have no clear idea whether the connection is server or client side, + // the peer certificate is obtained separately and compared against the first + // certificate in the chain. If they are not the same, it is added to the chain. + // + X509* cert = SSL_get_peer_certificate(_ssl); + STACK_OF(X509)* chain = SSL_get_peer_cert_chain(_ssl); + if(cert != 0 && (chain == 0 || sk_X509_num(chain) == 0 || cert != sk_X509_value(chain, 0))) + { + CertificatePtr certificate = new Certificate(cert); + info->certs.push_back(certificate->encode()); + } + else + { + X509_free(cert); + } + + if(chain != 0) + { + for(int i = 0; i < sk_X509_num(chain); ++i) + { + // + // Duplicate the certificate since the stack comes straight from the SSL connection. + // + CertificatePtr certificate = new Certificate(X509_dup(sk_X509_value(chain, i))); + info->certs.push_back(certificate->encode()); + } + } + + info->cipher = SSL_get_cipher_name(_ssl); // Nothing needs to be free'd. + return info; +} + void IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer& buf, size_t messageSizeMax) { @@ -786,7 +831,7 @@ IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer& buf, size_t messa } } -ConnectionInfo +IceSSL::ConnectionInfo IceSSL::TransceiverI::getConnectionInfo() const { // |