]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_codesigning/lib/diskrep.h
   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
; 
  48 // DiskRep is an abstract interface to code somewhere located by 
  49 // a file system path. It presents the ability to read and write 
  50 // Code Signing-related information about such code without exposing 
  51 // the details of the storage locations or formats. 
  53 class DiskRep 
: public RefCount 
{ 
  57         typedef std::set
<OSStatus
> ToleratedErrors
; 
  62         virtual DiskRep 
*base(); 
  63         virtual CFDataRef 
component(CodeDirectory::SpecialSlot slot
) = 0; // fetch component 
  64         virtual CFDataRef 
identification() = 0;                                 // binary lookup identifier 
  65         virtual std::string 
mainExecutablePath() = 0;                   // path to main executable 
  66         virtual CFURLRef 
copyCanonicalPath() = 0;                                       // path to whole code 
  67         virtual std::string 
resourcesRootPath();                                // resource directory if any [none] 
  68         virtual void adjustResources(ResourceBuilder 
&builder
); // adjust resource rule set [no change] 
  69         virtual void prepareForSigning(SigningContext
& context
); // pre-adjust signing defaults before argument preparation [none] 
  70         virtual Universal 
*mainExecutableImage();                               // Mach-O image if Mach-O based [null] 
  71         virtual size_t signingBase();                                                   // start offset of signed area in main executable [zero] 
  72         virtual size_t signingLimit() = 0;                                              // size of signed area in main executable 
  73         virtual std::string 
format() = 0;                                               // human-readable type string 
  74         virtual CFArrayRef 
modifiedFiles();                                             // list of files modified by signing [main execcutable only] 
  75         virtual UnixPlusPlus::FileDesc 
&fd() = 0;                               // a cached file descriptor for main executable file 
  76         virtual void flush();                                                                   // flush caches (refetch as needed) 
  77     virtual CFDictionaryRef 
diskRepInformation();           // information from diskrep 
  79         // default values for signing operations 
  80         virtual std::string 
recommendedIdentifier(const SigningContext 
&ctx
) = 0; // default identifier 
  81         virtual CFDictionaryRef 
defaultResourceRules(const SigningContext 
&ctx
); // default resource rules [none] 
  82         virtual const Requirements 
*defaultRequirements(const Architecture 
*arch
, 
  83                 const SigningContext 
&ctx
);                                                     // default internal requirements [none] 
  84         virtual size_t pageSize(const SigningContext 
&ctx
);             // default main executable page size [infinite, i.e. no paging] 
  86         virtual void strictValidate(const CodeDirectory
* cd
, const ToleratedErrors
& tolerated
, SecCSFlags flags
); // perform strict validation 
  87         virtual CFArrayRef 
allowedResourceOmissions();                  // allowed (default) resource omission rules 
  89         bool mainExecutableIsMachO() { return mainExecutableImage() != NULL
; } 
  92         CFDataRef 
signature()           { return component(cdSignatureSlot
); } 
  96         virtual Writer 
*writer();                                                               // Writer factory 
  99         // optional information that might be used to create a suitable DiskRep. All optional 
 101                 Context() : arch(Architecture::none
), version(NULL
), offset(0), fileOnly(false), inMemory(NULL
), size(0) { } 
 102                 Architecture arch
;                      // explicit architecture (choose amongst universal variants) 
 103                 const char *version
;            // bundle version (string) 
 104                 off_t offset
;                           // explicit file offset 
 105                 bool fileOnly
;                          // only consider single-file representations (no bundles etc.) 
 106                 const void *inMemory
;           // consider using in-memory copy at this address 
 107                 size_t size
;                            // size of this mach-o slice 
 110         static DiskRep 
*bestGuess(const char *path
, const Context 
*ctx 
= NULL
); // canonical heuristic, any path 
 111         static DiskRep 
*bestFileGuess(const char *path
, const Context 
*ctx 
= NULL
); // ctx (if any) + fileOnly 
 112         static DiskRep 
*bestGuess(const char *path
, size_t archOffset
); // Mach-O at given file offset only 
 114         // versions using std::string paths (merely a convenience) 
 115         static DiskRep 
*bestGuess(const std::string 
&path
, const Context 
*ctx 
= NULL
) 
 116                 { return bestGuess(path
.c_str(), ctx
); } 
 117         static DiskRep 
*bestGuess(const std::string 
&path
, size_t archOffset
) { return bestGuess(path
.c_str(), archOffset
); } 
 118         static DiskRep 
*bestFileGuess(const std::string 
&path
, const Context 
*ctx 
= NULL
) { return bestFileGuess(path
.c_str(), ctx
); } 
 121         // see DiskRep::Writer docs for why this is here 
 122         class SigningContext 
{ 
 127                 virtual std::string 
sdkPath(const std::string 
&path
) const = 0; 
 128                 virtual bool isAdhoc() const = 0; 
 129                 virtual SecCSFlags 
signingFlags() const = 0; 
 131                 virtual const CodeDirectory::HashAlgorithms 
&digestAlgorithms() const = 0; 
 132                 virtual void setDigestAlgorithms(CodeDirectory::HashAlgorithms types
) = 0; 
 134                 void setDigestAlgorithm(CodeDirectory::HashAlgorithm type
) 
 136                         CodeDirectory::HashAlgorithms types
; 
 138                         setDigestAlgorithms(types
); 
 143         // canonically derive a suggested signing identifier from some string 
 144         static std::string 
canonicalIdentifier(const std::string 
&name
); 
 147         static const size_t segmentedPageSize 
= 4096;   // default page size for system-paged signatures 
 148         static const size_t monolithicPageSize 
= 0;             // default page size for non-Mach-O executables 
 153 // Write-access objects. 
 154 // At this layer they are quite abstract, carrying just the functionality needed 
 155 // for the signing machinery to place data wherever it should go. Each DiskRep subclass 
 156 // that supports writing signing data to a place inside the code needs to implement 
 157 // a subclass of Writer and return an instance in the DiskRep::writer() method when asked. 
 159 // The Writer class is subclassed interestingly by the Mach-O multi-architecture signing code, 
 160 // which is handled as a special case. This means that not all Writer subclass objects were made 
 161 // by DiskRep::writer, and it is unwise to assume so. 
 163 // Note that the methods that provide defaults for signing operations are in DiskRep rather 
 164 // than here. That's because writers abstract data *sending*, and are virtual on management 
 165 // of stored data, while DiskRep is virtual on the existing code object, which is where 
 166 // we get our defaults from. 
 168 class DiskRep::Writer 
: public RefCount 
{ 
 170         Writer(uint32_t attrs 
= 0); 
 172         virtual void component(CodeDirectory::SpecialSlot slot
, CFDataRef data
) = 0; 
 173         virtual uint32_t attributes() const; 
 174         virtual void addDiscretionary(CodeDirectory::Builder 
&builder
); 
 175         virtual void remove(); 
 176         virtual void flush(); 
 178         bool attribute(uint32_t attr
) const             { return mAttributes 
& attr
; } 
 180         void signature(CFDataRef data
)                  { component(cdSignatureSlot
, data
); } 
 181         void codeDirectory(const CodeDirectory 
*cd
, CodeDirectory::SpecialSlot slot
) 
 182                 { component(slot
, CFTempData(cd
->data(), cd
->length())); } 
 186         uint32_t mAttributes
; 
 190 // Writer attributes. Defaults should be off-bits. 
 193         writerLastResort 
= 0x0001,                      // prefers not to store attributes itself 
 194         writerNoGlobal 
= 0x0002,                        // has only per-architecture storage 
 199 // A prefix DiskRep that filters (only) signature-dependent behavior and passes 
 200 // all code-dependent behavior off to an underlying (different) DiskRep. 
 201 // FilterRep subclasses are typically "stacked" on top of their base DiskRep, and 
 202 // then used in their place. 
 204 class FilterRep 
: public DiskRep 
{ 
 206         FilterRep(DiskRep 
*orig
) : mOriginal(orig
) { } 
 208         DiskRep 
*base()                                                 { return mOriginal
; } 
 210         // things that look at signature components are filtered 
 211         CFDataRef 
component(CodeDirectory::SpecialSlot slot
) = 0; 
 213         // the rest of the virtual behavior devolves on the original DiskRep 
 214         CFDataRef 
identification()                              { return mOriginal
->identification(); } 
 215         std::string 
mainExecutablePath()                { return mOriginal
->mainExecutablePath(); } 
 216         CFURLRef 
copyCanonicalPath()                    { return mOriginal
->copyCanonicalPath(); } 
 217         std::string 
resourcesRootPath()                 { return mOriginal
->resourcesRootPath(); } 
 218         void adjustResources(ResourceBuilder 
&builder
) { return mOriginal
->adjustResources(builder
); } 
 219         Universal 
*mainExecutableImage()                { return mOriginal
->mainExecutableImage(); } 
 220         size_t signingBase()                                    { return mOriginal
->signingBase(); } 
 221         size_t signingLimit()                                   { return mOriginal
->signingLimit(); } 
 222         std::string 
format()                                    { return mOriginal
->format(); } 
 223         CFArrayRef 
modifiedFiles()                              { return mOriginal
->modifiedFiles(); } 
 224         UnixPlusPlus::FileDesc 
&fd()                    { return mOriginal
->fd(); } 
 225         void flush()                                                    { return mOriginal
->flush(); } 
 227         std::string 
recommendedIdentifier(const SigningContext 
&ctx
) 
 228                 { return mOriginal
->recommendedIdentifier(ctx
); } 
 229         CFDictionaryRef 
defaultResourceRules(const SigningContext 
&ctx
) 
 230                 { return mOriginal
->defaultResourceRules(ctx
); } 
 231         const Requirements 
*defaultRequirements(const Architecture 
*arch
, const SigningContext 
&ctx
) 
 232                 { return mOriginal
->defaultRequirements(arch
, ctx
); } 
 233         size_t pageSize(const SigningContext 
&ctx
) { return mOriginal
->pageSize(ctx
); } 
 235         void strictValidate(const CodeDirectory
* cd
, const ToleratedErrors
& tolerated
, SecCSFlags flags
) { mOriginal
->strictValidate(cd
, tolerated
, flags
); } 
 236         CFArrayRef 
allowedResourceOmissions() { return mOriginal
->allowedResourceOmissions(); } 
 239         RefPointer
<DiskRep
> mOriginal
;                  // underlying representation 
 243 } // end namespace CodeSigning 
 244 } // end namespace Security 
 246 #endif // !_H_DISKREP