summaryrefslogtreecommitdiff
path: root/cpp/src/IceSSL/SChannelEngine.cpp
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2014-08-19 17:13:55 +0200
committerJose <jose@zeroc.com>2014-08-19 17:13:55 +0200
commit52a2903244d992388813fa9624f61b9cadda199d (patch)
treebd39b38f04b97981c41f39a025d12d35287a78c0 /cpp/src/IceSSL/SChannelEngine.cpp
parentFixed (ICE-5641) - MinGW compile error (diff)
downloadice-52a2903244d992388813fa9624f61b9cadda199d.tar.bz2
ice-52a2903244d992388813fa9624f61b9cadda199d.tar.xz
ice-52a2903244d992388813fa9624f61b9cadda199d.zip
Fixed (ICE-5592) - Add IceSSL.FindCert for OS X and Windows
Diffstat (limited to 'cpp/src/IceSSL/SChannelEngine.cpp')
-rw-r--r--cpp/src/IceSSL/SChannelEngine.cpp308
1 files changed, 2 insertions, 306 deletions
diff --git a/cpp/src/IceSSL/SChannelEngine.cpp b/cpp/src/IceSSL/SChannelEngine.cpp
index 4f8a8d061b4..e0aa2bc216e 100644
--- a/cpp/src/IceSSL/SChannelEngine.cpp
+++ b/cpp/src/IceSSL/SChannelEngine.cpp
@@ -76,7 +76,7 @@ addCertificateToStore(const string& file, HCERTSTORE store, PCCERT_CONTEXT* cert
}
if(!CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &outBuffer[0],
- outLength, CERT_STORE_ADD_NEW, cert))
+ outLength, CERT_STORE_ADD_NEW, cert))
{
if(GetLastError() != static_cast<DWORD>(CRYPT_E_EXISTS))
{
@@ -157,310 +157,6 @@ algorithmId(const string& name)
return 0;
}
-//
-// Parse a string of the form "location.name" into two parts.
-//
-void
-parseStore(const string& prop, const string& store, DWORD& loc, string& sname)
-{
- size_t pos = store.find('.');
- if(pos == string::npos)
- {
- throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: property `" + prop + "' has invalid format");
- }
-
- const string sloc = toUpper(store.substr(0, pos));
- if(sloc == "CURRENTUSER")
- {
- loc = CERT_SYSTEM_STORE_CURRENT_USER;
- }
- else if(sloc == "LOCALMACHINE")
- {
- loc = CERT_SYSTEM_STORE_LOCAL_MACHINE;
- }
- else
- {
- throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unknown store location `" + sloc + "' in " + prop);
- }
-
- sname = store.substr(pos + 1);
- if(sname.empty())
- {
- throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: invalid store name in " + prop);
- }
-}
-
-
-bool
-parseBytes(const string& arg, vector<BYTE>& buffer)
-{
- string v = toUpper(arg);
-
- //
- // Check for any invalid characters.
- //
- size_t pos = v.find_first_not_of(" :0123456789ABCDEF");
- if(pos != string::npos)
- {
- return false;
- }
-
- //
- // Remove any separator characters.
- //
- ostringstream s;
- for(string::const_iterator i = v.begin(); i != v.end(); ++i)
- {
- if(*i == ' ' || *i == ':')
- {
- continue;
- }
- s << *i;
- }
- v = s.str();
-
- //
- // Convert the bytes.
- //
- for(size_t i = 0, length = v.size(); i + 2 <= length;)
- {
- buffer.push_back(static_cast<BYTE>(strtol(v.substr(i, 2).c_str(), 0, 16)));
- i += 2;
- }
- return true;
-}
-
-void
-addMatchingCertificates(HCERTSTORE source, HCERTSTORE target, DWORD findType, const void* findParam)
-{
- PCCERT_CONTEXT next = 0;
- do
- {
- if((next = CertFindCertificateInStore(source, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
- findType, findParam, next)))
- {
- if(!CertAddCertificateContextToStore(target, next, CERT_STORE_ADD_ALWAYS, 0))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: error adding certificate to store:\n" + lastErrorToString());
- }
- }
- }
- while(next);
-}
-
-vector<PCCERT_CONTEXT>
-findCertificates(const string& prop, const string& storeSpec, const string& value, vector<HCERTSTORE>& stores)
-{
- DWORD storeLoc = 0;
- string storeName;
- parseStore(prop, storeSpec, storeLoc, storeName);
-
- HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, storeLoc, stringToWstring(storeName).c_str());
- if(!store)
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: failure while opening store specified by " + prop + ":\n" + lastErrorToString());
- }
-
- //
- // Start with all of the certificates in the collection and filter as necessary.
- //
- // - If the value is "*", return all certificates.
- // - Otherwise, search using key:value pairs. The following keys are supported:
- //
- // Issuer
- // IssuerDN
- // Serial
- // Subject
- // SubjectDN
- // SubjectKeyId
- // Thumbprint
- //
- // A value must be enclosed in single or double quotes if it contains whitespace.
- //
-
- HCERTSTORE tmpStore = 0;
- try
- {
- if(value != "*")
- {
- size_t start = 0;
- size_t pos;
- while((pos = value.find(':', start)) != string::npos)
- {
- string field = toUpper(trim(value.substr(start, pos - start)));
- if(field != "SUBJECT" && field != "SUBJECTDN" && field != "ISSUER" && field != "ISSUERDN" &&
- field != "THUMBPRINT" && field != "SUBJECTKEYID" && field != "SERIAL")
- {
- throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unknown key in `" + value + "'");
- }
-
- start = pos + 1;
- while(start < value.size() && (value[start] == ' ' || value[start] == '\t'))
- {
- ++start;
- }
-
- if(start == value.size())
- {
- throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: missing argument in `" + value + "'");
- }
-
- string arg;
- if(value[start] == '"' || value[start] == '\'')
- {
- size_t end = start;
- ++end;
- while(end < value.size())
- {
- if(value[end] == value[start] && value[end - 1] != '\\')
- {
- break;
- }
- ++end;
- }
- if(end == value.size() || value[end] != value[start])
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: unmatched quote in `" + value + "'");
- }
- ++start;
- arg = value.substr(start, end - start);
- start = end + 1;
- }
- else
- {
- size_t end = value.find_first_of(" \t", start);
- if(end == string::npos)
- {
- arg = value.substr(start);
- start = value.size();
- }
- else
- {
- arg = value.substr(start, end - start);
- start = end + 1;
- }
- }
-
- tmpStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 0, 0);
- if(!tmpStore)
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: error adding certificate to store:\n" + lastErrorToString());
- }
-
- if(field == "SUBJECT" || field == "ISSUER")
- {
- const wstring argW = stringToWstring(arg);
- DWORD findType = field == "SUBJECT" ? CERT_FIND_SUBJECT_STR : CERT_FIND_ISSUER_STR;
- addMatchingCertificates(store, tmpStore, findType, argW.c_str());
- }
- else if(field == "SUBJECTDN" || field == "ISSUERDN")
- {
- const wstring argW = stringToWstring(arg);
- DWORD length = 0;
- if(!CertStrToNameW(X509_ASN_ENCODING, argW.c_str(), CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
- 0, 0, &length, 0))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: invalid value `" + value + "' for property `" + prop + "'\n" +
- lastErrorToString());
- }
-
- vector<BYTE> buffer(length);
- if(!CertStrToNameW(X509_ASN_ENCODING, argW.c_str(), CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
- 0, &buffer[0], &length, 0))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: invalid value `" + value + "' for property `" + prop + "'\n" +
- lastErrorToString());
- }
-
- CERT_NAME_BLOB name = { length, &buffer[0] };
- DWORD findType = field == "SUBJECTDN" ? CERT_FIND_SUBJECT_NAME : CERT_FIND_ISSUER_NAME;
- addMatchingCertificates(store, tmpStore, findType, &name);
- }
- else if(field == "THUMBPRINT" || field == "SUBJECTKEYID")
- {
- vector<BYTE> buffer;
- if(!parseBytes(arg, buffer))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: invalid value `" + value + "' for property `" + prop + "'");
- }
-
- CRYPT_HASH_BLOB hash = { static_cast<DWORD>(buffer.size()), &buffer[0] };
- DWORD findType = field == "THUMBPRINT" ? CERT_FIND_HASH : CERT_FIND_KEY_IDENTIFIER;
- addMatchingCertificates(store, tmpStore, findType, &hash);
- }
- else if(field == "SERIAL")
- {
- vector<BYTE> buffer;
- if(!parseBytes(arg, buffer))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: invalid value `" + value + "' for property `" + prop + "'");
- }
-
- CRYPT_INTEGER_BLOB serial = { static_cast<DWORD>(buffer.size()), &buffer[0] };
- PCCERT_CONTEXT next = 0;
- do
- {
- if((next = CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
- CERT_FIND_ANY, 0, next)))
- {
- if(CertCompareIntegerBlob(&serial, &next->pCertInfo->SerialNumber))
- {
- if(!CertAddCertificateContextToStore(tmpStore, next, CERT_STORE_ADD_ALWAYS, 0))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: error adding certificate to store:\n" + lastErrorToString());
- }
- }
- }
- }
- while(next);
- }
- CertCloseStore(store, 0);
- store = tmpStore;
- }
- }
- }
- catch(...)
- {
- if(store && store != tmpStore)
- {
- CertCloseStore(store, 0);
- }
-
- if(tmpStore)
- {
- CertCloseStore(tmpStore, 0);
- tmpStore = 0;
- }
- throw;
- }
-
- vector<PCCERT_CONTEXT> certs;
- if(store)
- {
- PCCERT_CONTEXT next = 0;
- do
- {
- if((next = CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, 0,
- next)))
- {
- certs.push_back(next);
- }
- }
- while(next);
- stores.push_back(store);
- }
- return certs;
-}
-
}
SChannelEngine::SChannelEngine(const CommunicatorPtr& communicator) :
@@ -834,7 +530,7 @@ SChannelEngine::initialize()
_allCerts.insert(_allCerts.end(), _certs.begin(), _certs.end());
}
- const string findPrefix = prefix + "FindCert.";
+ const string findPrefix = prefix + "SChannel.FindCert.";
map<string, string> certProps = properties->getPropertiesForPrefix(findPrefix);
if(!certProps.empty())
{