1/* 2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24// 25// cs.h - code signing core header 26// 27#ifndef _H_CS 28#define _H_CS 29 30#include "cserror.h" 31#include "codesigning_dtrace.h" 32#include <Security/CSCommonPriv.h> 33#include <Security/SecCodePriv.h> 34#include <Security/SecStaticCodePriv.h> 35#include <Security/SecRequirementPriv.h> 36#include <Security/SecCodeSigner.h> 37#include <Security/SecBasePriv.h> 38#include <security_utilities/globalizer.h> 39#include <security_utilities/seccfobject.h> 40#include <security_utilities/cfclass.h> 41#include <security_utilities/errors.h> 42#include <security_utilities/sqlite++.h> 43#include <security_utilities/cfutilities.h> 44 45 46namespace Security { 47namespace CodeSigning { 48 49 50// 51// API per-thread globals 52// 53struct PerThread { 54 SecCSFlags flags; // flags of pending API call 55}; 56 57 58// 59// API globals 60// 61struct CFObjects { 62 CFObjects(); 63 CFClass Code; 64 CFClass StaticCode; 65 CFClass Requirement; 66 CFClass CodeSigner; 67 68 ThreadNexus<PerThread> perThread; 69 70 SecCSFlags &flags() { return perThread().flags; } 71}; 72 73extern ModuleNexus<CFObjects> gCFObjects; 74 75static inline SecCSFlags apiFlags() { return gCFObjects().flags(); } 76 77OSStatus dbError(const SQLite3::Error &err); 78 79 80// 81// Code Signing API brackets 82// 83#define BEGIN_CSAPI \ 84 try { 85 86#define END_CSAPI \ 87 } \ 88 catch (const UnixError &err) { \ 89 switch (err.error) { \ 90 case ENOEXEC: return errSecCSBadObjectFormat; \ 91 default: return err.osStatus(); \ 92 }} \ 93 catch (const MacOSError &err) { return err.osStatus(); } \ 94 catch (const SQLite3::Error &err) { return dbError(err); } \ 95 catch (const CommonError &err) { return SecKeychainErrFromOSStatus(err.osStatus()); } \ 96 catch (const std::bad_alloc &) { return errSecAllocate; } \ 97 catch (...) { return errSecCSInternalError; } \ 98 return errSecSuccess; 99 100#define END_CSAPI_ERRORS \ 101 } \ 102 catch (const CSError &err) { return err.cfError(errors); } \ 103 catch (const UnixError &err) { \ 104 switch (err.error) { \ 105 case ENOEXEC: return CSError::cfError(errors, errSecCSBadObjectFormat); \ 106 default: return CSError::cfError(errors, err.osStatus()); \ 107 }} \ 108 catch (const MacOSError &err) { return CSError::cfError(errors, err.osStatus()); } \ 109 catch (const SQLite3::Error &err) { return CSError::cfError(errors, dbError(err)); } \ 110 catch (const CommonError &err) { return CSError::cfError(errors, SecKeychainErrFromOSStatus(err.osStatus())); } \ 111 catch (const std::bad_alloc &) { return CSError::cfError(errors, errSecAllocate); } \ 112 catch (...) { return CSError::cfError(errors, errSecCSInternalError); } \ 113 return errSecSuccess; 114 115#define END_CSAPI1(bad) } catch (...) { return bad; } 116 117 118#define END_CSAPI_ERRORS1(bad) \ 119 } \ 120 catch (const CSError &err) { err.cfError(errors); } \ 121 catch (const UnixError &err) { \ 122 switch (err.error) { \ 123 case ENOEXEC: CSError::cfError(errors, errSecCSBadObjectFormat); \ 124 default: CSError::cfError(errors, err.osStatus()); \ 125 }} \ 126 catch (const MacOSError &err) { CSError::cfError(errors, err.osStatus()); } \ 127 catch (const SQLite3::Error &err) { CSError::cfError(errors, dbError(err)); } \ 128 catch (const CommonError &err) { CSError::cfError(errors, SecKeychainErrFromOSStatus(err.osStatus())); } \ 129 catch (const std::bad_alloc &) { CSError::cfError(errors, errSecAllocate); } \ 130 catch (...) { CSError::cfError(errors, errSecCSInternalError); } \ 131 return bad; 132 133 134// 135// A version of CodeSigning::Required 136// 137template <class T> 138static inline T &Required(T *ptr) 139{ 140 if (ptr == NULL) 141 MacOSError::throwMe(errSecCSObjectRequired); 142 return *ptr; 143} 144 145static inline void Required(const void *ptr) 146{ 147 if (ptr == NULL) 148 MacOSError::throwMe(errSecCSObjectRequired); 149} 150 151 152// 153// Check flags against a validity mask 154// 155static inline void checkFlags(SecCSFlags flags, SecCSFlags acceptable = 0) 156{ 157 if (flags & ~acceptable) 158 MacOSError::throwMe(errSecCSInvalidFlags); 159 gCFObjects().flags() = flags; 160} 161 162 163// 164// DTrace USDT function bracket. 165// Use like this: 166// DTRACK(PROVIDER_PROBE_PREFIX, arguments-after-this); 167// which will call 168// PROVIDER_PROBE_PREFIX_START(this, arguments-after-this) 169// and 170// PROVIDER_PROBE_PREFIX_END(this) 171// 172#define DTRACK(_prefix, _obj, _args...) \ 173 if (_prefix ## _START_ENABLED()) _prefix ## _START((_obj), ## _args); \ 174 struct _DTFrame ## _prefix { void *me; \ 175 _DTFrame ## _prefix(void *m) : me(m) { } \ 176 ~_DTFrame ## _prefix() { _prefix ## _END(me); } \ 177 } _dtframe##_prefix((_obj)); 178 179 180} // CodeSigning 181} // Security 182 183#endif //_H_CS 184