summaryrefslogtreecommitdiff
path: root/cpp/src/IceSSL/TransceiverI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IceSSL/TransceiverI.cpp')
-rw-r--r--cpp/src/IceSSL/TransceiverI.cpp47
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
{
//