reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
MacSecurity.cxx
Go to the documentation of this file.
1
2#if defined(HAVE_CONFIG_H)
3 #include "config.h"
4#endif
5
6#ifdef __clang__
7#pragma clang diagnostic ignored "-Wdeprecated"
8#endif
9
10#ifdef USE_SSL
11// .amr. Must include Apple headers first, otherwise conflicts with rutil/compat.hxx happen due to SDK type differences
12#include <CoreFoundation/CoreFoundation.h>
13#include <CoreServices/CoreServices.h>
14#include <Security/Security.h>
15
16#include <openssl/e_os2.h>
17#include <openssl/evp.h>
18#include <openssl/crypto.h>
19#include <openssl/err.h>
20#include <openssl/pem.h>
21#include <openssl/pkcs7.h>
22#include <openssl/ossl_typ.h>
23#include <openssl/x509.h>
24#include <openssl/x509v3.h>
25#include <openssl/ssl.h>
26
28#include "rutil/Logger.hxx"
29
30using namespace resip;
31using namespace std;
32
33#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
34
35int verifyCallback(int iInCode, X509_STORE_CTX *pInStore);
36
37void
39{
40 // load the root certificates
41 getCerts();
42}
43
44// Opens a search handle to certificates store in
45// the X509Anchors keychain
48{
49 OSStatus status = noErr;
50
51 const char *pathName = nil;
52 SInt32 MacVersion = 0;
53
54 if (Gestalt(gestaltSystemVersion, &MacVersion) == noErr)
55 {
56 if (MacVersion >= 0x1050)
57 {
58 //for Leopard OSX, the root certificate are located in SystemRootCertificates.keychain
59 pathName = "/System/Library/Keychains/SystemRootCertificates.keychain";
60 }
61 else
62 {
63 //for earlier OSX (including Tiger), the root certificate are located in X509Anchors
64 pathName = "/System/Library/Keychains/X509Anchors";
65 }
66 }
67 if(nil == pathName)
68 {
69 ErrLog( << "Cannot retrieve OS version");
70 return NULL;
71 }
72 // NOTE: instead of hardcoding the "/System" portion of the path
73 // we could retrieve it using ::FSFindFolder instead. But it
74 // doesn't seem useful right now.
75 SecKeychainRef systemCertsKeyChain;
76 status = ::SecKeychainOpen(
77 pathName,
78 &systemCertsKeyChain
79 );
80
81 if (status != noErr)
82 {
83 ErrLog( << "X509Anchors keychain could not be opened");
84 resip_assert(0);
85 return NULL;
86 }
87
88 // Create a handle to search that iterates over root certificates
89 // in the X509Anchors keychain
90
91 SecKeychainSearchRef searchReference = nil;
92 status = ::SecKeychainSearchCreateFromAttributes(
93 systemCertsKeyChain,
94 kSecCertificateItemClass,
95 NULL,
96 &searchReference
97 );
98
99 // Now that we have the search handle we don't need an explicit
100 // reference to the keychain
101
102 ::CFRelease(systemCertsKeyChain);
103
104 if (status != noErr)
105 {
106 ErrLog( << "System certificate store cannot be opened");
107 resip_assert(0);
108 return NULL;
109 }
110
111 InfoLog( << "System certificate store opened");
112 return searchReference;
113}
114
115void
117{
118 if (NULL == searchReference)
119 return;
120
121 ::CFRelease(searchReference);
122}
123
124void
126{
127 SecKeychainSearchRef searchReference = NULL;
128 searchReference = (SecKeychainSearchRef) openSystemCertStore();
129
130 // nothing to do, error already reported
131 if (searchReference == NULL)
132 return;
133
134 // iterate over each certificate
135 for (;;)
136 {
137 OSStatus status = noErr;
138 SecKeychainItemRef itemRef = nil;
139
140 // get the next certificate in the search
141 status = ::SecKeychainSearchCopyNext(
142 searchReference,
143 &itemRef
144 );
145 if (status == errSecItemNotFound)
146 {
147 // no more certificates left
148 break;
149 }
150
151 // get data from the certificate
152 if (status == noErr)
153 {
154 void *data;
155 uint32_t dataSize;
156 status = ::SecKeychainItemCopyAttributesAndData(
157 itemRef,
158 NULL,
159 NULL,
160 NULL,
161 &dataSize,
162 &data
163 );
164
165 if (status == noErr && data != NULL)
166 {
167 Data certDER(Data::Borrow, (const char*)data, dataSize);
168 addCertDER(BaseSecurity::RootCert, NULL, certDER, false);
169
170 status = ::SecKeychainItemFreeAttributesAndData(NULL, data);
171 }
172 }
173
174 // free the certificate handle
175 if (itemRef != NULL)
176 ::CFRelease(itemRef);
177
178 if (status != noErr)
179 {
180 // there was an error loading the certificate
181 ErrLog( << "Couldn't load certificate, error code: " << status);
182 resip_assert(0);
183 }
184 }
185
186 closeCertifStore(searchReference);
187}
188
189// TODO: this needs to be refactored with WinSecurity.cxx
190int
191verifyCallback(int iInCode, X509_STORE_CTX *pInStore)
192{
193 char cBuf1[500];
194 char cBuf2[500];
195 X509 *pErrCert;
196 int iErr = 0;
197 int iDepth = 0;
198 pErrCert = X509_STORE_CTX_get_current_cert(pInStore);
199 iErr = X509_STORE_CTX_get_error(pInStore);
200 iDepth = X509_STORE_CTX_get_error_depth(pInStore);
201
202 if (NULL != pErrCert)
203 X509_NAME_oneline(X509_get_subject_name(pErrCert),cBuf1,256);
204
205 snprintf(cBuf2,sizeof(cBuf2),"depth=%d %s\n",iDepth,cBuf1);
206 if(!iInCode)
207 {
208 memset(cBuf2, 0, sizeof(cBuf2) );
209 snprintf(cBuf2, sizeof(cBuf2), "\n Error %s", X509_verify_cert_error_string(X509_STORE_CTX_get_error(pInStore)) );
210 }
211
212 return iInCode;
213}
214
215#endif /* USE_SSL */
216
217/* ====================================================================
218 * The Vovida Software License, Version 1.0
219 *
220 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
221 *
222 * Redistribution and use in source and binary forms, with or without
223 * modification, are permitted provided that the following conditions
224 * are met:
225 *
226 * 1. Redistributions of source code must retain the above copyright
227 * notice, this list of conditions and the following disclaimer.
228 *
229 * 2. Redistributions in binary form must reproduce the above copyright
230 * notice, this list of conditions and the following disclaimer in
231 * the documentation and/or other materials provided with the
232 * distribution.
233 *
234 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
235 * and "Vovida Open Communication Application Library (VOCAL)" must
236 * not be used to endorse or promote products derived from this
237 * software without prior written permission. For written
238 * permission, please contact vocal@vovida.org.
239 *
240 * 4. Products derived from this software may not be called "VOCAL", nor
241 * may "VOCAL" appear in their name, without prior written
242 * permission of Vovida Networks, Inc.
243 *
244 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
245 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
246 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
247 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
248 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
249 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
250 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
251 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
252 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
253 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
255 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
256 * DAMAGE.
257 *
258 * ====================================================================
259 *
260 * This software consists of voluntary contributions made by Vovida
261 * Networks, Inc. and many individuals on behalf of Vovida Networks,
262 * Inc. For more information on Vovida Networks, Inc., please see
263 * <http://www.vovida.org/>.
264 *
265 */
struct x509_st X509
#define InfoLog(args_)
Definition Logger.hxx:131
#define ErrLog(args_)
Definition Logger.hxx:137
int verifyCallback(int iInCode, X509_STORE_CTX *pInStore)
#define resip_assert(x)
This file needs to work for both C and C++ code.
void addCertDER(PEMType type, const Data &name, const Data &certDER, bool write)
Definition Security.cxx:550
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
@ Borrow
The Data instance is borrowing the memory from the passed in buffer.
Definition Data.hxx:260
KeychainHandle openSystemCertStore()
void closeCertifStore(KeychainHandle searchReference)
virtual void preload()
dcm! – add UnusedChecking(_enum) below;
unsigned int uint32_t
Definition Stun.hxx:34
void * KeychainHandle