summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Glacier/GlacierI.cpp58
-rw-r--r--cpp/src/Glacier/GlacierI.h5
-rw-r--r--cpp/src/Ice/SslCertificateVerifier.cpp20
-rw-r--r--cpp/src/Ice/SslCertificateVerifier.h39
-rw-r--r--cpp/src/Ice/SslCertificateVerifierF.h39
-rw-r--r--cpp/src/Ice/SslCertificateVerifierOpenSSL.cpp44
-rw-r--r--cpp/src/Ice/SslCertificateVerifierOpenSSL.h50
-rw-r--r--cpp/src/Ice/SslConnection.cpp11
-rw-r--r--cpp/src/Ice/SslConnection.h18
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSL.cpp146
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSL.h35
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSLClient.cpp6
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSLClient.h2
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSLF.h42
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSLServer.cpp6
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSLServer.h2
-rw-r--r--cpp/src/Ice/SslFactory.cpp33
-rw-r--r--cpp/src/Ice/SslFactory.h16
-rw-r--r--cpp/src/Ice/SslRSACertificateGen.cpp253
-rw-r--r--cpp/src/Ice/SslRSAKeyPair.cpp181
-rw-r--r--cpp/src/Ice/SslSystem.cpp55
-rw-r--r--cpp/src/Ice/SslSystem.h24
-rw-r--r--cpp/src/Ice/SslSystemOpenSSL.cpp415
-rw-r--r--cpp/src/Ice/SslSystemOpenSSL.h2
-rw-r--r--cpp/src/Ice/ice.dsp64
-rw-r--r--cpp/src/IceUtil/Base64.cpp265
-rw-r--r--cpp/src/IceUtil/iceutil.dsp8
27 files changed, 1429 insertions, 410 deletions
diff --git a/cpp/src/Glacier/GlacierI.cpp b/cpp/src/Glacier/GlacierI.cpp
index 31402be91f3..463339d9bf6 100644
--- a/cpp/src/Glacier/GlacierI.cpp
+++ b/cpp/src/Glacier/GlacierI.cpp
@@ -10,7 +10,8 @@
#include <IceUtil/UUID.h>
#include <Glacier/GlacierI.h>
-#include <fcntl.h>
+#include <fcntl.h>
+#include <Ice/SslRSAKeyPair.h>
//#include <sys/wait.h>
#ifdef WIN32
@@ -19,7 +20,10 @@
using namespace std;
using namespace Ice;
-using namespace Glacier;
+using namespace Glacier;
+
+using IceSecurity::Ssl::OpenSSL::RSAKeyPairPtr;
+
Glacier::StarterI::StarterI(const CommunicatorPtr& communicator) :
_communicator(communicator),
@@ -27,6 +31,16 @@ Glacier::StarterI::StarterI(const CommunicatorPtr& communicator) :
_properties(_communicator->getProperties())
{
_traceLevel = atoi(_properties->getProperty("Glacier.Trace.Starter").c_str());
+
+ // Set up the Certificate Generation context
+ _certContext.setCountry(_properties->getProperty("Glacier.Starter.Certificate.Country"));
+ _certContext.setStateProvince(_properties->getProperty("Glacier.Starter.Certificate.StateProvince"));
+ _certContext.setLocality(_properties->getProperty("Glacier.Starter.Certificate.Locality"));
+ _certContext.setOrganization(_properties->getProperty("Glacier.Starter.Certificate.Organization"));
+ _certContext.setOrgainizationalUnit(_properties->getProperty("Glacier.Starter.Certificate.OranizationalUnit"));
+ _certContext.setCommonName(_properties->getProperty("Glacier.Starter.Certificate.CommonName"));
+ _certContext.setBitStrength(atoi(_properties->getProperty("Glacier.Starter.Certificate.BitStrength").c_str()));
+ _certContext.setSecondsValid(atol(_properties->getProperty("Glacier.Starter.Certificate.SecondsValid").c_str()));
}
void
@@ -49,7 +63,45 @@ Glacier::StarterI::startRouter(const string& userId, const string& password, con
//
// TODO: userId/password check
//
-
+
+ //
+ // Create a certificate for the Client and the Router
+ //
+ RSAKeyPairPtr clientKeyPair = _certificateGenerator.generate(_certContext);
+ RSAKeyPairPtr routerKeyPair = _certificateGenerator.generate(_certContext);
+
+ // NOTE: These will probably be returned from this method, I would assume.
+ ByteSeq clientPrivateKey;
+ ByteSeq clientCertificate;
+ ByteSeq routerCertificate;
+
+ clientKeyPair.keyToByteSeq(clientPrivateKey);
+ clientKeyPair.certToByteSeq(clientCertificate);
+ routerKeyPair.certToByteSeq(routerCertificate);
+
+ // routerPrivateKeyBase64 and routerCertificateBase64 are passed to the
+ // router as the values for the properties
+ // * Ice.Security.Ssl.Overrides.Server.RSA.PrivateKey
+ // * Ice.Security.Ssl.Overrides.Server.RSA.Certificate
+ // respectively.
+ //
+ // If the router is to act as a client to the Client as well, then
+ // these values should also be passed into the router as the properties
+ // * Ice.Security.Ssl.Overrides.Client.RSA.PrivateKey
+ // * Ice.Security.Ssl.Overrides.Client.RSA.Certificate
+ // respectively.
+ //
+ // The value of clientCertificateBase64 should be passed in to the router
+ // in the property
+ // * Glacier.Router.ClientCertificate
+ string routerPrivateKeyBase64;
+ string routerCertificateBase64;
+ string clientCertificateBase64;
+
+ routerKeyPair.keyToBase64(routerPrivateKeyBase64);
+ routerKeyPair.certToBase64(routerCertificateBase64);
+ clientKeyPair.certToBase64(clientCertificateBase64);
+
//
// Start a router
//
diff --git a/cpp/src/Glacier/GlacierI.h b/cpp/src/Glacier/GlacierI.h
index f28d542f560..455701dd486 100644
--- a/cpp/src/Glacier/GlacierI.h
+++ b/cpp/src/Glacier/GlacierI.h
@@ -12,6 +12,7 @@
#define GLACIER_GLACIER_I_H
#include <Ice/Ice.h>
+#include <Ice/SslRSACertificateGen.h>
#include <Glacier/Glacier.h>
namespace Glacier
@@ -32,7 +33,9 @@ private:
Ice::CommunicatorPtr _communicator;
Ice::LoggerPtr _logger;
Ice::PropertiesPtr _properties;
- int _traceLevel;
+ int _traceLevel;
+ RSACertificateGenContext _certContext;
+ RSACertificateGen _certificateGenerator;
};
}
diff --git a/cpp/src/Ice/SslCertificateVerifier.cpp b/cpp/src/Ice/SslCertificateVerifier.cpp
new file mode 100644
index 00000000000..064bd0a6fcf
--- /dev/null
+++ b/cpp/src/Ice/SslCertificateVerifier.cpp
@@ -0,0 +1,20 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/SslCertificateVerifier.h>
+
+void ::IceInternal::incRef(::IceSecurity::Ssl::CertificateVerifier* p) { p->__incRef(); }
+void ::IceInternal::decRef(::IceSecurity::Ssl::CertificateVerifier* p) { p->__decRef(); }
+
+IceSecurity::Ssl::CertificateVerifier::~CertificateVerifier()
+{
+}
+
+
diff --git a/cpp/src/Ice/SslCertificateVerifier.h b/cpp/src/Ice/SslCertificateVerifier.h
new file mode 100644
index 00000000000..c93d7b56c8a
--- /dev/null
+++ b/cpp/src/Ice/SslCertificateVerifier.h
@@ -0,0 +1,39 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_CERTIFICATE_VERIFIER_H
+#define ICE_SSL_CERTIFICATE_VERIFIER_H
+
+#include <IceUtil/Shared.h>
+#include <Ice/SslCertificateVerifierF.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+using IceUtil::Shared;
+
+class CertificateVerifier : public Shared
+{
+
+public:
+ virtual ~CertificateVerifier();
+
+};
+
+}
+
+}
+
+#endif
+
+
diff --git a/cpp/src/Ice/SslCertificateVerifierF.h b/cpp/src/Ice/SslCertificateVerifierF.h
new file mode 100644
index 00000000000..26e91ccd9f2
--- /dev/null
+++ b/cpp/src/Ice/SslCertificateVerifierF.h
@@ -0,0 +1,39 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_CERTIFICATE_VERIFIER_F_H
+#define ICE_SSL_CERTIFICATE_VERIFIER_F_H
+
+#include <Ice/Handle.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+class CertificateVerifier;
+typedef IceInternal::Handle<CertificateVerifier> CertificateVerifierPtr;
+
+}
+
+}
+
+namespace IceInternal
+{
+
+void incRef(::IceSecurity::Ssl::CertificateVerifier*);
+void decRef(::IceSecurity::Ssl::CertificateVerifier*);
+
+}
+
+#endif
+
+
diff --git a/cpp/src/Ice/SslCertificateVerifierOpenSSL.cpp b/cpp/src/Ice/SslCertificateVerifierOpenSSL.cpp
new file mode 100644
index 00000000000..faaeccffd61
--- /dev/null
+++ b/cpp/src/Ice/SslCertificateVerifierOpenSSL.cpp
@@ -0,0 +1,44 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/SslCertificateVerifierOpenSSL.h>
+
+IceSecurity::Ssl::OpenSSL::CertificateVerifier::~CertificateVerifier()
+{
+}
+
+int
+IceSecurity::Ssl::OpenSSL::DefaultCertificateVerifier::verify(int preVerifyOkay,
+ X509_STORE_CTX* x509StoreContext,
+ SSL* sslConnection)
+{
+ //
+ // Default verification steps.
+ //
+
+ int verifyError = X509_STORE_CTX_get_error(x509StoreContext);
+ int errorDepth = X509_STORE_CTX_get_error_depth(x509StoreContext);
+ int verifyDepth = SSL_get_verify_depth(sslConnection);
+
+ // Verify Depth was set
+ if (verifyError != X509_V_OK)
+ {
+ // If we have no errors so far, and the certificate chain is too long
+ if ((verifyDepth != -1) && (verifyDepth < errorDepth))
+ {
+ verifyError = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+ }
+
+ // If we have ANY errors, we bail out.
+ preVerifyOkay = 0;
+ }
+
+ return preVerifyOkay;
+}
diff --git a/cpp/src/Ice/SslCertificateVerifierOpenSSL.h b/cpp/src/Ice/SslCertificateVerifierOpenSSL.h
new file mode 100644
index 00000000000..edbd5f5209e
--- /dev/null
+++ b/cpp/src/Ice/SslCertificateVerifierOpenSSL.h
@@ -0,0 +1,50 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_CERTIFICATE_VERIFIER_OPENSSL_H
+#define ICE_SSL_CERTIFICATE_VERIFIER_OPENSSL_H
+
+#include <Ice/SslCertificateVerifier.h>
+#include <openssl/ssl.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+namespace OpenSSL
+{
+
+class CertificateVerifier : public IceSecurity::Ssl::CertificateVerifier
+{
+
+public:
+ virtual ~CertificateVerifier();
+
+ virtual int verify(int, X509_STORE_CTX*, SSL*) = 0;
+};
+
+class DefaultCertificateVerifier : public CertificateVerifier
+{
+
+public:
+ virtual int verify(int, X509_STORE_CTX*, SSL*);
+};
+
+}
+
+}
+
+}
+
+#endif
+
+
diff --git a/cpp/src/Ice/SslConnection.cpp b/cpp/src/Ice/SslConnection.cpp
index 1cd95218b24..1c490682323 100644
--- a/cpp/src/Ice/SslConnection.cpp
+++ b/cpp/src/Ice/SslConnection.cpp
@@ -12,4 +12,13 @@
void ::IceInternal::incRef(::IceSecurity::Ssl::Connection* p) { p->__incRef(); }
void ::IceInternal::decRef(::IceSecurity::Ssl::Connection* p) { p->__decRef(); }
-
+
+IceSecurity::Ssl::Connection::Connection(const CertificateVerifierPtr& certificateVerifier) :
+ _certificateVerifier(certificateVerifier)
+{
+}
+
+IceSecurity::Ssl::Connection::~Connection()
+{
+}
+
diff --git a/cpp/src/Ice/SslConnection.h b/cpp/src/Ice/SslConnection.h
index dec02ce6085..1a75f11ca95 100644
--- a/cpp/src/Ice/SslConnection.h
+++ b/cpp/src/Ice/SslConnection.h
@@ -15,7 +15,8 @@
#include <Ice/Buffer.h>
#include <Ice/TraceLevelsF.h>
#include <Ice/LoggerF.h>
-#include <Ice/SslConnectionF.h>
+#include <Ice/SslConnectionF.h>
+#include <Ice/SslCertificateVerifierF.h>
namespace IceSecurity
{
@@ -30,17 +31,20 @@ using Ice::LoggerPtr;
class Connection : public Shared
{
-public:
-
- virtual ~Connection() { };
-
+public:
+ Connection(const CertificateVerifierPtr&);
+ virtual ~Connection();
+
virtual void shutdown() = 0;
virtual int read(Buffer&, int) = 0;
virtual int write(Buffer&, int) = 0;
- virtual void setTrace(TraceLevelsPtr) = 0;
- virtual void setLogger(LoggerPtr) = 0;
+ virtual void setTrace(const TraceLevelsPtr&) = 0;
+ virtual void setLogger(const LoggerPtr&) = 0;
+
+protected:
+ CertificateVerifierPtr _certificateVerifier;
};
}
diff --git a/cpp/src/Ice/SslConnectionOpenSSL.cpp b/cpp/src/Ice/SslConnectionOpenSSL.cpp
index c2a90e42d76..28db8c164e0 100644
--- a/cpp/src/Ice/SslConnectionOpenSSL.cpp
+++ b/cpp/src/Ice/SslConnectionOpenSSL.cpp
@@ -26,7 +26,9 @@
#include <Ice/SslFactory.h>
#include <Ice/SslConnection.h>
#include <Ice/SslConnectionOpenSSL.h>
-#include <Ice/SslSystemOpenSSL.h>
+#include <Ice/SslSystemOpenSSL.h>
+#include <Ice/SslCertificateVerifierOpenSSL.h>
+#include <Ice/SslOpenSSLUtils.h>
#include <Ice/TraceLevels.h>
#include <Ice/Logger.h>
@@ -42,12 +44,24 @@ using IceSecurity::Ssl::SystemPtr;
////////////////////////////////
////////// Connection //////////
////////////////////////////////
+
+//
+// Static Member Initialization
+//
+IceSecurity::Ssl::OpenSSL::SslConnectionMap IceSecurity::Ssl::OpenSSL::Connection::_connectionMap;
+::IceUtil::Mutex IceSecurity::Ssl::OpenSSL::Connection::_connectionRepositoryMutex;
//
// Public Methods
//
-IceSecurity::Ssl::OpenSSL::Connection::Connection(SSL* sslConnection, const SystemPtr& system) :
+void ::IceInternal::incRef(::IceSecurity::Ssl::OpenSSL::Connection* p) { p->__incRef(); }
+void ::IceInternal::decRef(::IceSecurity::Ssl::OpenSSL::Connection* p) { p->__decRef(); }
+
+IceSecurity::Ssl::OpenSSL::Connection::Connection(const CertificateVerifierPtr& certificateVerifier,
+ SSL* sslConnection,
+ const SystemPtr& system) :
+ IceSecurity::Ssl::Connection(certificateVerifier),
_sslConnection(sslConnection),
_system(system)
{
@@ -61,7 +75,10 @@ IceSecurity::Ssl::OpenSSL::Connection::Connection(SSL* sslConnection, const Syst
_initWantWrite = 0;
// None configured, default to indicated timeout
- _handshakeReadTimeout = 0;
+ _handshakeReadTimeout = 0;
+
+ // Set up the SSL to be able to refer back to our connection object.
+ addConnection(_sslConnection, this);
}
IceSecurity::Ssl::OpenSSL::Connection::~Connection()
@@ -70,6 +87,7 @@ IceSecurity::Ssl::OpenSSL::Connection::~Connection()
if (_sslConnection != 0)
{
+ removeConnection(_sslConnection);
Factory::removeSystemHandle(_sslConnection);
SSL_free(_sslConnection);
_sslConnection = 0;
@@ -108,6 +126,110 @@ IceSecurity::Ssl::OpenSSL::Connection::shutdown()
ICE_METHOD_RET("OpenSSL::Connection::shutdown()");
}
+void
+IceSecurity::Ssl::OpenSSL::Connection::setTrace(const TraceLevelsPtr& traceLevels)
+{
+ _traceLevels = traceLevels;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::setLogger(const LoggerPtr& traceLevels)
+{
+ _logger = traceLevels;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::setHandshakeReadTimeout(int timeout)
+{
+ _handshakeReadTimeout = timeout;
+}
+
+IceSecurity::Ssl::OpenSSL::ConnectionPtr
+IceSecurity::Ssl::OpenSSL::Connection::getConnection(SSL* sslPtr)
+{
+ IceUtil::Mutex::Lock sync(_connectionRepositoryMutex);
+
+ assert(sslPtr);
+
+ Connection* connection = _connectionMap[sslPtr];
+
+ assert(connection);
+
+ return ConnectionPtr(connection);
+}
+
+int
+IceSecurity::Ssl::OpenSSL::Connection::verifyCertificate(int preVerifyOkay, X509_STORE_CTX* x509StoreContext)
+{
+ // Get the verifier, make sure it is for OpenSSL connections
+ IceSecurity::Ssl::OpenSSL::CertificateVerifier* verifier;
+ verifier = dynamic_cast<IceSecurity::Ssl::OpenSSL::CertificateVerifier*>(_certificateVerifier.get());
+
+ // Check to make sure we have a proper verifier for the operation.
+ if (!verifier)
+ {
+ // TODO: Throw exception here
+ // throw SslIncorrectVerifierTypeException(__FILE__, __LINE__);
+ return 0;
+ }
+
+ // Use the verifier to verify the certificate
+ preVerifyOkay = verifier->verify(preVerifyOkay, x509StoreContext, _sslConnection);
+
+ // Only if ICE_PROTOCOL level logging is on do we worry about this.
+ if (ICE_SECURITY_LEVEL_PROTOCOL)
+ {
+ char buf[256];
+
+ X509* err_cert = X509_STORE_CTX_get_current_cert(x509StoreContext);
+ int verifyError = X509_STORE_CTX_get_error(x509StoreContext);
+ int depth = X509_STORE_CTX_get_error_depth(x509StoreContext);
+
+ X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
+
+ ostringstream outStringStream;
+
+ outStringStream << "depth = " << depth << ":" << buf << endl;
+
+ if (!preVerifyOkay)
+ {
+ outStringStream << "verify error: num = " << verifyError << " : "
+ << X509_verify_cert_error_string(verifyError) << endl;
+
+ }
+
+ switch (verifyError)
+ {
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ {
+ X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, sizeof(buf));
+ outStringStream << "issuer = " << buf << endl;
+ break;
+ }
+
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ {
+ outStringStream << "notBefore = " << getASN1time(X509_get_notBefore(err_cert)) << endl;
+ break;
+ }
+
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ {
+ outStringStream << "notAfter = " << getASN1time(X509_get_notAfter(err_cert)) << endl;
+ break;
+ }
+ }
+
+ outStringStream << "verify return = " << preVerifyOkay << endl;
+
+ ICE_PROTOCOL(outStringStream.str());
+ }
+
+ return preVerifyOkay;
+}
+
//
// Protected Methods
//
@@ -709,7 +831,23 @@ IceSecurity::Ssl::OpenSSL::Connection::sslGetErrors()
return errorMessage;
}
-
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::addConnection(SSL* sslPtr, Connection* connection)
+{
+ assert(sslPtr);
+ assert(connection);
+ _connectionMap[sslPtr] = connection;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::removeConnection(SSL* sslPtr)
+{
+ IceUtil::Mutex::Lock sync(_connectionRepositoryMutex);
+ assert(sslPtr);
+ _connectionMap.erase(sslPtr);
+}
+
void
IceSecurity::Ssl::OpenSSL::Connection::showCertificateChain(BIO* bio)
{
diff --git a/cpp/src/Ice/SslConnectionOpenSSL.h b/cpp/src/Ice/SslConnectionOpenSSL.h
index c46699549a3..c0eb5cd182b 100644
--- a/cpp/src/Ice/SslConnectionOpenSSL.h
+++ b/cpp/src/Ice/SslConnectionOpenSSL.h
@@ -11,10 +11,13 @@
#ifndef ICE_SSL_CONNECTION_OPENSSL_H
#define ICE_SSL_CONNECTION_OPENSSL_H
+#include <map>
#include <openssl/ssl.h>
#include <IceUtil/Mutex.h>
#include <Ice/SslConnection.h>
-#include <Ice/SslSystemF.h>
+#include <Ice/SslSystemF.h>
+#include <Ice/SslConnectionOpenSSLF.h>
+#include <Ice/SslCertificateVerifierF.h>
namespace IceSecurity
{
@@ -27,7 +30,7 @@ namespace OpenSSL
using namespace Ice;
using namespace std;
-
+
class SafeFlag
{
public:
@@ -106,12 +109,19 @@ private:
bool _ownHandshake;
SafeFlag& _flag;
};
-
+
+// NOTE: This is a mapping from SSL* to Connection*, for use with the verifyCallback.
+// I have purposely not used ConnectionPtr here, as connections register themselves
+// with this map on construction and unregister themselves in the destructor. If
+// this map used ConnectionPtr, Connection instances would never destruct as there
+// would always be a reference to them from the map.
+typedef map<SSL*, Connection*> SslConnectionMap;
+
class Connection : public IceSecurity::Ssl::Connection
{
public:
- Connection(SSL*, const SystemPtr&);
+ Connection(const CertificateVerifierPtr&, SSL*, const SystemPtr&);
virtual ~Connection();
virtual void shutdown();
@@ -121,10 +131,15 @@ public:
virtual int init(int timeout = 0) = 0;
- void setTrace(TraceLevelsPtr traceLevels) { _traceLevels = traceLevels; };
- void setLogger(LoggerPtr traceLevels) { _logger = traceLevels; };
+ void setTrace(const TraceLevelsPtr& traceLevels);
+ void setLogger(const LoggerPtr& traceLevels);
- void setHandshakeReadTimeout(int timeout) { _handshakeReadTimeout = timeout; };
+ void setHandshakeReadTimeout(int timeout);
+
+ static ConnectionPtr getConnection(SSL*);
+
+ // Callback from OpenSSL for purposes of certificate verification
+ int verifyCertificate(int, X509_STORE_CTX*);
protected:
@@ -152,6 +167,9 @@ protected:
// Retrieves errors from the OpenSSL library.
string sslGetErrors();
+
+ static void addConnection(SSL*, Connection*);
+ static void removeConnection(SSL*);
virtual void showConnectionInfo() = 0;
@@ -164,6 +182,9 @@ protected:
void showClientCAList(BIO*, const char*);
void setLastError(int errorCode) { _lastError = errorCode; };
+
+ static SslConnectionMap _connectionMap;
+ static ::IceUtil::Mutex _connectionRepositoryMutex;
// Pointer to the OpenSSL Connection structure.
SSL* _sslConnection;
diff --git a/cpp/src/Ice/SslConnectionOpenSSLClient.cpp b/cpp/src/Ice/SslConnectionOpenSSLClient.cpp
index 58e43fa8fb5..a6278cd717f 100644
--- a/cpp/src/Ice/SslConnectionOpenSSLClient.cpp
+++ b/cpp/src/Ice/SslConnectionOpenSSLClient.cpp
@@ -37,8 +37,10 @@ using std::dec;
// Public Methods
//
-IceSecurity::Ssl::OpenSSL::ClientConnection::ClientConnection(SSL* connection, const SystemPtr& system) :
- Connection(connection, system)
+IceSecurity::Ssl::OpenSSL::ClientConnection::ClientConnection(const CertificateVerifierPtr& certificateVerifier,
+ SSL* connection,
+ const SystemPtr& system) :
+ Connection(certificateVerifier, connection, system)
{
}
diff --git a/cpp/src/Ice/SslConnectionOpenSSLClient.h b/cpp/src/Ice/SslConnectionOpenSSLClient.h
index da16597f798..9faa82df08a 100644
--- a/cpp/src/Ice/SslConnectionOpenSSLClient.h
+++ b/cpp/src/Ice/SslConnectionOpenSSLClient.h
@@ -30,7 +30,7 @@ class ClientConnection : public Connection
{
public:
- ClientConnection(SSL*, const SystemPtr&);
+ ClientConnection(const CertificateVerifierPtr&, SSL*, const SystemPtr&);
virtual ~ClientConnection();
virtual void shutdown();
virtual int init(int timeout = 0);
diff --git a/cpp/src/Ice/SslConnectionOpenSSLF.h b/cpp/src/Ice/SslConnectionOpenSSLF.h
new file mode 100644
index 00000000000..c5f23022411
--- /dev/null
+++ b/cpp/src/Ice/SslConnectionOpenSSLF.h
@@ -0,0 +1,42 @@
+// **********************************************************************
+//
+// Copyright (c) 2002
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_CONNECTION_OPENSSL_F_H
+#define ICE_SSL_CONNECTION_OPENSSL_F_H
+
+#include <Ice/Handle.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+namespace OpenSSL
+{
+
+class Connection;
+typedef IceInternal::Handle<Connection> ConnectionPtr;
+
+}
+
+}
+
+}
+
+namespace IceInternal
+{
+
+void incRef(::IceSecurity::Ssl::OpenSSL::Connection*);
+void decRef(::IceSecurity::Ssl::OpenSSL::Connection*);
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslConnectionOpenSSLServer.cpp b/cpp/src/Ice/SslConnectionOpenSSLServer.cpp
index d58e797e1c9..66e3816a8ff 100644
--- a/cpp/src/Ice/SslConnectionOpenSSLServer.cpp
+++ b/cpp/src/Ice/SslConnectionOpenSSLServer.cpp
@@ -38,8 +38,10 @@ using std::dec;
// Public Methods
//
-IceSecurity::Ssl::OpenSSL::ServerConnection::ServerConnection(SSL* connection, const SystemPtr& system) :
- Connection(connection, system)
+IceSecurity::Ssl::OpenSSL::ServerConnection::ServerConnection(const CertificateVerifierPtr& certificateVerifier,
+ SSL* connection,
+ const SystemPtr& system) :
+ Connection(certificateVerifier, connection, system)
{
}
diff --git a/cpp/src/Ice/SslConnectionOpenSSLServer.h b/cpp/src/Ice/SslConnectionOpenSSLServer.h
index 7498a186551..c24e703aafb 100644
--- a/cpp/src/Ice/SslConnectionOpenSSLServer.h
+++ b/cpp/src/Ice/SslConnectionOpenSSLServer.h
@@ -30,7 +30,7 @@ class ServerConnection : public Connection
{
public:
- ServerConnection(SSL*, const SystemPtr&);
+ ServerConnection(const CertificateVerifierPtr&, SSL*, const SystemPtr&);
virtual ~ServerConnection();
virtual void shutdown();
virtual int init(int timeout = 0);
diff --git a/cpp/src/Ice/SslFactory.cpp b/cpp/src/Ice/SslFactory.cpp
index 63ac8f9899d..2210a146d8c 100644
--- a/cpp/src/Ice/SslFactory.cpp
+++ b/cpp/src/Ice/SslFactory.cpp
@@ -35,18 +35,17 @@ namespace IceSecurity
namespace Ssl
{
-
-extern "C"
-{
- void lockingCallback(int, int, const char*, int);
-}
-
// Static member instantiations.
IceUtil::Mutex Factory::_systemRepositoryMutex;
SystemMap Factory::_systemRepository;
SslHandleSystemMap Factory::_sslHandleSystemRepository;
int Factory::_evict = 0;
+extern "C"
+{
+ void lockingCallback(int, int, const char*, int);
+}
+
class SslLockKeeper
{
@@ -83,9 +82,8 @@ void IceSecurity::Ssl::lockingCallback(int mode, int type, const char *file, int
}
}
-
IceSecurity::Ssl::SystemPtr
-IceSecurity::Ssl::Factory::getSystem(string& systemIdentifier)
+IceSecurity::Ssl::Factory::getSystem(const string& systemIdentifier)
{
IceUtil::Mutex::Lock sync(_systemRepositoryMutex);
@@ -145,7 +143,6 @@ IceSecurity::Ssl::Factory::getSystemFromHandle(void* sslHandle)
return system;
}
-
void
IceSecurity::Ssl::Factory::reapSystems()
{
@@ -194,3 +191,21 @@ IceSecurity::Ssl::Factory::reapSystems()
}
}
+void
+IceSecurity::Ssl::setSystemCertificateVerifier(const string& systemIdentifier,
+ CertificateVerifierType verifierType,
+ const CertificateVerifierPtr& certificateVerifier)
+{
+ SystemPtr sslSystem = Factory::getSystem(systemIdentifier);
+
+ if ((verifierType == Client) || (verifierType == ClientServer))
+ {
+ sslSystem->setClientCertificateVerifier(certificateVerifier);
+ }
+
+ if ((verifierType == Server) || (verifierType == ClientServer))
+ {
+ sslSystem->setServerCertificateVerifier(certificateVerifier);
+ }
+}
+
diff --git a/cpp/src/Ice/SslFactory.h b/cpp/src/Ice/SslFactory.h
index 6216c0c7ad3..cd56012d201 100644
--- a/cpp/src/Ice/SslFactory.h
+++ b/cpp/src/Ice/SslFactory.h
@@ -14,7 +14,8 @@
#include <string>
#include <map>
#include <IceUtil/Mutex.h>
-#include <Ice/SslSystemF.h>
+#include <Ice/SslSystemF.h>
+#include <Ice/SslCertificateVerifierF.h>
namespace IceSecurity
{
@@ -38,7 +39,7 @@ class Factory
{
public:
- static SystemPtr getSystem(string&);
+ static SystemPtr getSystem(const string&);
// System Handle related methods
static void addSystemHandle(void*, const SystemPtr&);
@@ -53,6 +54,17 @@ private:
static void reapSystems();
};
+
+typedef enum
+{
+ None = 0,
+ Client,
+ Server,
+ ClientServer
+} CertificateVerifierType;
+
+
+void setSystemCertificateVerifier(const string&, CertificateVerifierType, const CertificateVerifierPtr&);
}
diff --git a/cpp/src/Ice/SslRSACertificateGen.cpp b/cpp/src/Ice/SslRSACertificateGen.cpp
new file mode 100644
index 00000000000..64f2cf16eff
--- /dev/null
+++ b/cpp/src/Ice/SslRSACertificateGen.cpp
@@ -0,0 +1,253 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Config.h>
+#include <Ice/SslRSACertificateGen.h>
+#include <Ice/SslJanitors.h>
+#include <Ice/SslRSAKeyPair.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+using std::string;
+using std::back_inserter;
+
+using namespace IceSecurity::Ssl::OpenSSL;
+
+long
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::minutesToSeconds(long minutes)
+{
+ return minutes * 60L;
+}
+
+long
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::hoursToSeconds(long hours)
+{
+ return minutesToSeconds(hours * 60L);
+}
+
+long
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::daysToSeconds(long days)
+{
+ return hoursToSeconds(days * 24L);
+}
+
+long
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::weeksToSeconds(long weeks)
+{
+ return daysToSeconds(weeks * 7L);
+}
+
+long
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::yearsToSeconds(long years)
+{
+ return weeksToSeconds(years * 365L);
+}
+
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::RSACertificateGenContext() :
+ _modulusLength(0),
+ _secondsValid(0)
+{
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::setCountry(const string& country)
+{
+ _country = country;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::setStateProvince(const string& stateProvince)
+{
+ _stateProvince = stateProvince;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::setLocality(const string& locality)
+{
+ _locality = locality;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::setOrganization(const string& organization)
+{
+ _organization = organization;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::setOrgainizationalUnit(const string& organizationalUnit)
+{
+ _organizationalUnit = organizationalUnit;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::setCommonName(const string& commonName)
+{
+ _commonName = commonName;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::setBitStrength(int bitStrength)
+{
+ _modulusLength = bitStrength;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::setSecondsValid(long secondsValid)
+{
+ _secondsValid = secondsValid;
+}
+
+unsigned char*
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::getCountry() const
+{
+ return reinterpret_cast<unsigned char *>(const_cast<char*>(_country.c_str()));
+}
+
+unsigned char*
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::getStateProvince() const
+{
+ return reinterpret_cast<unsigned char *>(const_cast<char*>(_stateProvince.c_str()));
+}
+
+unsigned char*
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::getLocality() const
+{
+ return reinterpret_cast<unsigned char *>(const_cast<char*>(_locality.c_str()));
+}
+
+unsigned char*
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::getOrganization() const
+{
+ return reinterpret_cast<unsigned char *>(const_cast<char*>(_organization.c_str()));
+}
+
+unsigned char*
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::getOrgainizationalUnit() const
+{
+ return reinterpret_cast<unsigned char *>(const_cast<char*>(_organizationalUnit.c_str()));
+}
+
+unsigned char*
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::getCommonName() const
+{
+ return reinterpret_cast<unsigned char *>(const_cast<char*>(_commonName.c_str()));
+}
+
+int
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::getModulusLength() const
+{
+ return _modulusLength;
+}
+
+long
+IceSecurity::Ssl::OpenSSL::RSACertificateGenContext::getSecondsValid() const
+{
+ return _secondsValid;
+}
+
+IceSecurity::Ssl::OpenSSL::RSACertificateGen::RSACertificateGen()
+{
+ ERR_load_crypto_strings();
+}
+
+IceSecurity::Ssl::OpenSSL::RSACertificateGen::~RSACertificateGen()
+{
+}
+
+IceSecurity::Ssl::OpenSSL::RSAKeyPair*
+IceSecurity::Ssl::OpenSSL::RSACertificateGen::generate(const RSACertificateGenContext& context)
+{
+ // Generate an RSA key pair.
+ RSAJanitor rsaJanitor(RSA_generate_key(context.getModulusLength(), RSA_F4, 0, 0));
+ RSA* rsaKeyPair = rsaJanitor.get();
+
+ assert(rsaKeyPair);
+
+ // Do this if we already have an RSA*
+ EVP_PKEYJanitor evpPkeyJanitor(EVP_PKEY_new());
+ EVP_PKEY* pkey = evpPkeyJanitor.get();
+ assert(pkey);
+ EVP_PKEY_assign_RSA(pkey, rsaKeyPair);
+
+ // The RSA structure now belongs (temporarily) to the EVP_PKEY
+ rsaJanitor.clear();
+
+ // Create a signing request
+ X509_REQJanitor x509ReqJanitor(X509_REQ_new());
+ X509_REQ* signingRequest = x509ReqJanitor.get();
+ assert(signingRequest);
+
+ X509Janitor x509Janitor(X509_new());
+ X509* x509SelfSigned = x509Janitor.get();
+ assert(x509SelfSigned);
+
+ // Set version to V3
+ assert(X509_set_version(x509SelfSigned, 2));
+
+ ASN1_INTEGER_set(X509_get_serialNumber(x509SelfSigned), 0);
+
+ // NOTE: This is wierd. It looks like, for some reason, that the typedef of
+ // X509_NAME gets lost in this code module. I am using the straight struct
+ // here because X509_NAME isn't here.
+
+ // X509_NAME* subjectName = X509_REQ_get_subject_name(signingRequest);
+ struct X509_name_st* subjectName = X509_REQ_get_subject_name(signingRequest);
+
+ // Set valid time period
+ X509_gmtime_adj(X509_get_notBefore(x509SelfSigned), 0);
+ X509_gmtime_adj(X509_get_notAfter(x509SelfSigned), context.getSecondsValid());
+
+ // Set up subject/issuer name
+ X509_NAME_add_entry_by_txt(subjectName, "C", MBSTRING_ASC, context.getCountry(), -1, -1, 0);
+ X509_NAME_add_entry_by_txt(subjectName, "ST", MBSTRING_ASC, context.getStateProvince(), -1, -1, 0);
+ X509_NAME_add_entry_by_txt(subjectName, "L", MBSTRING_ASC, context.getLocality(), -1, -1, 0);
+ X509_NAME_add_entry_by_txt(subjectName, "O", MBSTRING_ASC, context.getOrganization(), -1, -1, 0);
+ X509_NAME_add_entry_by_txt(subjectName, "OU", MBSTRING_ASC, context.getOrgainizationalUnit(), -1, -1, 0);
+ X509_NAME_add_entry_by_txt(subjectName, "CN", MBSTRING_ASC, context.getCommonName(), -1, -1, 0);
+
+ // Self signed - set issuer and subject names identical
+ X509_set_issuer_name(x509SelfSigned, subjectName);
+ X509_set_subject_name(x509SelfSigned, subjectName);
+
+ // Set the public key in the self signed certificate from the request.
+ X509_set_pubkey(x509SelfSigned, pkey);
+
+ // Sign the public key using an MD5 digest
+ if (!X509_sign(x509SelfSigned, pkey, EVP_md5()))
+ {
+ // TODO: Throw exception here.
+ // throw CertificateSigningException(__FILE__, __LINE__);
+ return 0;
+ }
+
+ // Verify the Signature (paranoia)
+ if (!X509_REQ_verify(signingRequest, pkey))
+ {
+ // TODO: Throw exception here (signature verification)
+ // throw CertificateSignatureException(__FILE__, __LINE__);
+ return 0;
+ }
+
+ // Nasty Hack: Getting the pkey to let go of our rsaKeyPair - we own that.
+ pkey->pkey.ptr = 0;
+
+ // Constructing our object.
+ RSAKeyPair* keyPairPtr = new RSAKeyPair(rsaKeyPair, x509SelfSigned);
+
+ // Don't let them clean up, we're keeping those around.
+ rsaJanitor.clear();
+ x509Janitor.clear();
+
+ return keyPairPtr;
+}
+
+
+
+
diff --git a/cpp/src/Ice/SslRSAKeyPair.cpp b/cpp/src/Ice/SslRSAKeyPair.cpp
new file mode 100644
index 00000000000..c6af6b75767
--- /dev/null
+++ b/cpp/src/Ice/SslRSAKeyPair.cpp
@@ -0,0 +1,181 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Config.h>
+#include <IceUtil/Base64.h>
+#include <Ice/SslRSAKeyPair.h>
+#include <assert.h>
+
+void ::IceInternal::incRef(::IceSecurity::Ssl::OpenSSL::RSAKeyPair* p) { p->__incRef(); }
+void ::IceInternal::decRef(::IceSecurity::Ssl::OpenSSL::RSAKeyPair* p) { p->__decRef(); }
+
+using std::back_inserter;
+using std::string;
+using IceUtil::Base64;
+
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::RSAKeyPair(const string& key, const string& cert)
+{
+ _privateKey = 0;
+ _publicKey = 0;
+
+ ByteSeq keySeq = Base64::decode(key);
+ ByteSeq certSeq = Base64::decode(cert);
+
+ byteSeqToKey(keySeq);
+ byteSeqToCert(certSeq);
+}
+
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::RSAKeyPair(const ByteSeq& keySeq, const ByteSeq& certSeq)
+{
+ _privateKey = 0;
+ _publicKey = 0;
+ byteSeqToKey(keySeq);
+ byteSeqToCert(certSeq);
+}
+
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::~RSAKeyPair()
+{
+ RSA_free(_privateKey);
+ X509_free(_publicKey);
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::keyToBase64(string& b64Key)
+{
+ ByteSeq keySeq;
+ keyToByteSeq(keySeq);
+ b64Key = Base64::encode(keySeq);
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::certToBase64(string& b64Cert)
+{
+ ByteSeq certSeq;
+ certToByteSeq(certSeq);
+ b64Cert = Base64::encode(certSeq);
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::keyToByteSeq(ByteSeq& keySeq)
+{
+ assert(_privateKey);
+
+ // Output the Private Key to a char buffer
+ unsigned int privKeySize = i2d_RSAPrivateKey(_privateKey, 0);
+
+ assert(privKeySize > 0);
+
+ unsigned char* privateKeyBuffer = new unsigned char[privKeySize];
+
+ // We have to do this because i2d_RSAPrivateKey changes the pointer.
+ unsigned char* privKeyBuff = privateKeyBuffer;
+ i2d_RSAPrivateKey(_privateKey, &privKeyBuff);
+
+ ucharToByteSeq(privateKeyBuffer, privKeySize, keySeq);
+
+ delete []privateKeyBuffer;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::certToByteSeq(ByteSeq& certSeq)
+{
+ assert(_publicKey);
+
+ // Output the Public Key to a char buffer
+ unsigned int pubKeySize = i2d_X509(_publicKey, 0);
+
+ assert(pubKeySize > 0);
+
+ unsigned char* publicKeyBuffer = new unsigned char[pubKeySize];
+
+ // We have to do this because i2d_X509_PUBKEY changes the pointer.
+ unsigned char* pubKeyBuff = publicKeyBuffer;
+ int retSize = i2d_X509(_publicKey, &pubKeyBuff);
+
+ ucharToByteSeq(publicKeyBuffer, pubKeySize, certSeq);
+
+ delete []publicKeyBuffer;
+}
+
+RSA*
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::getRSAPrivateKey() const
+{
+ return _privateKey;
+}
+
+X509*
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::getX509PublicKey() const
+{
+ return _publicKey;
+}
+
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::RSAKeyPair(RSA* rsa, X509* x509) :
+ _privateKey(rsa),
+ _publicKey(x509)
+{
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::byteSeqToKey(const ByteSeq& keySeq)
+{
+ unsigned char* privateKeyBuffer = byteSeqToUChar(keySeq);
+ assert(privateKeyBuffer);
+
+ unsigned char* privKeyBuff = privateKeyBuffer;
+ unsigned char** privKeyBuffpp = &privKeyBuff;
+ RSA** rsapp = &_privateKey;
+
+ _privateKey = d2i_RSAPrivateKey(rsapp, privKeyBuffpp, (long)keySeq.size());
+ assert(_privateKey);
+
+ delete []privateKeyBuffer;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::byteSeqToCert(const ByteSeq& certSeq)
+{
+ unsigned char* publicKeyBuffer = byteSeqToUChar(certSeq);
+ assert(publicKeyBuffer);
+
+ // We have to do this because d2i_X509 changes the pointer.
+ unsigned char* pubKeyBuff = publicKeyBuffer;
+ unsigned char** pubKeyBuffpp = &pubKeyBuff;
+
+ X509** x509pp = &_publicKey;
+
+ _publicKey = d2i_X509(x509pp, pubKeyBuffpp, (long)certSeq.size());
+ assert(_publicKey);
+
+ delete []publicKeyBuffer;
+}
+
+
+void
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::ucharToByteSeq(unsigned char* ucharBuffer, int length, ByteSeq& destBuffer)
+{
+ destBuffer.reserve(length);
+ std::copy(ucharBuffer, (ucharBuffer + length), back_inserter(destBuffer));
+}
+
+
+unsigned char*
+IceSecurity::Ssl::OpenSSL::RSAKeyPair::byteSeqToUChar(const ByteSeq& sequence)
+{
+ int seqSize = sequence.size();
+
+ assert(seqSize > 0);
+
+ unsigned char* ucharSeq = new unsigned char[seqSize];
+ unsigned char* ucharPtr = ucharSeq;
+ std::copy(sequence.begin(), sequence.end(), ucharPtr);
+
+ return ucharSeq;
+}
+
diff --git a/cpp/src/Ice/SslSystem.cpp b/cpp/src/Ice/SslSystem.cpp
index c1b5a1fff03..1a18ebb5087 100644
--- a/cpp/src/Ice/SslSystem.cpp
+++ b/cpp/src/Ice/SslSystem.cpp
@@ -11,10 +11,63 @@
#include <string>
#include <Ice/SslSystem.h>
-using namespace std;
+using namespace std;
+using IceSecurity::Ssl::CertificateVerifierPtr;
void ::IceInternal::incRef(::IceSecurity::Ssl::System* p) { p->__incRef(); }
void ::IceInternal::decRef(::IceSecurity::Ssl::System* p) { p->__decRef(); }
+
+//
+// Public Methods
+//
+
+void
+IceSecurity::Ssl::System::setServerCertificateVerifier(const CertificateVerifierPtr& serverVerifier)
+{
+ _serverVerifier = serverVerifier;
+}
+
+void
+IceSecurity::Ssl::System::setClientCertificateVerifier(const CertificateVerifierPtr& clientVerifier)
+{
+ _clientVerifier = clientVerifier;
+}
+
+void
+IceSecurity::Ssl::System::setTrace(const TraceLevelsPtr& traceLevels)
+{
+ _traceLevels = traceLevels;
+}
+
+bool
+IceSecurity::Ssl::System::isTraceSet() const
+{
+ return _traceLevels;
+}
+
+void
+IceSecurity::Ssl::System::setLogger(const LoggerPtr& traceLevels)
+{
+ _logger = traceLevels;
+}
+
+bool
+IceSecurity::Ssl::System::isLoggerSet() const
+{
+ return _logger;
+}
+
+void
+IceSecurity::Ssl::System::setProperties(const PropertiesPtr& properties)
+{
+ _properties = properties;
+}
+
+bool
+IceSecurity::Ssl::System::isPropertiesSet() const
+{
+ return _properties;
+}
//
// Protected Methods
diff --git a/cpp/src/Ice/SslSystem.h b/cpp/src/Ice/SslSystem.h
index f73df892bf8..ae8b596a5c7 100644
--- a/cpp/src/Ice/SslSystem.h
+++ b/cpp/src/Ice/SslSystem.h
@@ -15,7 +15,8 @@
#include <IceUtil/Shared.h>
#include <Ice/SslConnectionF.h>
#include <Ice/Properties.h>
-#include <Ice/SslSystemF.h>
+#include <Ice/SslSystemF.h>
+#include <Ice/SslCertificateVerifierF.h>
#include <Ice/TraceLevels.h>
#include <Ice/LoggerF.h>
@@ -42,16 +43,19 @@ public:
virtual void shutdown() = 0;
virtual Connection* createServerConnection(int) = 0;
- virtual Connection* createClientConnection(int) = 0;
+ virtual Connection* createClientConnection(int) = 0;
+
+ virtual void setServerCertificateVerifier(const CertificateVerifierPtr&);
+ virtual void setClientCertificateVerifier(const CertificateVerifierPtr&);
- void setTrace(TraceLevelsPtr traceLevels) { _traceLevels = traceLevels; };
- bool isTraceSet() const { return _traceLevels; };
+ void setTrace(const TraceLevelsPtr&);
+ bool isTraceSet() const;
- void setLogger(LoggerPtr traceLevels) { _logger = traceLevels; };
- bool isLoggerSet() const { return _logger; };
+ void setLogger(const LoggerPtr&);
+ bool isLoggerSet() const;
- void setProperties(PropertiesPtr properties) { _properties = properties; };
- bool isPropertiesSet() const { return _properties; };
+ void setProperties(const PropertiesPtr&);
+ bool isPropertiesSet() const;
protected:
@@ -60,7 +64,9 @@ protected:
TraceLevelsPtr _traceLevels;
LoggerPtr _logger;
- PropertiesPtr _properties;
+ PropertiesPtr _properties;
+ CertificateVerifierPtr _clientVerifier;
+ CertificateVerifierPtr _serverVerifier;
friend class Factory;
};
diff --git a/cpp/src/Ice/SslSystemOpenSSL.cpp b/cpp/src/Ice/SslSystemOpenSSL.cpp
index d2828615af3..734bb5ecfbd 100644
--- a/cpp/src/Ice/SslSystemOpenSSL.cpp
+++ b/cpp/src/Ice/SslSystemOpenSSL.cpp
@@ -33,7 +33,10 @@
#include <Ice/SecurityException.h>
#include <Ice/SslConnectionOpenSSLClient.h>
#include <Ice/SslConnectionOpenSSLServer.h>
-#include <Ice/SslConfig.h>
+#include <Ice/SslConfig.h>
+#include <Ice/SslRSAKeyPair.h>
+#include <Ice/SslJanitors.h>
+#include <Ice/SslCertificateVerifierOpenSSL.h>
#include <Ice/TraceLevels.h>
#include <Ice/Logger.h>
@@ -92,158 +95,6 @@ Ice::LoggerPtr System::_globalLogger = 0;
using IceSecurity::Ssl::OpenSSL::ContextException;
using IceSecurity::Ssl::SystemPtr;
-//
-// NOTE: The following (mon, getGeneralizedTime, getUTCTime and getASN1time are routines that
-// have been abducted from the OpenSSL X509 library, and modified to work with the STL
-// basic_string template.
-
-static const char *mon[12]=
-{
- "Jan","Feb","Mar","Apr","May","Jun",
- "Jul","Aug","Sep","Oct","Nov","Dec"
-};
-
-string
-getGeneralizedTime(ASN1_GENERALIZEDTIME *tm)
-{
- char buf[30];
- char *v;
- int gmt=0;
- int i;
- int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
-
- i = tm->length;
- v = (char *) tm->data;
-
- if (i < 12)
- {
- goto err;
- }
-
- if (v[i-1] == 'Z')
- {
- gmt=1;
- }
-
- for (i=0; i<12; i++)
- {
- if ((v[i] > '9') || (v[i] < '0'))
- {
- goto err;
- }
- }
-
- y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 + (v[2] - '0') * 10 + (v[3] - '0');
- M = (v[4] - '0') * 10 + (v[5] - '0');
-
- if ((M > 12) || (M < 1))
- {
- goto err;
- }
-
- d = (v[6] - '0') * 10 + (v[7] - '0');
- h = (v[8] - '0') * 10 + (v[9] - '0');
- m = (v[10] - '0') * 10 + (v[11] - '0');
-
- if ((v[12] >= '0') && (v[12] <= '9') &&
- (v[13] >= '0') && (v[13] <= '9'))
- {
- s = (v[12] - '0') * 10 + (v[13] - '0');
- }
-
- sprintf(buf, "%s %2d %02d:%02d:%02d %d%s", mon[M-1], d, h, m, s, y, (gmt)?" GMT":"");
- return string(buf);
-
-err:
- return string("Bad time value");
-}
-
-string
-getUTCTime(ASN1_UTCTIME *tm)
-{
- char buf[30];
- char *v;
- int gmt=0;
- int i;
- int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
-
- i = tm->length;
- v = (char *) tm->data;
-
- if (i < 10)
- {
- goto err;
- }
-
- if (v[i-1] == 'Z')
- {
- gmt=1;
- }
-
- for (i = 0; i < 10; i++)
- {
- if ((v[i] > '9') || (v[i] < '0'))
- {
- goto err;
- }
- }
-
- y = (v[0] - '0') * 10 + (v[1] - '0');
-
- if (y < 50)
- {
- y+=100;
- }
-
- M = (v[2] - '0') * 10 + (v[3] - '0');
-
- if ((M > 12) || (M < 1))
- {
- goto err;
- }
-
- d = (v[4] - '0') * 10 + (v[5] - '0');
- h = (v[6] - '0') * 10 + (v[7] - '0');
- m = (v[8] - '0') * 10 + (v[9] - '0');
-
- if ((v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9'))
- {
- s = (v[10] - '0') * 10 + (v[11] - '0');
- }
-
- sprintf(buf, "%s %2d %02d:%02d:%02d %d%s", mon[M-1], d, h, m, s, y+1900, (gmt)?" GMT":"");
- return string(buf);
-
-err:
- return string("Bad time value");
-}
-
-string
-getASN1time(ASN1_TIME *tm)
-{
- string theTime;
-
- switch (tm->type)
- {
- case V_ASN1_UTCTIME :
- {
- theTime = getUTCTime(tm);
- }
-
- case V_ASN1_GENERALIZEDTIME :
- {
- theTime = getGeneralizedTime(tm);
- }
-
- default :
- {
- theTime = "Bad time value";
- }
- }
-
- return theTime;
-}
-
extern "C"
{
@@ -252,7 +103,8 @@ tmpRSACallback(SSL *s, int isExport, int keyLength)
{
IceSecurity::Ssl::SystemPtr sslSystem = IceSecurity::Ssl::Factory::getSystemFromHandle(s);
- IceSecurity::Ssl::OpenSSL::System* openSslSystem = dynamic_cast<IceSecurity::Ssl::OpenSSL::System*>(sslSystem.get());
+ IceSecurity::Ssl::OpenSSL::System* openSslSystem = 0;
+ openSslSystem = dynamic_cast<IceSecurity::Ssl::OpenSSL::System*>(sslSystem.get());
RSA* rsaKey = openSslSystem->getRSAKey(s, isExport, keyLength);
@@ -264,7 +116,8 @@ tmpDHCallback(SSL *s, int isExport, int keyLength)
{
IceSecurity::Ssl::SystemPtr sslSystem = IceSecurity::Ssl::Factory::getSystemFromHandle(s);
- IceSecurity::Ssl::OpenSSL::System* openSslSystem = dynamic_cast<IceSecurity::Ssl::OpenSSL::System*>(sslSystem.get());
+ IceSecurity::Ssl::OpenSSL::System* openSslSystem = 0;
+ openSslSystem = dynamic_cast<IceSecurity::Ssl::OpenSSL::System*>(sslSystem.get());
DH* dh = openSslSystem->getDHParams(s, isExport, keyLength);
@@ -275,71 +128,16 @@ tmpDHCallback(SSL *s, int isExport, int keyLength)
int
verifyCallback(int ok, X509_STORE_CTX *ctx)
{
- X509* err_cert = X509_STORE_CTX_get_current_cert(ctx);
- int verifyError = X509_STORE_CTX_get_error(ctx);
- int depth = X509_STORE_CTX_get_error_depth(ctx);
-
- // If we have no errors so far, and the certificate chain is too long
- if ((verifyError != X509_V_OK) && (10 < depth))
- {
- verifyError = X509_V_ERR_CERT_CHAIN_TOO_LONG;
- }
-
- if (verifyError != X509_V_OK)
- {
- // If we have ANY errors, we bail out.
- ok = 0;
- }
-
- // Only if ICE_PROTOCOL level logging is on do we worry about this.
- if (ICE_SECURITY_LEVEL_PROTOCOL_GLOBAL)
- {
- char buf[256];
-
- X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
-
- ostringstream outStringStream;
-
- outStringStream << "depth = " << depth << ":" << buf << endl;
-
- if (!ok)
- {
- outStringStream << "verify error: num = " << verifyError << " : "
- << X509_verify_cert_error_string(verifyError) << endl;
-
- }
-
- switch (verifyError)
- {
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- {
- X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, sizeof(buf));
- outStringStream << "issuer = " << buf << endl;
- break;
- }
-
- case X509_V_ERR_CERT_NOT_YET_VALID:
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- {
- outStringStream << "notBefore =" << getASN1time(X509_get_notBefore(ctx->current_cert)) << endl;
- break;
- }
-
- case X509_V_ERR_CERT_HAS_EXPIRED:
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- {
- outStringStream << "notAfter =" << getASN1time(X509_get_notAfter(ctx->current_cert)) << endl;
- break;
- }
- }
-
- outStringStream << "verify return = " << ok << endl;
-
- IceSecurity::Ssl::OpenSSL::System::_globalLogger->trace(
- IceSecurity::Ssl::OpenSSL::System::_globalTraceLevels->securityCat, outStringStream.str());
- }
-
- return ok;
+ // Tricky method to get access to our connection. I would use SSL_get_ex_data() to get
+ // the Connection object, if only I had some way to retrieve the index of the object
+ // in this function. Hence, we have to invent our own reference system here.
+ SSL* ssl = static_cast<SSL*>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
+ IceSecurity::Ssl::OpenSSL::ConnectionPtr connection = 0;
+ connection = IceSecurity::Ssl::OpenSSL::Connection::getConnection(ssl);
+ assert(connection);
+
+ // Call the connection, get it to perform the verification.
+ return connection->verifyCertificate(ok, ctx);
}
// This code duplicates functionality that existed in the BIO library of
@@ -531,7 +329,7 @@ IceSecurity::Ssl::OpenSSL::System::createServerConnection(int socket)
// Set the Accept Connection state for this connection.
SSL_set_accept_state(sslConnection);
- Connection* connection = new ServerConnection(sslConnection, SystemPtr(this));
+ Connection* connection = new ServerConnection(_serverVerifier, sslConnection, SystemPtr(this));
commonConnectionSetup(connection);
@@ -562,7 +360,7 @@ IceSecurity::Ssl::OpenSSL::System::createClientConnection(int socket)
// Set the Connect Connection state for this connection.
SSL_set_connect_state(sslConnection);
- Connection* connection = new ClientConnection(sslConnection, SystemPtr(this));
+ Connection* connection = new ClientConnection(_clientVerifier, sslConnection, SystemPtr(this));
commonConnectionSetup(connection);
@@ -842,6 +640,11 @@ IceSecurity::Ssl::OpenSSL::System::System()
_randSeeded = 0;
_sslServerContext = 0;
_sslClientContext = 0;
+
+ // Here we create a default verifier, which does very little other
+ // than check the verification depth. This can be overridden.
+ _clientVerifier = new DefaultCertificateVerifier();
+ _serverVerifier = _clientVerifier;
SSL_load_error_strings();
@@ -912,8 +715,8 @@ IceSecurity::Ssl::OpenSSL::System::initClient(GeneralConfig& general,
setKeyCert(_sslClientContext, baseCerts.getRSACert(), privateRSAKey, publicRSAKey);
// Process the DSA Certificate
- string privateDSAKey = _properties->getProperty("Ice.Security.Ssl.Overrides.Client.DSA.PrivateKey");
- string publicDSAKey = _properties->getProperty("Ice.Security.Ssl.Overrides.Client.DSA.Certificate");
+ string privateDSAKey; // = _properties->getProperty("Ice.Security.Ssl.Overrides.Client.DSA.PrivateKey");
+ string publicDSAKey; // = _properties->getProperty("Ice.Security.Ssl.Overrides.Client.DSA.Certificate");
setKeyCert(_sslClientContext, baseCerts.getDSACert(), privateDSAKey, publicDSAKey);
// Set the DH key agreement parameters.
@@ -965,8 +768,8 @@ IceSecurity::Ssl::OpenSSL::System::initServer(GeneralConfig& general,
setKeyCert(_sslServerContext, baseCerts.getRSACert(), privateRSAKey, publicRSAKey);
// Process the DSA Certificate
- string privateDSAKey = _properties->getProperty("Ice.Security.Ssl.Overrides.Server.DSA.PrivateKey");
- string publicDSAKey = _properties->getProperty("Ice.Security.Ssl.Overrides.Server.DSA.Certificate");
+ string privateDSAKey; // = _properties->getProperty("Ice.Security.Ssl.Overrides.Server.DSA.PrivateKey");
+ string publicDSAKey; // = _properties->getProperty("Ice.Security.Ssl.Overrides.Server.DSA.Certificate");
setKeyCert(_sslServerContext, baseCerts.getDSACert(), privateDSAKey, publicDSAKey);
// Set the DH key agreement parameters.
@@ -988,8 +791,8 @@ IceSecurity::Ssl::OpenSSL::System::initServer(GeneralConfig& general,
SSL_CTX_set_verify(_sslServerContext, general.getVerifyMode(), verifyCallback);
// Set the certificate verify depth
- SSL_CTX_set_verify_depth(_sslServerContext, general.getVerifyDepth());
-
+ SSL_CTX_set_verify_depth(_sslServerContext, general.getVerifyDepth());
+
// Set the default context for the SSL system (can be overridden if needed) [SERVER ONLY].
SSL_CTX_set_session_id_context(_sslServerContext,
reinterpret_cast<const unsigned char *>(_sessionContext.c_str()),
@@ -1145,22 +948,35 @@ IceSecurity::Ssl::OpenSSL::System::addKeyCert(SSL_CTX* sslContext,
ICE_METHOD_RET("OpenSSL::System::addKeyCert()");
}
-X509*
-IceSecurity::Ssl::OpenSSL::System::byteSeqToX509(ByteSeq& byteSeq)
+void
+IceSecurity::Ssl::OpenSSL::System::addKeyCert(SSL_CTX* sslContext,
+ const string& privateKey,
+ const string& publicKey)
{
- // Create a BIO that reads directly from our ByteSeq!
- // NOTE: The reinterpret_cast is required, nasty OpenSSL hack!
- BIO* memoryBio = BIO_new_mem_buf(reinterpret_cast<void *>(byteSeq.begin()), byteSeq.size());
+ ICE_METHOD_INV("OpenSSL::System::addKeyCert()");
- X509* x509 = PEM_read_bio_X509(memoryBio, 0, 0, 0);
+ string privKey = privateKey;
- if (!x509)
+ if (privKey.empty())
{
- SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB);
+ ICE_WARNING("No private key specified - using the certificate.");
+ privKey = publicKey;
+ }
+
+ // Make a key pair based on the Base64 encoded strings
+ RSAKeyPair keyPair(privateKey, publicKey);
+
+ // Janitors to ensure that everything gets cleaned up properly
+ RSAJanitor rsaJanitor(keyPair.getRSAPrivateKey());
+ X509Janitor x509Janitor(keyPair.getX509PublicKey());
+
+ // Set which Public Key file to use.
+ if (SSL_CTX_use_certificate(sslContext, x509Janitor.get()) <= 0)
+ {
ContextException contextEx(__FILE__, __LINE__);
- contextEx._message = "Unable to load Public Key from memory buffer.";
+ contextEx._message = "Unable to set certificate from memory.";
string sslError = sslGetErrors();
if (!sslError.empty())
@@ -1169,33 +985,17 @@ IceSecurity::Ssl::OpenSSL::System::byteSeqToX509(ByteSeq& byteSeq)
contextEx._message += sslError;
}
-
ICE_EXCEPTION(contextEx._message);
throw contextEx;
}
- BIO_free(memoryBio);
-
- return x509;
-}
-
-RSA*
-IceSecurity::Ssl::OpenSSL::System::byteSeqToKey(ByteSeq& byteSeq)
-{
- // Create a BIO that reads directly from our ByteSeq!
- // NOTE: The reinterpret_cast is required, nasty OpenSSL hack!
- BIO* memoryBio = BIO_new_mem_buf(reinterpret_cast<void *>(byteSeq.begin()), byteSeq.size());
-
- RSA* rsa = PEM_read_bio_RSAPrivateKey(memoryBio, 0, 0, 0);
-
- if (!rsa)
+ // Set which Private Key file to use.
+ if (SSL_CTX_use_RSAPrivateKey(sslContext, rsaJanitor.get()) <= 0)
{
- SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_PEM_LIB);
-
ContextException contextEx(__FILE__, __LINE__);
- contextEx._message = "Unable to load Private Key from memory buffer.";
+ contextEx._message = "Unable to set private key from memory.";
string sslError = sslGetErrors();
if (!sslError.empty())
@@ -1204,112 +1004,11 @@ IceSecurity::Ssl::OpenSSL::System::byteSeqToKey(ByteSeq& byteSeq)
contextEx._message += sslError;
}
-
ICE_EXCEPTION(contextEx._message);
throw contextEx;
}
-
- BIO_free(memoryBio);
-
- return rsa;
-}
-
-void
-IceSecurity::Ssl::OpenSSL::System::addKeyCert(SSL_CTX* sslContext,
- const string& privateKey,
- const string& publicKey)
-{
- ICE_METHOD_INV("OpenSSL::System::addKeyCert()");
-
- string privKey = privateKey;
-
- if (privKey.empty())
- {
- ICE_WARNING("No private key specified - using the certificate.");
-
- privKey = publicKey;
- }
-
- //
- // Convert the strings containing the Key (Private Key) and Certificate (Public Key)
- // into byte sequences.
- //
- ByteSeq publicKeyByteSeq;
- ByteSeq privateKeyByteSeq;
-
- publicKeyByteSeq.reserve(privateKey.size());
- privateKeyByteSeq.reserve(publicKey.size());
-
- std::copy(privateKey.begin(), privateKey.end(), back_inserter(privateKeyByteSeq));
- std::copy(publicKey.begin(), publicKey.end(), back_inserter(publicKeyByteSeq));
-
- X509* x509 = 0;
- RSA* rsa = 0;
-
- try
- {
- // These methods should throw exceptions if they can't perform the conversion.
- x509 = byteSeqToX509(publicKeyByteSeq);
- rsa = byteSeqToKey(privateKeyByteSeq);
-
- // Set which Public Key file to use.
- if (SSL_CTX_use_certificate(sslContext, x509) <= 0)
- {
- ContextException contextEx(__FILE__, __LINE__);
-
- contextEx._message = "Unable to set certificate from memory.";
- string sslError = sslGetErrors();
-
- if (!sslError.empty())
- {
- contextEx._message += "\n";
- contextEx._message += sslError;
- }
-
-
- ICE_EXCEPTION(contextEx._message);
-
- throw contextEx;
- }
-
- // Set which Private Key file to use.
- if (SSL_CTX_use_RSAPrivateKey(sslContext, rsa) <= 0)
- {
- ContextException contextEx(__FILE__, __LINE__);
-
- contextEx._message = "Unable to set private key from memory.";
- string sslError = sslGetErrors();
-
- if (!sslError.empty())
- {
- contextEx._message += "\n";
- contextEx._message += sslError;
- }
-
- ICE_EXCEPTION(contextEx._message);
-
- throw contextEx;
- }
- }
- catch (...)
- {
- if (x509)
- {
- X509_free(x509);
- }
-
- if (rsa)
- {
- RSA_free(rsa);
- }
-
- throw;
- }
-
- X509_free(x509);
- RSA_free(rsa);
-
+
// Check to see if the Private and Public keys that have been
// set against the SSL context match up.
if (!SSL_CTX_check_private_key(sslContext))
diff --git a/cpp/src/Ice/SslSystemOpenSSL.h b/cpp/src/Ice/SslSystemOpenSSL.h
index beaa682a631..970d8a2b30c 100644
--- a/cpp/src/Ice/SslSystemOpenSSL.h
+++ b/cpp/src/Ice/SslSystemOpenSSL.h
@@ -153,8 +153,6 @@ private:
void processCertificate(SSL_CTX*, const CertificateDesc&);
void addKeyCert(SSL_CTX*, const CertificateFile&, const CertificateFile&);
- X509* byteSeqToX509(ByteSeq&);
- RSA* byteSeqToKey(ByteSeq&);
void addKeyCert(SSL_CTX*, const string&, const string&);
SSL_CTX* createContext(SslProtocol);
diff --git a/cpp/src/Ice/ice.dsp b/cpp/src/Ice/ice.dsp
index 855020d2652..10f9ed1483a 100644
--- a/cpp/src/Ice/ice.dsp
+++ b/cpp/src/Ice/ice.dsp
@@ -308,6 +308,14 @@ SOURCE=.\SslCertificateDesc.cpp
# End Source File
# Begin Source File
+SOURCE=.\SslCertificateVerifier.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SslCertificateVerifierOpenSSL.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\SslConfig.cpp
# End Source File
# Begin Source File
@@ -344,6 +352,22 @@ SOURCE=.\SslGeneralConfig.cpp
# End Source File
# Begin Source File
+SOURCE=.\SslJanitors.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SslOpenSSLUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SslRSACertificateGen.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SslRSAKeyPair.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\SslSystem.cpp
# End Source File
# Begin Source File
@@ -776,6 +800,18 @@ SOURCE=.\SslCertificateDesc.h
# End Source File
# Begin Source File
+SOURCE=.\SslCertificateVerifier.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SslCertificateVerifierF.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SslCertificateVerifierOpenSSL.h
+# End Source File
+# Begin Source File
+
SOURCE=.\SslConfig.h
# End Source File
# Begin Source File
@@ -796,6 +832,10 @@ SOURCE=.\SslConnectionOpenSSLClient.h
# End Source File
# Begin Source File
+SOURCE=.\SslConnectionOpenSSLF.h
+# End Source File
+# Begin Source File
+
SOURCE=.\SslConnectionOpenSSLServer.h
# End Source File
# Begin Source File
@@ -812,6 +852,30 @@ SOURCE=.\SslGeneralConfig.h
# End Source File
# Begin Source File
+SOURCE=.\SslJanitors.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SslOpenSSLUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\Ice\SslRSACertificateGen.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\Ice\SslRSACertificateGenF.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\Ice\SslRSAKeyPair.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\Ice\SslRSAKeyPairF.h
+# End Source File
+# Begin Source File
+
SOURCE=.\SslSystem.h
# End Source File
# Begin Source File
diff --git a/cpp/src/IceUtil/Base64.cpp b/cpp/src/IceUtil/Base64.cpp
new file mode 100644
index 00000000000..7f65da07865
--- /dev/null
+++ b/cpp/src/IceUtil/Base64.cpp
@@ -0,0 +1,265 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Base64.h>
+#include <iostream>
+
+using namespace std;
+
+string
+IceUtil::Base64::encode(const ByteSeq& plainSeq)
+{
+ string retval;
+
+ if (plainSeq.size() == 0)
+ {
+ return retval;
+ }
+
+ // Reserve enough space for the returned base64 string
+ long base64Bytes = (((plainSeq.size() * 4L) / 3L) + 1L);
+ long newlineBytes = (((base64Bytes * 2L) / 76L) + 1L);
+ long totalBytes = base64Bytes + newlineBytes;
+
+ retval.reserve(totalBytes);
+
+ unsigned char by1 = 0;
+ unsigned char by2 = 0;
+ unsigned char by3 = 0;
+ unsigned char by4 = 0;
+ unsigned char by5 = 0;
+ unsigned char by6 = 0;
+ unsigned char by7 = 0;
+
+ for (unsigned int i = 0; i < plainSeq.size(); i += 3)
+ {
+ by1 = plainSeq[i];
+ by2 = 0;
+ by3 = 0;
+
+ if ((i + 1) < plainSeq.size())
+ {
+ by2 = plainSeq[i+1];
+ }
+
+ if ((i + 2) < plainSeq.size())
+ {
+ by3 = plainSeq[i+2];
+ }
+
+ by4 = by1 >> 2;
+ by5 = ((by1 & 0x3) << 4) | (by2 >> 4);
+ by6 = ((by2 & 0xf) << 2) | (by3 >> 6);
+ by7 = by3 & 0x3f;
+
+ retval += encode(by4);
+ retval += encode(by5);
+
+ if ((i + 1) < plainSeq.size())
+ {
+ retval += encode(by6);
+ }
+ else
+ {
+ retval += "=";
+ }
+
+ if ((i + 2) < plainSeq.size())
+ {
+ retval += encode(by7);
+ }
+ else
+ {
+ retval += "=";
+ }
+ }
+
+ string outString;
+ outString.reserve(totalBytes);
+ string::iterator iter = retval.begin();
+
+ while ((retval.end() - iter) > 76)
+ {
+ copy(iter, iter+76, back_inserter(outString));
+ outString += "\r\n";
+ iter += 76;
+ }
+
+ copy(iter, retval.end(), back_inserter(outString));
+
+ return outString;
+}
+
+IceUtil::ByteSeq
+IceUtil::Base64::decode(const string& _str)
+{
+ string str;
+
+ for (unsigned int j = 0; j < _str.length(); j++)
+ {
+ if (isBase64(_str[j]))
+ {
+ str += _str[j];
+ }
+ }
+
+ ByteSeq retval;
+
+ if (str.length() == 0)
+ {
+ return retval;
+ }
+
+ // Figure out how long the final sequence is going to be.
+ long lines = _str.size() / 78;
+ long totalBytes = (lines * 76) + (((_str.size() - (lines * 78)) * 3) / 4);
+
+ retval.reserve(totalBytes);
+
+ unsigned char by1 = 0;
+ unsigned char by2 = 0;
+ unsigned char by3 = 0;
+ unsigned char by4 = 0;
+
+ char c1, c2, c3, c4;
+
+ for (unsigned int i = 0; i < str.length(); i += 4)
+ {
+ c1='A';
+ c2='A';
+ c3='A';
+ c4='A';
+
+ c1 = str[i];
+
+ if ((i + 1) < str.length())
+ {
+ c2 = str[i+1];
+ }
+
+ if ((i + 2) < str.length())
+ {
+ c3 = str[i+2];
+ }
+
+ if ((i + 3) < str.length())
+ {
+ c4 = str[i+3];
+ }
+
+ by1 = decode(c1);
+ by2 = decode(c2);
+ by3 = decode(c3);
+ by4 = decode(c4);
+
+ retval.push_back((by1 << 2) | (by2 >> 4));
+
+ if (c3 != '=')
+ {
+ retval.push_back(((by2 & 0xf) << 4) | (by3 >> 2));
+ }
+
+ if (c4 != '=')
+ {
+ retval.push_back(((by3 & 0x3) << 6) | by4);
+ }
+ }
+
+ return retval;
+}
+
+char
+IceUtil::Base64::encode(unsigned char uc)
+{
+ if (uc < 26)
+ {
+ return 'A'+uc;
+ }
+
+ if (uc < 52)
+ {
+ return 'a'+(uc-26);
+ }
+
+ if (uc < 62)
+ {
+ return '0'+(uc-52);
+ }
+
+ if (uc == 62)
+ {
+ return '+';
+ }
+
+ return '/';
+}
+
+unsigned char
+IceUtil::Base64::decode(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ {
+ return c - 'A';
+ }
+
+ if (c >= 'a' && c <= 'z')
+ {
+ return c - 'a' + 26;
+ }
+
+ if (c >= '0' && c <= '9')
+ {
+ return c - '0' + 52;
+ }
+
+ if (c == '+')
+ {
+ return 62;
+ }
+
+ return 63;
+}
+
+
+bool
+IceUtil::Base64::isBase64(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ {
+ return true;
+ }
+
+ if (c >= 'a' && c <= 'z')
+ {
+ return true;
+ }
+
+ if (c >= '0' && c <= '9')
+ {
+ return true;
+ }
+
+ if (c == '+')
+ {
+ return true;
+ }
+
+ if (c == '/')
+ {
+ return true;
+ }
+
+ if (c == '=')
+ {
+ return true;
+ }
+
+ return false;
+}
diff --git a/cpp/src/IceUtil/iceutil.dsp b/cpp/src/IceUtil/iceutil.dsp
index de63136a9a4..8f3c5261c04 100644
--- a/cpp/src/IceUtil/iceutil.dsp
+++ b/cpp/src/IceUtil/iceutil.dsp
@@ -104,6 +104,10 @@ PostBuild_Cmds=copy Debug\iceutil001d.* ..\..\lib
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
+SOURCE=.\Base64.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\Cond.cpp
# End Source File
# Begin Source File
@@ -140,6 +144,10 @@ SOURCE=.\UUID.cpp
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
+SOURCE=..\..\include\IceUtil\Base64.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\IceUtil\Cond.h
# End Source File
# Begin Source File