reSIProcate/stack  9694
WinSecurity.cxx
Go to the documentation of this file.
00001 #include <sys/types.h>
00002 
00003 #if defined(HAVE_CONFIG_H)
00004   #include "config.h"
00005 #endif
00006 
00007 
00008 #ifdef USE_SSL
00009 #include "resip/stack/ssl/WinSecurity.hxx"
00010 #include <openssl/e_os2.h>
00011 #include <openssl/evp.h>
00012 #include <openssl/crypto.h>
00013 #include <openssl/err.h>
00014 #include <openssl/pem.h>
00015 #include <openssl/pkcs7.h>
00016 #include <openssl/ossl_typ.h>
00017 #include <openssl/x509.h>
00018 #include <openssl/x509v3.h>
00019 #include <openssl/ssl.h>
00020 
00021 #include <Wincrypt.h>
00022 #include "rutil/Logger.hxx"
00023 
00024 using namespace resip;
00025 using namespace std;
00026 
00027 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP
00028 
00029 #include <windows.h>
00030 #include <wincrypt.h>
00031 
00032 void 
00033 WinSecurity::preload()
00034 {
00035    HCERTSTORE storeHandle = NULL;
00036 
00037    getCerts(WinSecurity::ROOT_CA_STORE);
00038    //getCerts(WinSecurity::CA_STORE);
00039    //getCredentials(WinSecurity::PRIVATE_STORE);
00040    //getCerts(WinSecurity::USERS_STORE);   
00041 }
00042 
00043 void
00044 WinSecurity::onReadPEM(const Data& name, PEMType type, Data& buffer) const
00045 {
00046    return;
00047 }
00048 
00049 void
00050 WinSecurity::onWritePEM(const Data& name, PEMType type, const Data& buffer) const
00051 {
00052    return;
00053 }
00054 
00055 void
00056 WinSecurity::onRemovePEM(const Data& name, PEMType type) const
00057 {
00058    return;
00059 }
00060 
00061 static const Data storeRootCA("Root");
00062 static const Data storeCA("CA");
00063 static const Data storePrivate("My");
00064 static const Data storeUsers("DOMAIN_USERS");
00065 static const Data storeUnknown("UNKNOWN_STORE");
00066 static const Data 
00067 certStoreTypes(  WinSecurity::MsCertStoreType pType )
00068 {
00069    switch (pType)
00070    {
00071       case  WinSecurity::ROOT_CA_STORE:         return storeRootCA;
00072       case  WinSecurity::CA_STORE:              return storeCA;
00073       case  WinSecurity::PRIVATE_STORE:         return storePrivate;
00074       case  WinSecurity::USERS_STORE:           return storeUsers;
00075       default:
00076       {
00077          ErrLog( << "Some unknown certificate store type requested" << (int)(pType) );
00078          assert(0);
00079       }
00080    }
00081    return storeUnknown;
00082 }
00083 
00084 #ifdef UNICODE
00085 static LPWSTR AnsiToUnicode(LPCSTR szInString)
00086 {
00087    LPWSTR pwszString = NULL;
00088    if(NULL == szInString))
00089       return 0;
00090 
00091 int iLen = 0;
00092 iLen = MultiByteToWideChar( CP_UTF8, 0, szInString, -1, 0, 0 );
00093 if (0 == iLen)
00094    return pwszString;
00095 
00096       pwszString = (LPWSTR)LocalAlloc(
00097          LMEM_FIXED, 
00098          iLen * sizeof(WCHAR)
00099          );
00100 if (NULL == pwszString)
00101    return pwszString;
00102 
00103 int iRet = MultiByteToWideChar( CP_UTF8, 0, szInString, -1, pwszString, iLen );
00104 
00105 if (0 == iRet)
00106 {
00107    LocalFree(pwszString);
00108 }
00109 return pwszString;
00110 }
00111 #endif
00112 
00113 HCERTSTORE 
00114 WinSecurity::openSystemCertStore(const Data& name)
00115 {
00116    HCERTSTORE mStoreHandle = NULL;
00117    LPCTSTR storeName = NULL;
00118    DWORD dwFlags;
00119 
00120    dwFlags = CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE;
00121 
00122 #ifndef UNICODE
00123    storeName = name.c_str();
00124 #else
00125    storeName = AnsiToUnicode(name.c_str());
00126 #endif
00127 
00128    if (NULL == storeName)
00129    {
00130       ErrLog( << " Invalid store name");
00131       assert(0);
00132       return NULL;
00133    }
00134    //mStoreHandle = ::CertOpenStore(
00135    //                    CERT_STORE_PROV_SYSTEM, 
00136    //                    0, 
00137    //                    0,
00138    //                    dwFlags, 
00139    //                    storeName
00140    //                );
00141    mStoreHandle = ::CertOpenSystemStore(0, "Root");
00142 #ifdef UNICODE
00143    LocalFree((HLOCAL)storeName);
00144 #endif
00145 
00146    if(NULL == mStoreHandle)
00147    {
00148       ErrLog( << name.c_str() << " system certificate store cannot be openned");
00149       assert(0);
00150       return NULL;
00151    }
00152    InfoLog( << name.c_str() << " System certificate store opened");
00153    return mStoreHandle;
00154 }
00155 
00156 void 
00157 WinSecurity::closeCertifStore(HCERTSTORE storeHandle)
00158 {
00159    if (NULL == storeHandle)
00160       return;
00161     
00162    ::CertCloseStore(storeHandle ,0);
00163 }
00164 void 
00165 WinSecurity::getCerts(MsCertStoreType eType)
00166 {
00167    //retrive only certificates
00168    HCERTSTORE storeHandle = NULL;
00169    storeHandle = openSystemCertStore(certStoreTypes(eType));
00170    int i = 0;
00171    if(NULL != storeHandle)
00172    {
00173       PCCERT_CONTEXT   pCertContext = NULL;  
00174       while((pCertContext = ::CertEnumCertificatesInStore(storeHandle, pCertContext)) != NULL)
00175       {
00176          Data certDER(Data::Borrow, (const char*)pCertContext->pbCertEncoded, pCertContext->cbCertEncoded);
00177          addCertDER (BaseSecurity::RootCert, NULL, certDER, false);
00178          i++;
00179       }
00180       CertFreeCertificateContext(pCertContext);
00181    }
00182    InfoLog( << i << " certs loaded of type " << eType );
00183    closeCertifStore(storeHandle);
00184 }
00185 
00186 /*
00187   void 
00188   WinSecurity::getCredentials(MsCertStoreType eType)
00189   {
00190   //retrieves both certificates and assocaited private keys
00191   //retrive only certificates
00192   HCERTSTORE storeHandle = NULL;
00193   storeHandle = openCertifStore(certStoreTypes(eType));
00194   if(NULL != storeHandle)
00195   {
00196   PCCERT_CONTEXT   pCertContext = NULL;  
00197   while(pCertContext = ::CertEnumCertificatesInStore(mStoreHandle, pCertContext) != NULL)
00198   {
00199   Data certDER(Data::Take, pCertContext->pbCertEncoded, pCertContext->cbCertEncoded);
00200   addCertDER (BaseSecurity::RootCert, NULL, certDER, true);
00201   DWORD dwKeySpec;
00202   HCRYPTPROV hCryptProv;
00203   //get private key
00204   BOOL bRet = CryptAcquireCertificatePrivateKey(
00205   pCertContext,
00206   0,
00207   NULL,
00208   &hCryptProv,
00209   &dwKeySpec,
00210   NULL
00211   );
00212   if (!bRet)
00213   {
00214   ErrLog( << " Cannot retrieve private key");
00215   }
00216   }
00217   }
00218   closeCertifStore(storeHandle);
00219   }*/
00220 
00221 #endif // ifdef USE_SSL
00222 
00223 /* ====================================================================
00224  * The Vovida Software License, Version 1.0 
00225  * 
00226  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00227  * 
00228  * Redistribution and use in source and binary forms, with or without
00229  * modification, are permitted provided that the following conditions
00230  * are met:
00231  * 
00232  * 1. Redistributions of source code must retain the above copyright
00233  *    notice, this list of conditions and the following disclaimer.
00234  * 
00235  * 2. Redistributions in binary form must reproduce the above copyright
00236  *    notice, this list of conditions and the following disclaimer in
00237  *    the documentation and/or other materials provided with the
00238  *    distribution.
00239  * 
00240  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00241  *    and "Vovida Open Communication Application Library (VOCAL)" must
00242  *    not be used to endorse or promote products derived from this
00243  *    software without prior written permission. For written
00244  *    permission, please contact vocal@vovida.org.
00245  *
00246  * 4. Products derived from this software may not be called "VOCAL", nor
00247  *    may "VOCAL" appear in their name, without prior written
00248  *    permission of Vovida Networks, Inc.
00249  * 
00250  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00251  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00252  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00253  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00254  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00255  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00256  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00257  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00258  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00259  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00260  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00261  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00262  * DAMAGE.
00263  * 
00264  * ====================================================================
00265  * 
00266  * This software consists of voluntary contributions made by Vovida
00267  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00268  * Inc.  For more information on Vovida Networks, Inc., please see
00269  * <http://www.vovida.org/>.
00270  *
00271  */