1/* 2 * Copyright (c) 2006,2011,2013-2014 Apple 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 75OSStatus dbError(const SQLite3::Error &err); 76 77 78// 79// Code Signing API brackets 80// 81#define BEGIN_CSAPI \ 82 try { 83 84#define END_CSAPI \ 85 } \ 86 catch (const UnixError &err) { \ 87 switch (err.error) { \ 88 case ENOEXEC: return errSecCSBadObjectFormat; \ 89 default: return err.osStatus(); \ 90 }} \ 91 catch (const MacOSError &err) { return err.osStatus(); } \ 92 catch (const SQLite3::Error &err) { return dbError(err); } \ 93 catch (const CommonError &err) { return SecKeychainErrFromOSStatus(err.osStatus()); } \ 94 catch (const std::bad_alloc &) { return errSecAllocate; } \ 95 catch (...) { return errSecCSInternalError; } \ 96 return errSecSuccess; 97 98#define END_CSAPI_ERRORS \ 99 } \ 100 catch (const CSError &err) { return err.cfError(errors); } \ 101 catch (const UnixError &err) { \ 102 switch (err.error) { \ 103 case ENOEXEC: return CSError::cfError(errors, errSecCSBadObjectFormat); \ 104 default: return CSError::cfError(errors, err.osStatus()); \ 105 }} \ 106 catch (const MacOSError &err) { return CSError::cfError(errors, err.osStatus()); } \ 107 catch (const SQLite3::Error &err) { return CSError::cfError(errors, dbError(err)); } \ 108 catch (const CommonError &err) { return CSError::cfError(errors, SecKeychainErrFromOSStatus(err.osStatus())); } \ 109 catch (const std::bad_alloc &) { return CSError::cfError(errors, errSecAllocate); } \ 110 catch (...) { return CSError::cfError(errors, errSecCSInternalError); } \ 111 return errSecSuccess; 112 113#define END_CSAPI1(bad) } catch (...) { return bad; } 114 115 116#define END_CSAPI_ERRORS1(bad) \ 117 } \ 118 catch (const CSError &err) { err.cfError(errors); } \ 119 catch (const UnixError &err) { \ 120 switch (err.error) { \ 121 case ENOEXEC: CSError::cfError(errors, errSecCSBadObjectFormat); \ 122 default: CSError::cfError(errors, err.osStatus()); \ 123 }} \ 124 catch (const MacOSError &err) { CSError::cfError(errors, err.osStatus()); } \ 125 catch (const SQLite3::Error &err) { CSError::cfError(errors, dbError(err)); } \ 126 catch (const CommonError &err) { CSError::cfError(errors, SecKeychainErrFromOSStatus(err.osStatus())); } \ 127 catch (const std::bad_alloc &) { CSError::cfError(errors, errSecAllocate); } \ 128 catch (...) { CSError::cfError(errors, errSecCSInternalError); } \ 129 return bad; 130 131 132// 133// A version of CodeSigning::Required 134// 135template <class T> 136static inline T &Required(T *ptr) 137{ 138 if (ptr == NULL) 139 MacOSError::throwMe(errSecCSObjectRequired); 140 return *ptr; 141} 142 143static inline void Required(const void *ptr) 144{ 145 if (ptr == NULL) 146 MacOSError::throwMe(errSecCSObjectRequired); 147} 148 149 150// 151// Check flags against a validity mask 152// 153static inline void checkFlags(SecCSFlags flags, SecCSFlags acceptable = 0) 154{ 155 if (flags & ~acceptable) 156 MacOSError::throwMe(errSecCSInvalidFlags); 157} 158 159 160// 161// DTrace USDT function bracket. 162// Use like this: 163// DTRACK(PROVIDER_PROBE_PREFIX, arguments-after-this); 164// which will call 165// PROVIDER_PROBE_PREFIX_START(this, arguments-after-this) 166// and 167// PROVIDER_PROBE_PREFIX_END(this) 168// 169#define DTRACK(_prefix, _obj, _args...) \ 170 if (_prefix ## _START_ENABLED()) _prefix ## _START((_obj), ## _args); \ 171 struct _DTFrame ## _prefix { void *me; \ 172 _DTFrame ## _prefix(void *m) : me(m) { } \ 173 ~_DTFrame ## _prefix() { _prefix ## _END(me); } \ 174 } _dtframe##_prefix((_obj)); 175 176 177} // CodeSigning 178} // Security 179 180#endif //_H_CS 181