]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_codesigning/lib/diskrep.h
b92195218a01c6aec7af58194f004839883a7573
   2  * Copyright (c) 2006-2007,2011-2012,2014 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 // diskrep - disk representations of code 
  31 #include "codedirectory.h" 
  32 #include "cdbuilder.h" 
  33 #include "requirement.h" 
  34 #include "resources.h" 
  35 #include <security_utilities/macho++.h>         // for class Architecture 
  36 #include <security_utilities/refcount.h> 
  37 #include <security_utilities/superblob.h> 
  38 #include <CoreFoundation/CFData.h> 
  41 namespace CodeSigning 
{ 
  43 class ResourceBuilder
; 
  47 // DiskRep is an abstract interface to code somewhere located by 
  48 // a file system path. It presents the ability to read and write 
  49 // Code Signing-related information about such code without exposing 
  50 // the details of the storage locations or formats. 
  52 class DiskRep 
: public RefCount 
{ 
  56         typedef std::set
<OSStatus
> ToleratedErrors
; 
  61         virtual DiskRep 
*base(); 
  62         virtual CFDataRef 
component(CodeDirectory::SpecialSlot slot
) = 0; // fetch component 
  63         virtual CFDataRef 
identification() = 0;                                 // binary lookup identifier 
  64         virtual std::string 
mainExecutablePath() = 0;                   // path to main executable 
  65         virtual CFURLRef 
copyCanonicalPath() = 0;                                       // path to whole code 
  66         virtual std::string 
resourcesRootPath();                                // resource directory if any [none] 
  67         virtual void adjustResources(ResourceBuilder 
&builder
); // adjust resource rule set [no change] 
  68         virtual Universal 
*mainExecutableImage();                               // Mach-O image if Mach-O based [null] 
  69         virtual size_t signingBase();                                                   // start offset of signed area in main executable [zero] 
  70         virtual size_t signingLimit() = 0;                                              // size of signed area in main executable 
  71         virtual std::string 
format() = 0;                                               // human-readable type string 
  72         virtual CFArrayRef 
modifiedFiles();                                             // list of files modified by signing [main execcutable only] 
  73         virtual UnixPlusPlus::FileDesc 
&fd() = 0;                               // a cached file descriptor for main executable file 
  74         virtual void flush();                                                                   // flush caches (refetch as needed) 
  76         // default values for signing operations 
  77         virtual std::string 
recommendedIdentifier(const SigningContext 
&ctx
) = 0; // default identifier 
  78         virtual CFDictionaryRef 
defaultResourceRules(const SigningContext 
&ctx
); // default resource rules [none] 
  79         virtual const Requirements 
*defaultRequirements(const Architecture 
*arch
, 
  80                 const SigningContext 
&ctx
);                                                     // default internal requirements [none] 
  81         virtual size_t pageSize(const SigningContext 
&ctx
);             // default main executable page size [infinite, i.e. no paging] 
  83         virtual void strictValidate(const CodeDirectory
* cd
, const ToleratedErrors
& tolerated
); // perform strict validation 
  84         virtual CFArrayRef 
allowedResourceOmissions();                  // allowed (default) resource omission rules 
  86         bool mainExecutableIsMachO() { return mainExecutableImage() != NULL
; } 
  89         CFDataRef 
codeDirectory()       { return component(cdCodeDirectorySlot
); } 
  90         CFDataRef 
signature()           { return component(cdSignatureSlot
); } 
  94         virtual Writer 
*writer();                                                               // Writer factory 
  97         // optional information that might be used to create a suitable DiskRep. All optional 
  99                 Context() : arch(Architecture::none
), version(NULL
), offset(0), fileOnly(false), inMemory(NULL
), size(0) { } 
 100                 Architecture arch
;                      // explicit architecture (choose amongst universal variants) 
 101                 const char *version
;            // bundle version (string) 
 102                 off_t offset
;                           // explicit file offset 
 103                 bool fileOnly
;                          // only consider single-file representations (no bundles etc.) 
 104                 const void *inMemory
;           // consider using in-memory copy at this address 
 105                 size_t size
;                            // size of this mach-o slice 
 108         static DiskRep 
*bestGuess(const char *path
, const Context 
*ctx 
= NULL
); // canonical heuristic, any path 
 109         static DiskRep 
*bestFileGuess(const char *path
, const Context 
*ctx 
= NULL
); // ctx (if any) + fileOnly 
 110         static DiskRep 
*bestGuess(const char *path
, size_t archOffset
); // Mach-O at given file offset only 
 112         // versions using std::string paths (merely a convenience) 
 113         static DiskRep 
*bestGuess(const std::string 
&path
, const Context 
*ctx 
= NULL
) 
 114                 { return bestGuess(path
.c_str(), ctx
); } 
 115         static DiskRep 
*bestGuess(const std::string 
&path
, size_t archOffset
) { return bestGuess(path
.c_str(), archOffset
); } 
 116         static DiskRep 
*bestFileGuess(const std::string 
&path
, const Context 
*ctx 
= NULL
) { return bestFileGuess(path
.c_str(), ctx
); } 
 119         // see DiskRep::Writer docs for why this is here 
 120         class SigningContext 
{ 
 125                 virtual std::string 
sdkPath(const std::string 
&path
) const = 0; 
 126                 virtual bool isAdhoc() const = 0; 
 127                 virtual SecCSFlags 
signingFlags() const = 0; 
 131         // canonically derive a suggested signing identifier from some string 
 132         static std::string 
canonicalIdentifier(const std::string 
&name
); 
 135         static const size_t segmentedPageSize 
= 4096;   // default page size for system-paged signatures 
 136         static const size_t monolithicPageSize 
= 0;             // default page size for non-Mach-O executables 
 141 // Write-access objects. 
 142 // At this layer they are quite abstract, carrying just the functionality needed 
 143 // for the signing machinery to place data wherever it should go. Each DiskRep subclass 
 144 // that supports writing signing data to a place inside the code needs to implement 
 145 // a subclass of Writer and return an instance in the DiskRep::writer() method when asked. 
 147 // The Writer class is subclassed interestingly by the Mach-O multi-architecture signing code, 
 148 // which is handled as a special case. This means that not all Writer subclass objects were made 
 149 // by DiskRep::writer, and it is unwise to assume so. 
 151 // Note that the methods that provide defaults for signing operations are in DiskRep rather 
 152 // than here. That's because writers abstract data *sending*, and are virtual on management 
 153 // of stored data, while DiskRep is virtual on the existing code object, which is where 
 154 // we get our defaults from. 
 156 class DiskRep::Writer 
: public RefCount 
{ 
 158         Writer(uint32_t attrs 
= 0); 
 160         virtual void component(CodeDirectory::SpecialSlot slot
, CFDataRef data
) = 0; 
 161         virtual uint32_t attributes() const; 
 162         virtual void addDiscretionary(CodeDirectory::Builder 
&builder
); 
 163         virtual void remove(); 
 164         virtual void flush(); 
 166         bool attribute(uint32_t attr
) const             { return mAttributes 
& attr
; } 
 168         void signature(CFDataRef data
)                  { component(cdSignatureSlot
, data
); } 
 169         void codeDirectory(const CodeDirectory 
*cd
) 
 170                 { component(cdCodeDirectorySlot
, CFTempData(cd
->data(), cd
->length())); } 
 174         uint32_t mAttributes
; 
 178 // Writer attributes. Defaults should be off-bits. 
 181         writerLastResort 
= 0x0001,                      // prefers not to store attributes itself 
 182         writerNoGlobal 
= 0x0002,                        // has only per-architecture storage 
 187 // A prefix DiskRep that filters (only) signature-dependent behavior and passes 
 188 // all code-dependent behavior off to an underlying (different) DiskRep. 
 189 // FilterRep subclasses are typically "stacked" on top of their base DiskRep, and 
 190 // then used in their place. 
 192 class FilterRep 
: public DiskRep 
{ 
 194         FilterRep(DiskRep 
*orig
) : mOriginal(orig
) { } 
 196         DiskRep 
*base()                                                 { return mOriginal
; } 
 198         // things that look at signature components are filtered 
 199         CFDataRef 
component(CodeDirectory::SpecialSlot slot
) = 0; 
 201         // the rest of the virtual behavior devolves on the original DiskRep 
 202         CFDataRef 
identification()                              { return mOriginal
->identification(); } 
 203         std::string 
mainExecutablePath()                { return mOriginal
->mainExecutablePath(); } 
 204         CFURLRef 
copyCanonicalPath()                    { return mOriginal
->copyCanonicalPath(); } 
 205         std::string 
resourcesRootPath()                 { return mOriginal
->resourcesRootPath(); } 
 206         void adjustResources(ResourceBuilder 
&builder
) { return mOriginal
->adjustResources(builder
); } 
 207         Universal 
*mainExecutableImage()                { return mOriginal
->mainExecutableImage(); } 
 208         size_t signingBase()                                    { return mOriginal
->signingBase(); } 
 209         size_t signingLimit()                                   { return mOriginal
->signingLimit(); } 
 210         std::string 
format()                                    { return mOriginal
->format(); } 
 211         CFArrayRef 
modifiedFiles()                              { return mOriginal
->modifiedFiles(); } 
 212         UnixPlusPlus::FileDesc 
&fd()                    { return mOriginal
->fd(); } 
 213         void flush()                                                    { return mOriginal
->flush(); } 
 215         std::string 
recommendedIdentifier(const SigningContext 
&ctx
) 
 216                 { return mOriginal
->recommendedIdentifier(ctx
); } 
 217         CFDictionaryRef 
defaultResourceRules(const SigningContext 
&ctx
) 
 218                 { return mOriginal
->defaultResourceRules(ctx
); } 
 219         const Requirements 
*defaultRequirements(const Architecture 
*arch
, const SigningContext 
&ctx
) 
 220                 { return mOriginal
->defaultRequirements(arch
, ctx
); } 
 221         size_t pageSize(const SigningContext 
&ctx
) { return mOriginal
->pageSize(ctx
); } 
 223         void strictValidate(const CodeDirectory
* cd
, const ToleratedErrors
& tolerated
) { mOriginal
->strictValidate(cd
, tolerated
); } 
 224         CFArrayRef 
allowedResourceOmissions() { return mOriginal
->allowedResourceOmissions(); } 
 227         RefPointer
<DiskRep
> mOriginal
;                  // underlying representation 
 231 } // end namespace CodeSigning 
 232 } // end namespace Security 
 234 #endif // !_H_DISKREP