X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_codesigning/lib/signerutils.h diff --git a/Security/libsecurity_codesigning/lib/signerutils.h b/Security/libsecurity_codesigning/lib/signerutils.h new file mode 100644 index 00000000..906be1ea --- /dev/null +++ b/Security/libsecurity_codesigning/lib/signerutils.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2006-2012 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +// +// signerutils - utilities for signature generation +// +#ifndef _H_SIGNERUTILS +#define _H_SIGNERUTILS + +#include "CodeSigner.h" +#include "sigblob.h" +#include "cdbuilder.h" +#include +#include +#include +#include + +namespace Security { +namespace CodeSigning { + + +// +// A helper to deal with the magic merger logic of internal requirements +// +class InternalRequirements : public Requirements::Maker { +public: + InternalRequirements() : mReqs(NULL) { } + ~InternalRequirements() { ::free((void *)mReqs); } + void operator () (const Requirements *given, const Requirements *defaulted, const Requirement::Context &context); + operator const Requirements * () const { return mReqs; } + +private: + const Requirements *mReqs; +}; + + +// +// A DiskRep::Writer that assembles data in a SuperBlob (in memory) +// +class BlobWriter : public DiskRep::Writer, public EmbeddedSignatureBlob::Maker { +public: + void component(CodeDirectory::SpecialSlot slot, CFDataRef data); +}; + + +class DetachedBlobWriter : public BlobWriter { +public: + DetachedBlobWriter(SecCodeSigner::Signer &s) : signer(s) { } + + SecCodeSigner::Signer &signer; + + void flush(); +}; + + +// +// A multi-architecture editing assistant. +// ArchEditor collects (Mach-O) architectures in use, and maintains per-archtitecture +// data structures. It must be subclassed to express a particular way to handle the signing +// data. +// +class ArchEditor : public DiskRep::Writer { +public: + ArchEditor(Universal &fat, CodeDirectory::HashAlgorithm hashType, uint32_t attrs); + virtual ~ArchEditor(); + +public: + // + // One architecture's signing construction element. + // This also implements DispRep::Writer so generic writing code + // can work with both Mach-O and other files. + // + struct Arch : public BlobWriter { + Architecture architecture; // our architecture + auto_ptr source; // Mach-O object to be signed + CodeDirectory::Builder cdbuilder; // builder for CodeDirectory + InternalRequirements ireqs; // consolidated internal requirements + size_t blobSize; // calculated SuperBlob size + + Arch(const Architecture &arch, CodeDirectory::HashAlgorithm hashType) + : architecture(arch), cdbuilder(hashType) { } + }; + + // + // Our callers access the architectural universe through a map + // from Architectures to Arch objects. + // + typedef std::map ArchMap; + typedef ArchMap::iterator Iterator; + ArchMap::iterator begin() { return architecture.begin(); } + ArchMap::iterator end() { return architecture.end(); } + unsigned count() const { return (unsigned)architecture.size(); } + + // methods needed for an actual implementation + virtual void allocate() = 0; // interpass allocations + virtual void reset(Arch &arch) = 0; // pass 2 prep + virtual void write(Arch &arch, EmbeddedSignatureBlob *blob) = 0; // takes ownership of blob + virtual void commit() = 0; // write/flush result + +protected: + ArchMap architecture; +}; + + +// +// An ArchEditor that collects all architectures into a single SuperBlob, +// usually for writing a detached multi-architecture signature. +// +class BlobEditor : public ArchEditor { +public: + BlobEditor(Universal &fat, SecCodeSigner::Signer &s); + + SecCodeSigner::Signer &signer; + + void component(CodeDirectory::SpecialSlot slot, CFDataRef data); + void allocate() { } + void reset(Arch &arch) { } + void write(Arch &arch, EmbeddedSignatureBlob *blob); + void commit(); + +private: + DetachedSignatureBlob::Maker mMaker; + EmbeddedSignatureBlob::Maker mGlobal; +}; + + +// +// An ArchEditor that writes its signatures into a (fat) binary file. +// We do this by forking a helper tool (codesign_allocate) and asking +// it to make a copy with suitable space "opened up" in the right spots. +// +class MachOEditor : public ArchEditor, private UnixPlusPlus::Child { +public: + MachOEditor(DiskRep::Writer *w, Universal &code, CodeDirectory::HashAlgorithm hashType, std::string srcPath); + ~MachOEditor(); + + const RefPointer writer; + const std::string sourcePath; + const std::string tempPath; + + void component(CodeDirectory::SpecialSlot slot, CFDataRef data); + void allocate(); + void reset(Arch &arch); + void write(Arch &arch, EmbeddedSignatureBlob *blob); + void commit(); + +private: + // fork operation + void childAction(); + void parentAction(); + + // controlling the temporary file copy + Universal *mNewCode; + UnixPlusPlus::AutoFileDesc mFd; + bool mTempMayExist; + + // finding and managing the helper tool + const char *mHelperPath; + bool mHelperOverridden; +}; + + +// +// A Requirement::Context populated from a signing request. +// We use this to help generate the explicit Designated Requirement +// during signing ops, and thus this must be constructed BEFORE we +// actually have a signed object. +// +class PreSigningContext : public Requirement::Context { +public: + PreSigningContext(const SecCodeSigner::Signer &signer); + +private: + CFRef mCerts; // hold cert chain +}; + + +} // end namespace CodeSigning +} // end namespace Security + +#endif // !_H_SIGNERUTILS