]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_codesigning/lib/slcrep.cpp
8a0ecbd4ed06d88edf034f2b31e4afb83a7df1e4
   2  * Copyright (c) 2009,2011-2012 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 // slcrep - DiskRep representing the Mac OS Shared Library Cache 
  31 namespace CodeSigning 
{ 
  33 using namespace UnixPlusPlus
; 
  38 // We open the file lazily, so nothing much happens on constructions. 
  39 // We can construct directly from a file path, or from an architecture 
  40 // (represented by Context), which will find the file in its usual 
  43 DYLDCacheRep::DYLDCacheRep(const char *path
) 
  44         : SingleDiskRep(path
), mCache(path
) 
  49 DYLDCacheRep::DYLDCacheRep(const Context 
*ctx
) 
  50         : SingleDiskRep(DYLDCache::pathFor(((ctx 
&& ctx
->arch
) ? ctx
->arch 
: Architecture::local()))), 
  56 void DYLDCacheRep::setup() 
  59         if (mCache
.totalSize() >= mCache
.mapSize() + sizeof(BlobCore
)) { 
  60                 const EmbeddedSignatureBlob 
*blob 
= mCache
.at
<const EmbeddedSignatureBlob
>((uint32_t)mCache
.mapSize()); 
  61                 if (mCache
.totalSize() >= mCache
.mapSize() + blob
->length())    // entire blob fits in file 
  64         CODESIGN_DISKREP_CREATE_SLC(this, (char*)this->mainExecutablePath().c_str()); 
  69 // Sniffer function for "plausible shared library cache file". 
  71 bool DYLDCacheRep::candidate(FileDesc 
&fd
) 
  73         return DYLDCache::validate(fd
); 
  78 // Default to system page size for segmented (paged) signatures 
  80 size_t DYLDCacheRep::pageSize(const SigningContext 
&) 
  82         return segmentedPageSize
; 
  87 // Signing limit is the start of the (trailing) signature 
  89 size_t DYLDCacheRep::signingLimit() 
  91         return mCache
.mapSize(); 
  96 // Retrieve a component from the executable. 
  97 // Our mCache has mapped the entire file, so we just fish the contents out of 
  98 // the mapped area as needed. 
 100 CFDataRef 
DYLDCacheRep::component(CodeDirectory::SpecialSlot slot
) 
 102         return mSigningData 
? mSigningData
->component(slot
) : NULL
; 
 107 // Provide a (vaguely) human readable characterization of this code 
 109 string 
DYLDCacheRep::format() 
 111         if (const char *name 
= mCache
.architecture().name()) { 
 113                 snprintf(result
, sizeof(result
), "OS X Shared Library Cache (%s @ 0x%llx)", 
 114                         name
, mCache
.baseAddress()); 
 117                 return "OS X Shared Library Cache (unknown type)"; 
 122 // DYLDCacheRep::Writers 
 124 DiskRep::Writer 
*DYLDCacheRep::writer() 
 126         return new Writer(this); 
 131 // Write a component. 
 133 void DYLDCacheRep::Writer::component(CodeDirectory::SpecialSlot slot
, CFDataRef data
) 
 135         EmbeddedSignatureBlob::Maker::component(slot
, data
); 
 140 // Append the superblob we built to the cache file. 
 142 void DYLDCacheRep::Writer::flush() 
 144         delete mSigningData
;                    // ditch previous blob just in case 
 145         mSigningData 
= Maker::make();   // assemble new signature SuperBlob 
 146         fd().seek(rep
->mCache
.mapSize()); // end of impage proper 
 147         fd().writeAll(*mSigningData
); 
 152 // The discretionary additions insert a Scatter vector describing the file's mapping table. 
 154 void DYLDCacheRep::Writer::addDiscretionary(CodeDirectory::Builder 
&builder
) 
 156         unsigned count 
= rep
->mCache
.mappingCount(); 
 157         builder
.scatter(count
); 
 158         for (unsigned n 
= 0; n 
< count
; n
++) { 
 159                 const DYLDCache::Mapping dmap 
= rep
->mCache
.mapping(n
); 
 160                 CodeDirectory::Scatter 
*scatter 
= builder
.scatter() + n
; 
 161                 scatter
->targetOffset 
= dmap
.address(); 
 162                 scatter
->base 
= (uint32_t)(dmap
.offset() / segmentedPageSize
); 
 163                 assert(dmap
.offset() % segmentedPageSize 
== 0); 
 164                 scatter
->count 
= (uint32_t)(dmap
.size() / segmentedPageSize
); 
 165                 assert(dmap
.size() % segmentedPageSize 
== 0); 
 170 } // end namespace CodeSigning 
 171 } // end namespace Security