X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_codesigning/lib/CodeSigner.cpp diff --git a/libsecurity_codesigning/lib/CodeSigner.cpp b/libsecurity_codesigning/lib/CodeSigner.cpp deleted file mode 100644 index 004fb125..00000000 --- a/libsecurity_codesigning/lib/CodeSigner.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2006-2010 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@ - */ - -// -// CodeSigner - SecCodeSigner API objects -// -#include "CodeSigner.h" -#include "signer.h" -#include "csdatabase.h" -#include "drmaker.h" -#include "csutilities.h" -#include -#include -#include -#include -#include - -namespace Security { - -__SEC_CFTYPE(SecIdentity) - -namespace CodeSigning { - -using namespace UnixPlusPlus; - - -// -// A helper for parsing out a CFDictionary signing-data specification -// -class SecCodeSigner::Parser : CFDictionary { -public: - Parser(SecCodeSigner &signer, CFDictionaryRef parameters); - - bool getBool(CFStringRef key) const - { - if (CFBooleanRef flag = get(key)) - return flag == kCFBooleanTrue; - else - return false; - } -}; - - -// -// Construct a SecCodeSigner -// -SecCodeSigner::SecCodeSigner(SecCSFlags flags) - : mOpFlags(flags), mDigestAlgorithm(kSecCodeSignatureDefaultDigestAlgorithm) -{ -} - - -// -// Clean up a SecCodeSigner -// -SecCodeSigner::~SecCodeSigner() throw() -try { -} catch (...) { - return; -} - - -// -// Parse an input parameter dictionary and set ready-to-use parameters -// -void SecCodeSigner::parameters(CFDictionaryRef paramDict) -{ - Parser(*this, paramDict); - if (!valid()) - MacOSError::throwMe(errSecCSInvalidObjectRef); -} - -// -// Retrieve the team ID from the signing certificate if and only if -// it is an apple developer signing cert -// -std::string SecCodeSigner::getTeamIDFromSigner(CFArrayRef certs) -{ - if (mSigner && mSigner != SecIdentityRef(kCFNull)) { - CFRef signerCert; - MacOSError::check(SecIdentityCopyCertificate(mSigner, &signerCert.aref())); - - /* Make sure the certificate looks like an Apple certificate, because we do not - extract the team ID from a non Apple certificate */ - if (SecStaticCode::isAppleDeveloperCert(certs)) { - CFRef teamIDFromCert; - - MacOSError::check(SecCertificateCopySubjectComponent(signerCert.get(), &CSSMOID_OrganizationalUnitName, &teamIDFromCert.aref())); - - if (teamIDFromCert) - return cfString(teamIDFromCert); - } - } - - return ""; -} - -// -// Roughly check for validity. -// This isn't thorough; it just sees if if looks like we've set up the object appropriately. -// -bool SecCodeSigner::valid() const -{ - if (mOpFlags & kSecCSRemoveSignature) - return true; - return mSigner; -} - - -// -// Sign code -// -void SecCodeSigner::sign(SecStaticCode *code, SecCSFlags flags) -{ - if (code->isSigned() && (flags & kSecCSSignPreserveSignature)) - return; - Signer operation(*this, code); - if ((flags | mOpFlags) & kSecCSRemoveSignature) { - secdebug("signer", "%p will remove signature from %p", this, code); - operation.remove(flags); - } else { - if (!valid()) - MacOSError::throwMe(errSecCSInvalidObjectRef); - secdebug("signer", "%p will sign %p (flags 0x%x)", this, code, flags); - operation.sign(flags); - } - code->resetValidity(); -} - - -// -// ReturnDetachedSignature is called by writers or editors that try to return -// detached signature data (rather than annotate the target). -// -void SecCodeSigner::returnDetachedSignature(BlobCore *blob, Signer &signer) -{ - assert(mDetached); - if (CFGetTypeID(mDetached) == CFURLGetTypeID()) { - // URL to destination file - AutoFileDesc fd(cfString(CFURLRef(mDetached.get())), O_WRONLY | O_CREAT | O_TRUNC); - fd.writeAll(*blob); - } else if (CFGetTypeID(mDetached) == CFDataGetTypeID()) { - CFDataAppendBytes(CFMutableDataRef(mDetached.get()), - (const UInt8 *)blob, blob->length()); - } else if (CFGetTypeID(mDetached) == CFNullGetTypeID()) { - SignatureDatabaseWriter db; - db.storeCode(blob, signer.path().c_str()); - } else - assert(false); -} - - -// -// Our DiskRep::signingContext methods communicate with the signing subsystem -// in terms those callers can easily understand. -// -string SecCodeSigner::sdkPath(const std::string &path) const -{ - assert(path[0] == '/'); // need absolute path here - if (mSDKRoot) - return cfString(mSDKRoot) + path; - else - return path; -} - -bool SecCodeSigner::isAdhoc() const -{ - return mSigner == SecIdentityRef(kCFNull); -} - -SecCSFlags SecCodeSigner::signingFlags() const -{ - return mOpFlags; -} - - -// -// The actual parsing operation is done in the Parser class. -// -// Note that we need to copy or retain all incoming data. The caller has no requirement -// to keep the parameters dictionary around. -// -SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters) - : CFDictionary(parameters, errSecCSBadDictionaryFormat) -{ - // the signer may be an identity or null - state.mSigner = SecIdentityRef(get(kSecCodeSignerIdentity)); - if (state.mSigner) - if (CFGetTypeID(state.mSigner) != SecIdentityGetTypeID() && !CFEqual(state.mSigner, kCFNull)) - MacOSError::throwMe(errSecCSInvalidObjectRef); - - // the flags need some augmentation - if (CFNumberRef flags = get(kSecCodeSignerFlags)) { - state.mCdFlagsGiven = true; - state.mCdFlags = cfNumber(flags); - } else - state.mCdFlagsGiven = false; - - // digest algorithms are specified as a numeric code - if (CFNumberRef digestAlgorithm = get(kSecCodeSignerDigestAlgorithm)) - state.mDigestAlgorithm = cfNumber(digestAlgorithm); - - if (CFNumberRef cmsSize = get(CFSTR("cmssize"))) - state.mCMSSize = cfNumber(cmsSize); - else - state.mCMSSize = 9000; // likely big enough - - // metadata preservation options - if (CFNumberRef preserve = get(kSecCodeSignerPreserveMetadata)) { - state.mPreserveMetadata = cfNumber(preserve); - } else - state.mPreserveMetadata = 0; - - - // signing time can be a CFDateRef or null - if (CFTypeRef time = get(kSecCodeSignerSigningTime)) { - if (CFGetTypeID(time) == CFDateGetTypeID() || time == kCFNull) - state.mSigningTime = CFDateRef(time); - else - MacOSError::throwMe(errSecCSInvalidObjectRef); - } - - if (CFStringRef ident = get(kSecCodeSignerIdentifier)) - state.mIdentifier = cfString(ident); - - if (CFStringRef teamid = get(kSecCodeSignerTeamIdentifier)) - state.mTeamID = cfString(teamid); - - if (CFStringRef prefix = get(kSecCodeSignerIdentifierPrefix)) - state.mIdentifierPrefix = cfString(prefix); - - // Requirements can be binary or string (to be compiled). - // We must pass them along to the signer for possible text substitution - if (CFTypeRef reqs = get(kSecCodeSignerRequirements)) { - if (CFGetTypeID(reqs) == CFDataGetTypeID() || CFGetTypeID(reqs) == CFStringGetTypeID()) - state.mRequirements = reqs; - else - MacOSError::throwMe(errSecCSInvalidObjectRef); - } else - state.mRequirements = NULL; - - state.mNoMachO = getBool(CFSTR("no-macho")); - - state.mPageSize = get(kSecCodeSignerPageSize); - - // detached can be (destination) file URL or (mutable) Data to be appended-to - if ((state.mDetached = get(kSecCodeSignerDetached))) { - CFTypeID type = CFGetTypeID(state.mDetached); - if (type != CFURLGetTypeID() && type != CFDataGetTypeID() && type != CFNullGetTypeID()) - MacOSError::throwMe(errSecCSInvalidObjectRef); - } - - state.mDryRun = getBool(kSecCodeSignerDryRun); - - state.mResourceRules = get(kSecCodeSignerResourceRules); - - state.mApplicationData = get(kSecCodeSignerApplicationData); - state.mEntitlementData = get(kSecCodeSignerEntitlements); - - state.mSDKRoot = get(kSecCodeSignerSDKRoot); - - if (CFBooleanRef timestampRequest = get(kSecCodeSignerRequireTimestamp)) { - state.mWantTimeStamp = timestampRequest == kCFBooleanTrue; - } else { // pick default - state.mWantTimeStamp = false; - if (state.mSigner && state.mSigner != SecIdentityRef(kCFNull)) { - CFRef signerCert; - MacOSError::check(SecIdentityCopyCertificate(state.mSigner, &signerCert.aref())); - if (certificateHasField(signerCert, devIdLeafMarkerOID)) - state.mWantTimeStamp = true; - } - } - state.mTimestampAuthentication = get(kSecCodeSignerTimestampAuthentication); - state.mTimestampService = get(kSecCodeSignerTimestampServer); - state.mNoTimeStampCerts = getBool(kSecCodeSignerTimestampOmitCertificates); -} - - -} // end namespace CodeSigning -} // end namespace Security