X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/72a12576750f52947eb043106ba5c12c0d07decf..b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195:/libsecurity_codesigning/lib/reqmaker.cpp diff --git a/libsecurity_codesigning/lib/reqmaker.cpp b/libsecurity_codesigning/lib/reqmaker.cpp new file mode 100644 index 00000000..31642a94 --- /dev/null +++ b/libsecurity_codesigning/lib/reqmaker.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2006 Apple Computer, 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@ + */ + +// +// reqmaker - Requirement assembler +// +#include "reqmaker.h" + +namespace Security { +namespace CodeSigning { + + +// +// Requirement::Makers +// +Requirement::Maker::Maker(Kind k) + : mSize(1024) +{ + mBuffer = (Requirement *)malloc(mSize); + mBuffer->initialize(); + mBuffer->kind(k); + mPC = sizeof(Requirement); +} + +// need at least (size) bytes in the creation buffer +void Requirement::Maker::require(size_t size) +{ + if (mPC + size > mSize) { + mSize *= 2; + if (mPC + size > mSize) + mSize = mPC + size; + if (!(mBuffer = (Requirement *)realloc(mBuffer, mSize))) + UnixError::throwMe(ENOMEM); + } +} + +// allocate (size) bytes at end of buffer and return pointer to that +void *Requirement::Maker::alloc(size_t size) +{ + // round size up to preserve alignment + size_t usedSize = LowLevelMemoryUtilities::alignUp(size, baseAlignment); + require(usedSize); + void *data = mBuffer->at(mPC); + mPC += usedSize; + + // clear any padding (avoid random bytes in code image) + const uint32_t zero = 0; + memcpy(mBuffer->at(mPC - usedSize + size), &zero, usedSize - size); + + // all done + return data; +} + +// put contiguous data blob +void Requirement::Maker::putData(const void *data, size_t length) +{ + put(uint32_t(length)); + memcpy(alloc(length), data, length); +} + +// Specialized Maker put operations +void Requirement::Maker::anchor() +{ + put(opAppleAnchor); +} + +void Requirement::Maker::anchorGeneric() +{ + put(opAppleGenericAnchor); +} + +void Requirement::Maker::anchor(int slot, SHA1::Digest digest) +{ + put(opAnchorHash); + put(slot); + putData(digest, SHA1::digestLength); +} + +void Requirement::Maker::anchor(int slot, const void *cert, size_t length) +{ + SHA1 hasher; + hasher(cert, length); + SHA1::Digest digest; + hasher.finish(digest); + anchor(slot, digest); +} + +void Requirement::Maker::trustedAnchor() +{ + put(opTrustedCerts); +} + +void Requirement::Maker::trustedAnchor(int slot) +{ + put(opTrustedCert); + put(slot); +} + +void Requirement::Maker::infoKey(const string &key, const string &value) +{ + put(opInfoKeyValue); + put(key); + put(value); +} + +void Requirement::Maker::ident(const string &identifier) +{ + put(opIdent); + put(identifier); +} + +void Requirement::Maker::cdhash(SHA1::Digest digest) +{ + put(opCDHash); + putData(digest, SHA1::digestLength); +} + + + +void Requirement::Maker::copy(const Requirement *req) +{ + assert(req); + if (req->kind() != exprForm) // don't know how to embed this + MacOSError::throwMe(errSecCSReqUnsupported); + this->copy(req->at(sizeof(Requirement)), req->length() - sizeof(Requirement)); +} + + +void *Requirement::Maker::insert(const Label &label, size_t length) +{ + require(length); + memmove(mBuffer->at(label.pos + length), + mBuffer->at(label.pos), mPC - label.pos); + mPC += length; + return mBuffer->at(label.pos); +} + + +Requirement *Requirement::Maker::make() +{ + mBuffer->length(mPC); + Requirement *result = mBuffer; + mBuffer = NULL; + return result; +} + + +} // CodeSigning +} // Security