/ OSX / libsecurity_codesigning / lib / detachedrep.cpp
detachedrep.cpp
  1  /*
  2   * Copyright (c) 2006-2008,2011-2012 Apple Inc. All Rights Reserved.
  3   * 
  4   * @APPLE_LICENSE_HEADER_START@
  5   * 
  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
 11   * file.
 12   * 
 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.
 20   * 
 21   * @APPLE_LICENSE_HEADER_END@
 22   */
 23  
 24  //
 25  // detachedrep - prefix diskrep representing a detached signature stored in a file
 26  //
 27  #include "detachedrep.h"
 28  
 29  
 30  namespace Security {
 31  namespace CodeSigning {
 32  
 33  
 34  //
 35  // We construct a DetachedRep from the data blob of the detached signature
 36  // and a reference of the original DiskRep we chain to.
 37  // We accept an EmbeddedSignatureBlob (for a non-architected signature)
 38  // or a DetachedSignatureBlob (for architected signatures) that is a SuperBlob
 39  // of EmbeddedSignatureBlobs.
 40  //
 41  DetachedRep::DetachedRep(CFDataRef sig, DiskRep *orig, const std::string &source)
 42  	: FilterRep(orig), mSig(sig), mFull(true), mSource(source)
 43  {
 44  	const BlobCore *sigBlob = reinterpret_cast<const BlobCore *>(CFDataGetBytePtr(sig));
 45  	if (sigBlob->is<EmbeddedSignatureBlob>()) {		// architecture-less
 46  		if ((mArch = EmbeddedSignatureBlob::specific(sigBlob))) {
 47  			mGlobal = NULL;
 48  			CODESIGN_DISKREP_CREATE_DETACHED(this, orig, (char*)source.c_str(), NULL);
 49  			return;
 50  		}
 51  	} else if (sigBlob->is<DetachedSignatureBlob>())	// architecture collection
 52  		if (const DetachedSignatureBlob *dsblob = DetachedSignatureBlob::specific(sigBlob))
 53  			if (Universal *fat = orig->mainExecutableImage())
 54  				if (const BlobCore *blob = dsblob->find(fat->bestNativeArch().cpuType()))
 55  					if ((mArch = EmbeddedSignatureBlob::specific(blob)))
 56  						if ((mGlobal = EmbeddedSignatureBlob::specific(dsblob->find(0)))) {
 57  							CODESIGN_DISKREP_CREATE_DETACHED(this, orig, (char*)source.c_str(), (void*)mGlobal);
 58  							return;
 59  						}
 60  	MacOSError::throwMe(errSecCSSignatureInvalid);
 61  }
 62  
 63  
 64  //
 65  // Here's a version to construct a DetachedRep if we already have the right architecture
 66  // and (optional) associated global blob. Just take them.
 67  //
 68  DetachedRep::DetachedRep(CFDataRef sig, CFDataRef gsig, DiskRep *orig, const std::string &source)
 69  	: FilterRep(orig), mSig(sig), mGSig(gsig), mFull(false), mSource(source)
 70  {
 71  	const BlobCore *sigBlob = reinterpret_cast<const BlobCore *>(CFDataGetBytePtr(sig));
 72  	mArch = EmbeddedSignatureBlob::specific(sigBlob);
 73  	if (!mArch)
 74  		MacOSError::throwMe(errSecCSSignatureInvalid);
 75  	if (gsig) {
 76  		const BlobCore *gsigBlob = reinterpret_cast<const BlobCore *>(CFDataGetBytePtr(gsig));
 77  		mGlobal = EmbeddedSignatureBlob::specific(gsigBlob);
 78  		if (!mGlobal)
 79  			MacOSError::throwMe(errSecCSSignatureInvalid);
 80  	} else
 81  		mGlobal = NULL;
 82  	CODESIGN_DISKREP_CREATE_DETACHED(this, orig, (char*)source.c_str(), (void*)mGlobal);
 83  }
 84  
 85  
 86  //
 87  // We look up components by first checking for a per-architecture item,
 88  // then for a global item in the detached signature, and finally falling
 89  // back on the original DiskRep (for static components).
 90  //
 91  CFDataRef DetachedRep::component(CodeDirectory::SpecialSlot slot)
 92  {
 93  	if (CFDataRef result = mArch->component(slot))
 94  		return result;
 95  	if (mGlobal)
 96  		if (CFDataRef result = mGlobal->component(slot))
 97  			return result;
 98  	return this->base()->component(slot);
 99  }
100  
101  
102  } // end namespace CodeSigning
103  } // end namespace Security