]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cdsa_utilities/lib/osxverifier.cpp
6075df06e41618c18e82b466a650e5c2a1998b9d
   2  * Copyright (c) 2000-2001,2011,2013-2014 Apple Inc. All Rights Reserved. 
   4  * The contents of this file constitute Original Code as defined in and are 
   5  * subject to the Apple Public Source License Version 1.2 (the 'License'). 
   6  * You may not use this file except in compliance with the License. Please obtain 
   7  * a copy of the License at http://www.apple.com/publicsource and read it before 
  10  * This Original Code and all software distributed under the License are 
  11  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 
  12  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 
  13  * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
  14  * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 
  15  * specific language governing rights and limitations under the License. 
  20 // osxsigner - MacOS X's standard code signing algorithm. 
  22 #include <security_cdsa_utilities/osxverifier.h> 
  23 #include <security_utilities/unix++.h> 
  24 #include <security_utilities/hashing.h> 
  25 #include <security_utilities/memutils.h> 
  26 #include <security_utilities/debugging.h> 
  27 #include <security_codesigning/requirement.h> 
  28 #include <security_codesigning/reqdumper.h>             // debug only 
  31 using namespace CodeSigning
; 
  38 // Create a Verifier from a code object. 
  40 // This does not add any auxiliary information blobs. You can do that 
  41 // by calling add() after construction, of course. 
  43 OSXVerifier::OSXVerifier(OSXCode 
*code
) 
  45         mPath 
= code
->canonicalPath(); 
  46         secinfo("codesign", "building verifier for %s", mPath
.c_str()); 
  48         // build new-style verifier 
  49         CFRef
<SecStaticCodeRef
> staticCode 
= code
->codeRef(); 
  50         switch (OSStatus rc 
= SecCodeCopyDesignatedRequirement(staticCode
, 
  51                         kSecCSDefaultFlags
, &mRequirement
.aref())) { 
  53                 secinfo("codesign", "  is signed; canonical requirement loaded"); 
  55         case errSecCSUnsigned
: 
  56                 secinfo("codesign", "  is unsigned; no requirement"); 
  59                 MacOSError::throwMe(rc
); 
  62         // build old-style verifier 
  63         makeLegacyHash(code
, mLegacyHash
); 
  64         secinfo("codesign", "  hash generated"); 
  69 // Create a Verifier from hash, path, and requirement. 
  70 // Again, this has no auxiliary data when constructed. 
  72 OSXVerifier::OSXVerifier(const SHA1::Byte 
*hash
, const std::string 
&path
) 
  75         secinfo("codesign", "building verifier from hash %p and path=%s", hash
, path
.c_str()); 
  77                 memcpy(mLegacyHash
, hash
, sizeof(mLegacyHash
)); 
  79                 memset(mLegacyHash
, 0, sizeof(mLegacyHash
)); 
  83 OSXVerifier::~OSXVerifier() 
  85         secinfo("codesign", "%p verifier destroyed", this); 
  90 // Add an auxiliary comment blob. 
  91 // Note that we only allow one auxiliary blob for each magic number. 
  93 void OSXVerifier::add(const BlobCore 
*blob
) 
  95         if (blob
->is
<Requirement
>()) { 
  97                 secinfo("codesign", "%p verifier adds requirement", this); 
  99                 secinfo("codesign", "%p verifier adds requirement %s", this, 
 100                         Dumper::dump(Requirement::specific(blob
), true).c_str()); 
 102                 MacOSError::check(SecRequirementCreateWithData(CFTempData(*blob
), 
 103                         kSecCSDefaultFlags
, &mRequirement
.aref())); 
 105                 secinfo("codesign", "%p verifier adds blob (0x%x,%zd)", 
 106                         this, blob
->magic(), blob
->length()); 
 107                 BlobCore 
* &slot 
= mAuxiliary
[blob
->magic()]; 
 110                 slot 
= blob
->clone(); 
 116 // Find a comment blob, by magic number 
 118 const BlobCore 
*OSXVerifier::find(BlobCore::Magic magic
) 
 120         AuxMap::const_iterator it 
= mAuxiliary
.find(magic
); 
 121         return (it 
== mAuxiliary
.end()) ? NULL 
: it
->second
; 
 125 void OSXVerifier::makeLegacyHash(OSXCode 
*code
, SHA1::Digest digest
) 
 127         secinfo("codesign", "calculating legacy hash for %s", code
->canonicalPath().c_str()); 
 128         UnixPlusPlus::AutoFileDesc 
fd(code
->executablePath(), O_RDONLY
); 
 129         char buffer
[legacyHashLimit
]; 
 130         size_t size 
= fd
.read(buffer
, legacyHashLimit
); 
 138 // The AuxMap helper class provides a map-to-Blob-pointers with automatic memory management. 
 140 OSXVerifier::AuxMap::AuxMap(const OSXVerifier::AuxMap 
&src
) 
 142         for (const_iterator it 
= src
.begin(); it 
!= src
.end(); it
++) 
 146 OSXVerifier::AuxMap::~AuxMap() 
 148         for (const_iterator it 
= this->begin(); it 
!= this->end(); ++it
) 
 155 void OSXVerifier::dump() const 
 157         static const SHA1::Digest nullDigest 
= { 0 }; 
 158         if (!memcmp(mLegacyHash
, nullDigest
, sizeof(mLegacyHash
))) { 
 159                 Debug::dump("(no hash)"); 
 161                 Debug::dump("oldHash="); 
 162                 Debug::dumpData(mLegacyHash
, sizeof(mLegacyHash
)); 
 165                 CFRef
<CFDataRef
> reqData
; 
 166                 if (!SecRequirementCopyData(mRequirement
, 0, &reqData
.aref())) { 
 167                         Debug::dump(" Requirement =>"); 
 168                         ((const Requirement 
*)CFDataGetBytePtr(reqData
))->dump(); 
 171                 Debug::dump(" NO REQ"); 
 177 } // end namespace Security