summaryrefslogtreecommitdiff
path: root/cpp/src/IceSSL/RSACertificateGen.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/RSACertificateGen.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/RSACertificateGen.cpp')
-rw-r--r--cpp/src/IceSSL/RSACertificateGen.cpp355
1 files changed, 355 insertions, 0 deletions
diff --git a/cpp/src/IceSSL/RSACertificateGen.cpp b/cpp/src/IceSSL/RSACertificateGen.cpp
new file mode 100644
index 00000000000..173e18a1017
--- /dev/null
+++ b/cpp/src/IceSSL/RSACertificateGen.cpp
@@ -0,0 +1,355 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Config.h>
+#include <IceSSL/RSACertificateGen.h>
+#include <IceSSL/OpenSSLJanitors.h>
+#include <IceSSL/RSAKeyPair.h>
+#include <IceSSL/RSAPrivateKey.h>
+#include <IceSSL/RSAPublicKey.h>
+#include <IceSSL/Exception.h>
+#include <IceSSL/OpenSSLUtils.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+using std::string;
+using std::back_inserter;
+
+using namespace IceSSL::OpenSSL;
+
+long
+IceSSL::OpenSSL::RSACertificateGenContext::minutesToSeconds(long minutes)
+{
+ return minutes * 60L;
+}
+
+long
+IceSSL::OpenSSL::RSACertificateGenContext::hoursToSeconds(long hours)
+{
+ return minutesToSeconds(hours * 60L);
+}
+
+long
+IceSSL::OpenSSL::RSACertificateGenContext::daysToSeconds(long days)
+{
+ return hoursToSeconds(days * 24L);
+}
+
+long
+IceSSL::OpenSSL::RSACertificateGenContext::weeksToSeconds(long weeks)
+{
+ return daysToSeconds(weeks * 7L);
+}
+
+long
+IceSSL::OpenSSL::RSACertificateGenContext::yearsToSeconds(long years)
+{
+ return weeksToSeconds(years * 365L);
+}
+
+IceSSL::OpenSSL::RSACertificateGenContext::RSACertificateGenContext() :
+ _modulusLength(0),
+ _secondsValid(0)
+{
+}
+
+IceSSL::OpenSSL::RSACertificateGenContext::~RSACertificateGenContext()
+{
+}
+
+void
+IceSSL::OpenSSL::RSACertificateGenContext::setCountry(const string& country)
+{
+ _country = country;
+}
+
+void
+IceSSL::OpenSSL::RSACertificateGenContext::setStateProvince(const string& stateProvince)
+{
+ _stateProvince = stateProvince;
+}
+
+void
+IceSSL::OpenSSL::RSACertificateGenContext::setLocality(const string& locality)
+{
+ _locality = locality;
+}
+
+void
+IceSSL::OpenSSL::RSACertificateGenContext::setOrganization(const string& organization)
+{
+ _organization = organization;
+}
+
+void
+IceSSL::OpenSSL::RSACertificateGenContext::setOrgainizationalUnit(const string& organizationalUnit)
+{
+ _organizationalUnit = organizationalUnit;
+}
+
+void
+IceSSL::OpenSSL::RSACertificateGenContext::setCommonName(const string& commonName)
+{
+ _commonName = commonName;
+}
+
+void
+IceSSL::OpenSSL::RSACertificateGenContext::setBitStrength(int bitStrength)
+{
+ _modulusLength = bitStrength;
+}
+
+void
+IceSSL::OpenSSL::RSACertificateGenContext::setSecondsValid(long secondsValid)
+{
+ _secondsValid = secondsValid;
+}
+
+unsigned char*
+IceSSL::OpenSSL::RSACertificateGenContext::getCountry() const
+{
+ unsigned char* country = reinterpret_cast<unsigned char *>(const_cast<char*>(_country.c_str()));
+
+ assert(country != 0);
+
+ return country;
+}
+
+unsigned char*
+IceSSL::OpenSSL::RSACertificateGenContext::getStateProvince() const
+{
+ unsigned char* stateProvince = reinterpret_cast<unsigned char *>(const_cast<char*>(_stateProvince.c_str()));
+
+ assert(stateProvince != 0);
+
+ return stateProvince;
+}
+
+unsigned char*
+IceSSL::OpenSSL::RSACertificateGenContext::getLocality() const
+{
+ unsigned char* locality = reinterpret_cast<unsigned char *>(const_cast<char*>(_locality.c_str()));
+
+ assert(locality != 0);
+
+ return locality;
+}
+
+unsigned char*
+IceSSL::OpenSSL::RSACertificateGenContext::getOrganization() const
+{
+ unsigned char* organization = reinterpret_cast<unsigned char *>(const_cast<char*>(_organization.c_str()));
+
+ assert(organization != 0);
+
+ return organization;
+}
+
+unsigned char*
+IceSSL::OpenSSL::RSACertificateGenContext::getOrgainizationalUnit() const
+{
+ unsigned char* orgUnit = reinterpret_cast<unsigned char *>(const_cast<char*>(_organizationalUnit.c_str()));
+
+ assert(orgUnit != 0);
+
+ return orgUnit;
+}
+
+unsigned char*
+IceSSL::OpenSSL::RSACertificateGenContext::getCommonName() const
+{
+ unsigned char* commonName = reinterpret_cast<unsigned char *>(const_cast<char*>(_commonName.c_str()));
+
+ assert(commonName != 0);
+
+ return commonName;
+}
+
+int
+IceSSL::OpenSSL::RSACertificateGenContext::getModulusLength() const
+{
+ return _modulusLength;
+}
+
+long
+IceSSL::OpenSSL::RSACertificateGenContext::getSecondsValid() const
+{
+ return _secondsValid;
+}
+
+IceSSL::OpenSSL::RSACertificateGen::RSACertificateGen()
+{
+ ERR_load_crypto_strings();
+}
+
+IceSSL::OpenSSL::RSACertificateGen::~RSACertificateGen()
+{
+}
+
+IceSSL::OpenSSL::RSAKeyPairPtr
+IceSSL::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 != 0);
+
+ EVP_PKEYJanitor evpPkeyJanitor(EVP_PKEY_new());
+ EVP_PKEY* pkey = evpPkeyJanitor.get();
+ assert(pkey != 0);
+ 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 != 0);
+
+ X509Janitor x509Janitor(X509_new());
+ X509* x509SelfSigned = x509Janitor.get();
+ assert(x509SelfSigned != 0);
+
+ // Set version to V3.
+ int setVersionReturn = X509_set_version(x509SelfSigned, 2);
+ assert(setVersionReturn != 0);
+
+ 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 Distinguished Name (DN).
+ 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()))
+ {
+ throw IceSSL::CertificateSigningException(__FILE__, __LINE__);
+ }
+
+ // Verify the Signature (paranoia).
+ if (!X509_REQ_verify(signingRequest, pkey))
+ {
+ throw IceSSL::CertificateSignatureException(__FILE__, __LINE__);
+ }
+
+ // Nasty Hack: Getting the pkey to let go of our rsaKeyPair - we own that now.
+ pkey->pkey.ptr = 0;
+
+ RSAPrivateKeyPtr privKeyPtr = new RSAPrivateKey(rsaKeyPair);
+ RSAPublicKeyPtr pubKeyPtr = new RSAPublicKey(x509SelfSigned);
+ RSAKeyPair* keyPairPtr = new RSAKeyPair(privKeyPtr, pubKeyPtr);
+
+ // Do not let the janitors clean up, we're keeping the keys for ourselves.
+ rsaJanitor.clear();
+ x509Janitor.clear();
+
+ return keyPairPtr;
+}
+
+IceSSL::OpenSSL::RSAKeyPairPtr
+IceSSL::OpenSSL::RSACertificateGen::loadKeyPair(const std::string& keyFile, const std::string& certFile)
+{
+ //
+ // Read in the X509 Certificate Structure
+ //
+ BIOJanitor certBIO(BIO_new_file(certFile.c_str(), "r"));
+ if (certBIO.get() == 0)
+ {
+ IceSSL::OpenSSL::CertificateLoadException certLoadEx(__FILE__, __LINE__);
+
+ certLoadEx._message = "unable to load certificate from '";
+ certLoadEx._message += certFile;
+ certLoadEx._message += "'\n";
+ certLoadEx._message += sslGetErrors();
+
+ throw certLoadEx;
+ }
+
+ X509Janitor x509Janitor(PEM_read_bio_X509(certBIO.get(), 0, 0, 0));
+
+ if (x509Janitor.get() == 0)
+ {
+ IceSSL::OpenSSL::CertificateLoadException certLoadEx(__FILE__, __LINE__);
+
+ certLoadEx._message = "unable to load certificate from '";
+ certLoadEx._message += certFile;
+ certLoadEx._message += "'\n";
+ certLoadEx._message += sslGetErrors();
+
+ throw certLoadEx;
+ }
+
+ //
+ // Read in the RSA Private Key Structure
+ //
+ BIOJanitor keyBIO(BIO_new_file(keyFile.c_str(), "r"));
+ if (keyBIO.get() == 0)
+ {
+ IceSSL::OpenSSL::PrivateKeyLoadException pklEx(__FILE__, __LINE__);
+
+ pklEx._message = "unable to load private key from '";
+ pklEx._message += keyFile;
+ pklEx._message += "'\n";
+ pklEx._message += sslGetErrors();
+
+ throw pklEx;
+ }
+
+ RSAJanitor rsaJanitor(PEM_read_bio_RSAPrivateKey(keyBIO.get(), 0, 0, 0));
+
+ if (rsaJanitor.get() == 0)
+ {
+ IceSSL::OpenSSL::PrivateKeyLoadException pklEx(__FILE__, __LINE__);
+
+ pklEx._message = "unable to load private key from '";
+ pklEx._message += keyFile;
+ pklEx._message += "'\n";
+ pklEx._message += sslGetErrors();
+
+ throw pklEx;
+ }
+
+ //
+ // Construct our RSAKeyPair
+ //
+ RSAPrivateKeyPtr privKeyPtr = new RSAPrivateKey(rsaJanitor.get());
+ RSAPublicKeyPtr pubKeyPtr = new RSAPublicKey(x509Janitor.get());
+ RSAKeyPairPtr keyPairPtr = new RSAKeyPair(privKeyPtr, pubKeyPtr);
+
+ // Do not let the janitors clean up, we're keeping these keys.
+ rsaJanitor.clear();
+ x509Janitor.clear();
+
+ return keyPairPtr;
+}