|
reSIProcate/stack
9694
|
00001 00002 #if defined(HAVE_CONFIG_H) 00003 #include "config.h" 00004 #endif 00005 00006 #ifdef USE_SSL 00007 // .amr. Must include Apple headers first, otherwise conflicts with rutil/compat.hxx happen due to SDK type differences 00008 #include <CoreFoundation/CoreFoundation.h> 00009 #include <CoreServices/CoreServices.h> 00010 #include <Security/Security.h> 00011 00012 #include <openssl/e_os2.h> 00013 #include <openssl/evp.h> 00014 #include <openssl/crypto.h> 00015 #include <openssl/err.h> 00016 #include <openssl/pem.h> 00017 #include <openssl/pkcs7.h> 00018 #include <openssl/ossl_typ.h> 00019 #include <openssl/x509.h> 00020 #include <openssl/x509v3.h> 00021 #include <openssl/ssl.h> 00022 00023 #include "resip/stack/ssl/MacSecurity.hxx" 00024 #include "rutil/Logger.hxx" 00025 00026 using namespace resip; 00027 using namespace std; 00028 00029 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP 00030 00031 int verifyCallback(int iInCode, X509_STORE_CTX *pInStore); 00032 00033 void 00034 MacSecurity::preload() 00035 { 00036 // load the root certificates 00037 getCerts(); 00038 } 00039 00040 // Opens a search handle to certificates store in 00041 // the X509Anchors keychain 00042 KeychainHandle 00043 MacSecurity::openSystemCertStore() 00044 { 00045 OSStatus status = noErr; 00046 00047 const char *pathName = nil; 00048 SInt32 MacVersion = 0; 00049 00050 if (Gestalt(gestaltSystemVersion, &MacVersion) == noErr) 00051 { 00052 if (MacVersion >= 0x1050) 00053 { 00054 //for Leopard OSX, the root certificate are located in SystemRootCertificates.keychain 00055 pathName = "/System/Library/Keychains/SystemRootCertificates.keychain"; 00056 } 00057 else 00058 { 00059 //for earlier OSX (including Tiger), the root certificate are located in X509Anchors 00060 pathName = "/System/Library/Keychains/X509Anchors"; 00061 } 00062 } 00063 if(nil == pathName) 00064 { 00065 ErrLog( << "Cannot retrieve OS version"); 00066 return NULL; 00067 } 00068 // NOTE: instead of hardcoding the "/System" portion of the path 00069 // we could retrieve it using ::FSFindFolder instead. But it 00070 // doesn't seem useful right now. 00071 SecKeychainRef systemCertsKeyChain; 00072 status = ::SecKeychainOpen( 00073 pathName, 00074 &systemCertsKeyChain 00075 ); 00076 00077 if (status != noErr) 00078 { 00079 ErrLog( << "X509Anchors keychain could not be opened"); 00080 assert(0); 00081 return NULL; 00082 } 00083 00084 // Create a handle to search that iterates over root certificates 00085 // in the X509Anchors keychain 00086 00087 SecKeychainSearchRef searchReference = nil; 00088 status = ::SecKeychainSearchCreateFromAttributes( 00089 systemCertsKeyChain, 00090 kSecCertificateItemClass, 00091 NULL, 00092 &searchReference 00093 ); 00094 00095 // Now that we have the search handle we don't need an explicit 00096 // reference to the keychain 00097 00098 ::CFRelease(systemCertsKeyChain); 00099 00100 if (status != noErr) 00101 { 00102 ErrLog( << "System certificate store cannot be opened"); 00103 assert(0); 00104 return NULL; 00105 } 00106 00107 InfoLog( << "System certificate store opened"); 00108 return searchReference; 00109 } 00110 00111 void 00112 MacSecurity::closeCertifStore(KeychainHandle searchReference) 00113 { 00114 if (NULL == searchReference) 00115 return; 00116 00117 ::CFRelease(searchReference); 00118 } 00119 00120 void 00121 MacSecurity::getCerts() 00122 { 00123 SecKeychainSearchRef searchReference = NULL; 00124 searchReference = (SecKeychainSearchRef) openSystemCertStore(); 00125 00126 // nothing to do, error already reported 00127 if (searchReference == NULL) 00128 return; 00129 00130 // iterate over each certificate 00131 for (;;) 00132 { 00133 OSStatus status = noErr; 00134 SecKeychainItemRef itemRef = nil; 00135 00136 // get the next certificate in the search 00137 status = ::SecKeychainSearchCopyNext( 00138 searchReference, 00139 &itemRef 00140 ); 00141 if (status == errSecItemNotFound) 00142 { 00143 // no more certificates left 00144 break; 00145 } 00146 00147 // get data from the certificate 00148 if (status == noErr) 00149 { 00150 void *data; 00151 UInt32 dataSize; 00152 status = ::SecKeychainItemCopyAttributesAndData( 00153 itemRef, 00154 NULL, 00155 NULL, 00156 NULL, 00157 &dataSize, 00158 &data 00159 ); 00160 00161 if (status == noErr && data != NULL) 00162 { 00163 Data certDER(Data::Borrow, (const char*)data, dataSize); 00164 addCertDER(BaseSecurity::RootCert, NULL, certDER, false); 00165 00166 status = ::SecKeychainItemFreeAttributesAndData(NULL, data); 00167 } 00168 } 00169 00170 // free the certificate handle 00171 if (itemRef != NULL) 00172 ::CFRelease(itemRef); 00173 00174 if (status != noErr) 00175 { 00176 // there was an error loading the certificate 00177 ErrLog( << "Couldn't load certificate, error code: " << status); 00178 assert(0); 00179 } 00180 } 00181 00182 closeCertifStore(searchReference); 00183 } 00184 00185 // TODO: this needs to be refactored with WinSecurity.cxx 00186 int 00187 verifyCallback(int iInCode, X509_STORE_CTX *pInStore) 00188 { 00189 char cBuf1[500]; 00190 char cBuf2[500]; 00191 X509 *pErrCert; 00192 int iErr = 0; 00193 int iDepth = 0; 00194 pErrCert = X509_STORE_CTX_get_current_cert(pInStore); 00195 iErr = X509_STORE_CTX_get_error(pInStore); 00196 iDepth = X509_STORE_CTX_get_error_depth(pInStore); 00197 00198 if (NULL != pErrCert) 00199 X509_NAME_oneline(X509_get_subject_name(pErrCert),cBuf1,256); 00200 00201 sprintf(cBuf2,"depth=%d %s\n",iDepth,cBuf1); 00202 if(!iInCode) 00203 { 00204 memset(cBuf2, 0, sizeof(cBuf2) ); 00205 sprintf(cBuf2, "\n Error %s", X509_verify_cert_error_string(pInStore->error) ); 00206 } 00207 00208 return iInCode; 00209 } 00210 00211 #endif /* USE_SSL */ 00212 00213 /* ==================================================================== 00214 * The Vovida Software License, Version 1.0 00215 * 00216 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00217 * 00218 * Redistribution and use in source and binary forms, with or without 00219 * modification, are permitted provided that the following conditions 00220 * are met: 00221 * 00222 * 1. Redistributions of source code must retain the above copyright 00223 * notice, this list of conditions and the following disclaimer. 00224 * 00225 * 2. Redistributions in binary form must reproduce the above copyright 00226 * notice, this list of conditions and the following disclaimer in 00227 * the documentation and/or other materials provided with the 00228 * distribution. 00229 * 00230 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00231 * and "Vovida Open Communication Application Library (VOCAL)" must 00232 * not be used to endorse or promote products derived from this 00233 * software without prior written permission. For written 00234 * permission, please contact vocal@vovida.org. 00235 * 00236 * 4. Products derived from this software may not be called "VOCAL", nor 00237 * may "VOCAL" appear in their name, without prior written 00238 * permission of Vovida Networks, Inc. 00239 * 00240 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00241 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00242 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00243 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00244 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00245 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00246 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00247 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00248 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00249 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00250 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00251 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00252 * DAMAGE. 00253 * 00254 * ==================================================================== 00255 * 00256 * This software consists of voluntary contributions made by Vovida 00257 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00258 * Inc. For more information on Vovida Networks, Inc., please see 00259 * <http://www.vovida.org/>. 00260 * 00261 */
1.7.5.1