2 * Copyright (c) 2006-2007 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 // SecStaticCode - API frame for SecStaticCode objects
28 #include "StaticCode.h"
31 using namespace CodeSigning
;
35 // CF-standard type code function
37 CFTypeID
SecStaticCodeGetTypeID(void)
40 return gCFObjects().StaticCode
.typeID
;
41 END_CSAPI1(_kCFRuntimeNotATypeID
)
46 // Create an StaticCode directly from disk path.
48 OSStatus
SecStaticCodeCreateWithPath(CFURLRef path
, SecCSFlags flags
, SecStaticCodeRef
*staticCodeRef
)
53 Required(staticCodeRef
) = (new SecStaticCode(DiskRep::bestGuess(cfString(path
).c_str())))->handle();
60 // Check static validity of a StaticCode
62 OSStatus
SecStaticCodeCheckValidity(SecStaticCodeRef staticCodeRef
, SecCSFlags flags
,
63 SecRequirementRef requirementRef
)
65 return SecStaticCodeCheckValidityWithErrors(staticCodeRef
, flags
, requirementRef
, NULL
);
68 OSStatus
SecStaticCodeCheckValidityWithErrors(SecStaticCodeRef staticCodeRef
, SecCSFlags flags
,
69 SecRequirementRef requirementRef
, CFErrorRef
*errors
)
74 kSecCSCheckAllArchitectures
75 | kSecCSDoNotValidateExecutable
76 | kSecCSDoNotValidateResources
77 | kSecCSConsiderExpiration
);
79 SecPointer
<SecStaticCode
> code
= SecStaticCode::requiredStatic(staticCodeRef
);
80 DTRACK(CODESIGN_EVAL_STATIC
, code
, (char*)code
->mainExecutablePath().c_str());
81 code
->validateDirectory();
82 if (!(flags
& kSecCSDoNotValidateExecutable
))
83 code
->validateExecutable();
84 if (!(flags
& kSecCSDoNotValidateResources
))
85 code
->validateResources();
86 if (const SecRequirement
*req
= SecRequirement::optional(requirementRef
))
87 code
->validateRequirements(req
->requirement(), errSecCSReqFailed
);
94 // ====================================================================================
96 // The following API functions are called SecCode* but accept both SecCodeRef and
97 // SecStaticCodeRef arguments, operating on the implied SecStaticCodeRef as appropriate.
98 // Hence they're here, rather than in SecCode.cpp.
103 // Retrieve location information for an StaticCode.
105 OSStatus
SecCodeCopyPath(SecStaticCodeRef staticCodeRef
, SecCSFlags flags
, CFURLRef
*path
)
110 SecPointer
<SecStaticCode
> staticCode
= SecStaticCode::requiredStatic(staticCodeRef
);
111 Required(path
) = staticCode
->canonicalPath();
118 // Fetch or make up a designated requirement
120 OSStatus
SecCodeCopyDesignatedRequirement(SecStaticCodeRef staticCodeRef
, SecCSFlags flags
,
121 SecRequirementRef
*requirementRef
)
126 const Requirement
*req
=
127 SecStaticCode::requiredStatic(staticCodeRef
)->designatedRequirement();
128 Required(requirementRef
) = (new SecRequirement(req
))->handle();
135 // Fetch a particular internal requirement, if present
137 OSStatus
SecCodeCopyInternalRequirement(SecStaticCodeRef staticCodeRef
, SecRequirementType type
,
138 SecCSFlags flags
, SecRequirementRef
*requirementRef
)
143 const Requirement
*req
=
144 SecStaticCode::requiredStatic(staticCodeRef
)->internalRequirement(type
);
145 Required(requirementRef
) = req
? (new SecRequirement(req
))->handle() : NULL
;
152 // Record for future use a detached code signature.
154 OSStatus
SecCodeSetDetachedSignature(SecStaticCodeRef codeRef
, CFDataRef signature
,
160 SecPointer
<SecStaticCode
> code
= SecStaticCode::requiredStatic(codeRef
);
163 CFRetain(signature
); // own a reference...
164 code
->detachedSignature(signature
); // ... and pass it to the code
165 code
->resetValidity();
172 // Attach a code signature to a kernel memory mapping for page-in validation.
174 OSStatus
SecCodeMapMemory(SecStaticCodeRef codeRef
, SecCSFlags flags
)
179 SecPointer
<SecStaticCode
> code
= SecStaticCode::requiredStatic(codeRef
);
180 if (const CodeDirectory
*cd
= code
->codeDirectory(false)) {
181 fsignatures args
= { code
->diskRep()->signingBase(), (void *)cd
, cd
->length() };
182 UnixError::check(::fcntl(code
->diskRep()->fd(), F_ADDSIGS
, &args
));
184 MacOSError::throwMe(errSecCSUnsigned
);