summaryrefslogtreecommitdiff
path: root/cpp/src/IceSSL/OpenSSLUtils.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2002-04-24 21:13:00 +0000
committerMark Spruiell <mes@zeroc.com>2002-04-24 21:13:00 +0000
commit5409c1ecef0f226dedc77721c0d2fc8dfe9e85de (patch)
tree97ba75bc47a143726d6d8382be3a462e51716700 /cpp/src/IceSSL/OpenSSLUtils.cpp
parentcleaning up sample impls (diff)
downloadice-5409c1ecef0f226dedc77721c0d2fc8dfe9e85de.tar.bz2
ice-5409c1ecef0f226dedc77721c0d2fc8dfe9e85de.tar.xz
ice-5409c1ecef0f226dedc77721c0d2fc8dfe9e85de.zip
merging from plugins branch
Diffstat (limited to 'cpp/src/IceSSL/OpenSSLUtils.cpp')
-rw-r--r--cpp/src/IceSSL/OpenSSLUtils.cpp464
1 files changed, 464 insertions, 0 deletions
diff --git a/cpp/src/IceSSL/OpenSSLUtils.cpp b/cpp/src/IceSSL/OpenSSLUtils.cpp
new file mode 100644
index 00000000000..2767ce97aba
--- /dev/null
+++ b/cpp/src/IceSSL/OpenSSLUtils.cpp
@@ -0,0 +1,464 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Mutex.h>
+#include <IceSSL/OpenSSLUtils.h>
+#include <IceSSL/OpenSSLPluginI.h>
+#include <IceSSL/SslConnectionOpenSSL.h>
+#include <openssl/err.h>
+
+using namespace std;
+
+// The following arrays are compiled-in diffie hellman group parameters.
+// These are used when OpenSSL opts to use ephemeral diffie-hellman keys
+// and no group parameters have been supplied in the SSL configuration
+// files. These are known strong primes, distributed with the OpenSSL
+// library in the files dh512.pem, dh1024.pem, dh2048.pem and dh4096.pem.
+// They are not keys themselves, but the basis for generating DH keys
+// on the fly.
+
+static unsigned char dh512_p[] =
+{
+ 0xF5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C,
+ 0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29,
+ 0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B,
+ 0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C,
+ 0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55,
+ 0xE9,0x2A,0x05,0x5F,
+};
+
+static unsigned char dh512_g[] = { 0x02, };
+
+static unsigned char dh1024_p[] =
+{
+ 0xF4,0x88,0xFD,0x58,0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,
+ 0x91,0x07,0x36,0x6B,0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,
+ 0x88,0xB3,0x1C,0x7C,0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,
+ 0x43,0xF0,0xA5,0x5B,0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,
+ 0x38,0xD3,0x34,0xFD,0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,
+ 0xDE,0x33,0x21,0x2C,0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,
+ 0x18,0x11,0x8D,0x7C,0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,
+ 0x19,0xC8,0x07,0x29,0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,
+ 0xD0,0x0A,0x50,0x9B,0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,
+ 0x41,0x9F,0x9C,0x7C,0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,
+ 0xA2,0x5E,0xC3,0x55,0xE9,0x2F,0x78,0xC7,
+};
+
+static unsigned char dh1024_g[] = { 0x02, };
+
+static unsigned char dh2048_p[] =
+{
+ 0xF6,0x42,0x57,0xB7,0x08,0x7F,0x08,0x17,0x72,0xA2,0xBA,0xD6,
+ 0xA9,0x42,0xF3,0x05,0xE8,0xF9,0x53,0x11,0x39,0x4F,0xB6,0xF1,
+ 0x6E,0xB9,0x4B,0x38,0x20,0xDA,0x01,0xA7,0x56,0xA3,0x14,0xE9,
+ 0x8F,0x40,0x55,0xF3,0xD0,0x07,0xC6,0xCB,0x43,0xA9,0x94,0xAD,
+ 0xF7,0x4C,0x64,0x86,0x49,0xF8,0x0C,0x83,0xBD,0x65,0xE9,0x17,
+ 0xD4,0xA1,0xD3,0x50,0xF8,0xF5,0x59,0x5F,0xDC,0x76,0x52,0x4F,
+ 0x3D,0x3D,0x8D,0xDB,0xCE,0x99,0xE1,0x57,0x92,0x59,0xCD,0xFD,
+ 0xB8,0xAE,0x74,0x4F,0xC5,0xFC,0x76,0xBC,0x83,0xC5,0x47,0x30,
+ 0x61,0xCE,0x7C,0xC9,0x66,0xFF,0x15,0xF9,0xBB,0xFD,0x91,0x5E,
+ 0xC7,0x01,0xAA,0xD3,0x5B,0x9E,0x8D,0xA0,0xA5,0x72,0x3A,0xD4,
+ 0x1A,0xF0,0xBF,0x46,0x00,0x58,0x2B,0xE5,0xF4,0x88,0xFD,0x58,
+ 0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,0x91,0x07,0x36,0x6B,
+ 0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,0x88,0xB3,0x1C,0x7C,
+ 0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,0x43,0xF0,0xA5,0x5B,
+ 0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,0x38,0xD3,0x34,0xFD,
+ 0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,0xDE,0x33,0x21,0x2C,
+ 0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C,
+ 0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29,
+ 0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B,
+ 0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C,
+ 0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55,
+ 0xE9,0x32,0x0B,0x3B,
+};
+
+static unsigned char dh2048_g[] = { 0x02, };
+
+static unsigned char dh4096_p[] =
+{
+ 0xFA,0x14,0x72,0x52,0xC1,0x4D,0xE1,0x5A,0x49,0xD4,0xEF,0x09,
+ 0x2D,0xC0,0xA8,0xFD,0x55,0xAB,0xD7,0xD9,0x37,0x04,0x28,0x09,
+ 0xE2,0xE9,0x3E,0x77,0xE2,0xA1,0x7A,0x18,0xDD,0x46,0xA3,0x43,
+ 0x37,0x23,0x90,0x97,0xF3,0x0E,0xC9,0x03,0x50,0x7D,0x65,0xCF,
+ 0x78,0x62,0xA6,0x3A,0x62,0x22,0x83,0xA1,0x2F,0xFE,0x79,0xBA,
+ 0x35,0xFF,0x59,0xD8,0x1D,0x61,0xDD,0x1E,0x21,0x13,0x17,0xFE,
+ 0xCD,0x38,0x87,0x9E,0xF5,0x4F,0x79,0x10,0x61,0x8D,0xD4,0x22,
+ 0xF3,0x5A,0xED,0x5D,0xEA,0x21,0xE9,0x33,0x6B,0x48,0x12,0x0A,
+ 0x20,0x77,0xD4,0x25,0x60,0x61,0xDE,0xF6,0xB4,0x4F,0x1C,0x63,
+ 0x40,0x8B,0x3A,0x21,0x93,0x8B,0x79,0x53,0x51,0x2C,0xCA,0xB3,
+ 0x7B,0x29,0x56,0xA8,0xC7,0xF8,0xF4,0x7B,0x08,0x5E,0xA6,0xDC,
+ 0xA2,0x45,0x12,0x56,0xDD,0x41,0x92,0xF2,0xDD,0x5B,0x8F,0x23,
+ 0xF0,0xF3,0xEF,0xE4,0x3B,0x0A,0x44,0xDD,0xED,0x96,0x84,0xF1,
+ 0xA8,0x32,0x46,0xA3,0xDB,0x4A,0xBE,0x3D,0x45,0xBA,0x4E,0xF8,
+ 0x03,0xE5,0xDD,0x6B,0x59,0x0D,0x84,0x1E,0xCA,0x16,0x5A,0x8C,
+ 0xC8,0xDF,0x7C,0x54,0x44,0xC4,0x27,0xA7,0x3B,0x2A,0x97,0xCE,
+ 0xA3,0x7D,0x26,0x9C,0xAD,0xF4,0xC2,0xAC,0x37,0x4B,0xC3,0xAD,
+ 0x68,0x84,0x7F,0x99,0xA6,0x17,0xEF,0x6B,0x46,0x3A,0x7A,0x36,
+ 0x7A,0x11,0x43,0x92,0xAD,0xE9,0x9C,0xFB,0x44,0x6C,0x3D,0x82,
+ 0x49,0xCC,0x5C,0x6A,0x52,0x42,0xF8,0x42,0xFB,0x44,0xF9,0x39,
+ 0x73,0xFB,0x60,0x79,0x3B,0xC2,0x9E,0x0B,0xDC,0xD4,0xA6,0x67,
+ 0xF7,0x66,0x3F,0xFC,0x42,0x3B,0x1B,0xDB,0x4F,0x66,0xDC,0xA5,
+ 0x8F,0x66,0xF9,0xEA,0xC1,0xED,0x31,0xFB,0x48,0xA1,0x82,0x7D,
+ 0xF8,0xE0,0xCC,0xB1,0xC7,0x03,0xE4,0xF8,0xB3,0xFE,0xB7,0xA3,
+ 0x13,0x73,0xA6,0x7B,0xC1,0x0E,0x39,0xC7,0x94,0x48,0x26,0x00,
+ 0x85,0x79,0xFC,0x6F,0x7A,0xAF,0xC5,0x52,0x35,0x75,0xD7,0x75,
+ 0xA4,0x40,0xFA,0x14,0x74,0x61,0x16,0xF2,0xEB,0x67,0x11,0x6F,
+ 0x04,0x43,0x3D,0x11,0x14,0x4C,0xA7,0x94,0x2A,0x39,0xA1,0xC9,
+ 0x90,0xCF,0x83,0xC6,0xFF,0x02,0x8F,0xA3,0x2A,0xAC,0x26,0xDF,
+ 0x0B,0x8B,0xBE,0x64,0x4A,0xF1,0xA1,0xDC,0xEE,0xBA,0xC8,0x03,
+ 0x82,0xF6,0x62,0x2C,0x5D,0xB6,0xBB,0x13,0x19,0x6E,0x86,0xC5,
+ 0x5B,0x2B,0x5E,0x3A,0xF3,0xB3,0x28,0x6B,0x70,0x71,0x3A,0x8E,
+ 0xFF,0x5C,0x15,0xE6,0x02,0xA4,0xCE,0xED,0x59,0x56,0xCC,0x15,
+ 0x51,0x07,0x79,0x1A,0x0F,0x25,0x26,0x27,0x30,0xA9,0x15,0xB2,
+ 0xC8,0xD4,0x5C,0xCC,0x30,0xE8,0x1B,0xD8,0xD5,0x0F,0x19,0xA8,
+ 0x80,0xA4,0xC7,0x01,0xAA,0x8B,0xBA,0x53,0xBB,0x47,0xC2,0x1F,
+ 0x6B,0x54,0xB0,0x17,0x60,0xED,0x79,0x21,0x95,0xB6,0x05,0x84,
+ 0x37,0xC8,0x03,0xA4,0xDD,0xD1,0x06,0x69,0x8F,0x4C,0x39,0xE0,
+ 0xC8,0x5D,0x83,0x1D,0xBE,0x6A,0x9A,0x99,0xF3,0x9F,0x0B,0x45,
+ 0x29,0xD4,0xCB,0x29,0x66,0xEE,0x1E,0x7E,0x3D,0xD7,0x13,0x4E,
+ 0xDB,0x90,0x90,0x58,0xCB,0x5E,0x9B,0xCD,0x2E,0x2B,0x0F,0xA9,
+ 0x4E,0x78,0xAC,0x05,0x11,0x7F,0xE3,0x9E,0x27,0xD4,0x99,0xE1,
+ 0xB9,0xBD,0x78,0xE1,0x84,0x41,0xA0,0xDF,
+};
+
+static unsigned char dh4096_g[] = { 0x02, };
+
+// Ensures that the sslGetErrors() function is synchronized.
+static ::IceUtil::Mutex sslErrorsMutex;
+
+//
+// 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
+IceSSL::OpenSSL::getGeneralizedTime(ASN1_GENERALIZEDTIME *tm)
+{
+ assert(tm != 0);
+
+ char buf[30];
+ int gmt = 0, y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+
+ int i = tm->length;
+
+ char* 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
+IceSSL::OpenSSL::getUTCTime(ASN1_UTCTIME *tm)
+{
+ assert(tm != 0);
+
+ char buf[30];
+ int gmt = 0, y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+
+ int i = tm->length;
+ char* 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
+IceSSL::OpenSSL::getASN1time(ASN1_TIME *tm)
+{
+ assert(tm != 0);
+
+ string theTime;
+
+ switch (tm->type)
+ {
+ case V_ASN1_UTCTIME :
+ {
+ theTime = getUTCTime(tm);
+ break;
+ }
+
+ case V_ASN1_GENERALIZEDTIME :
+ {
+ theTime = getGeneralizedTime(tm);
+ break;
+ }
+
+ default :
+ {
+ theTime = "Bad time value";
+ break;
+ }
+ }
+
+ return theTime;
+}
+
+DH*
+IceSSL::OpenSSL::loadDHParam(const char* dhfile)
+{
+ assert(dhfile != 0);
+
+ DH* ret = 0;
+ BIO* bio = BIO_new_file(dhfile,"r");
+
+ if (bio != 0)
+ {
+ ret = PEM_read_bio_DHparams(bio, 0, 0, 0);
+ BIO_free(bio);
+ }
+
+ return ret;
+}
+
+DH*
+IceSSL::OpenSSL::getTempDH(unsigned char* p, int plen, unsigned char* g, int glen)
+{
+ assert(p != 0);
+ assert(g != 0);
+
+ DH* dh = DH_new();
+
+ if (dh != 0)
+ {
+ dh->p = BN_bin2bn(p, plen, 0);
+
+ dh->g = BN_bin2bn(g, glen, 0);
+
+ if ((dh->p == 0) || (dh->g == 0))
+ {
+ DH_free(dh);
+ dh = 0;
+ }
+ }
+
+ return dh;
+}
+
+DH*
+IceSSL::OpenSSL::getTempDH512()
+{
+ DH* dh = getTempDH(dh512_p, sizeof(dh512_p), dh512_g, sizeof(dh512_g));
+
+ return dh;
+}
+
+DH*
+IceSSL::OpenSSL::getTempDH1024()
+{
+ DH* dh = getTempDH(dh1024_p, sizeof(dh1024_p), dh1024_g, sizeof(dh1024_g));
+
+ return dh;
+}
+
+DH*
+IceSSL::OpenSSL::getTempDH2048()
+{
+ DH* dh = getTempDH(dh2048_p, sizeof(dh2048_p), dh2048_g, sizeof(dh2048_g));
+
+ return dh;
+}
+
+DH*
+IceSSL::OpenSSL::getTempDH4096()
+{
+ DH* dh = getTempDH(dh4096_p, sizeof(dh4096_p), dh4096_g, sizeof(dh4096_g));
+
+ return dh;
+}
+
+string
+IceSSL::OpenSSL::sslGetErrors()
+{
+ IceUtil::Mutex::Lock sync(sslErrorsMutex);
+
+ string errorMessage;
+ char buf[200];
+ char bigBuffer[1024];
+ const char* file = 0;
+ const char* data = 0;
+ int line = 0;
+ int flags = 0;
+ unsigned errorCode = 0;
+ int errorNum = 1;
+
+ unsigned long es = CRYPTO_thread_id();
+
+ while ((errorCode = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0)
+ {
+ sprintf(bigBuffer,"%6d - Thread ID: %lu\n", errorNum, es);
+ errorMessage += bigBuffer;
+
+ sprintf(bigBuffer,"%6d - Error: %u\n", errorNum, errorCode);
+ errorMessage += bigBuffer;
+
+ // Request an error from the OpenSSL library
+ ERR_error_string_n(errorCode, buf, sizeof(buf));
+ sprintf(bigBuffer,"%6d - Message: %s\n", errorNum, buf);
+ errorMessage += bigBuffer;
+
+ sprintf(bigBuffer,"%6d - Location: %s, %d\n", errorNum, file, line);
+ errorMessage += bigBuffer;
+
+ if (flags & ERR_TXT_STRING)
+ {
+ sprintf(bigBuffer,"%6d - Data: %s\n", errorNum, data);
+ errorMessage += bigBuffer;
+ }
+
+ errorNum++;
+ }
+
+ ERR_clear_error();
+
+ return errorMessage;
+}
+
+extern "C"
+{
+
+RSA*
+tmpRSACallback(SSL* sslConnection, int isExport, int keyLength)
+{
+ assert(sslConnection != 0);
+
+ void* p = SSL_get_ex_data(sslConnection, 0);
+ assert(p != 0);
+ IceSSL::PluginBaseI* plugin = static_cast<IceSSL::PluginBaseI*>(p);
+
+ IceSSL::OpenSSL::PluginI* openSslPlugin = dynamic_cast<IceSSL::OpenSSL::PluginI*>(plugin);
+ assert(openSslPlugin != 0);
+
+ return openSslPlugin->getRSAKey(isExport, keyLength);
+}
+
+DH*
+tmpDHCallback(SSL* sslConnection, int isExport, int keyLength)
+{
+ assert(sslConnection != 0);
+
+ void* p = SSL_get_ex_data(sslConnection, 0);
+ assert(p != 0);
+ IceSSL::PluginBaseI* plugin = static_cast<IceSSL::PluginBaseI*>(p);
+
+ IceSSL::OpenSSL::PluginI* openSslPlugin = dynamic_cast<IceSSL::OpenSSL::PluginI*>(plugin);
+ assert(openSslPlugin != 0);
+
+ return openSslPlugin->getDHParams(isExport, keyLength);
+}
+
+// verifyCallback - Certificate Verification callback function.
+int
+verifyCallback(int ok, X509_STORE_CTX* ctx)
+{
+ assert(ctx != 0);
+
+ // 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* sslConnection = static_cast<SSL*>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
+ assert(sslConnection != 0);
+
+ IceSSL::OpenSSL::ConnectionPtr connection = IceSSL::OpenSSL::Connection::getConnection(sslConnection);
+ assert(connection != 0);
+
+ // Call the connection, get it to perform the verification.
+ return connection->verifyCertificate(ok, ctx);
+}
+
+}