diff options
author | Jose <jose@zeroc.com> | 2014-08-19 17:13:55 +0200 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2014-08-19 17:13:55 +0200 |
commit | 52a2903244d992388813fa9624f61b9cadda199d (patch) | |
tree | bd39b38f04b97981c41f39a025d12d35287a78c0 /cpp/src/IceSSL/SChannelEngine.cpp | |
parent | Fixed (ICE-5641) - MinGW compile error (diff) | |
download | ice-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.cpp | 308 |
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()) { |