]> git.saurik.com Git - apple/libsecurity_codesigning.git/blobdiff - lib/CodeSigner.cpp
libsecurity_codesigning-55004.tar.gz
[apple/libsecurity_codesigning.git] / lib / CodeSigner.cpp
index 6514c24e2e23a32816f1ccd79c97db00f1e78ae9..361d8fc342243ec21bfdf6a3834308316b2d7077 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -28,6 +28,7 @@
 #include "signer.h"
 #include "reqparser.h"
 #include "renum.h"
+#include "csdatabase.h"
 #include <security_utilities/unix++.h>
 #include <security_utilities/unixchild.h>
 #include <vector>
@@ -41,14 +42,6 @@ namespace CodeSigning {
 using namespace UnixPlusPlus;
 
 
-//
-// The allocation helper
-//
-static const char helperName[] = "codesign_allocate";
-static const char helperPath[] = "/usr/bin/codesign_allocate";
-static const size_t csAlign = 16;
-
-
 //
 // A helper for parsing out a CFDictionary signing-data specification
 //
@@ -69,10 +62,9 @@ public:
 //
 // Construct a SecCodeSigner
 //
-SecCodeSigner::SecCodeSigner()
-       : mRequirements(NULL)
+SecCodeSigner::SecCodeSigner(SecCSFlags flags)
+       : mOpFlags(flags), mRequirements(NULL), mDigestAlgorithm(kSecCodeSignatureDefaultDigestAlgorithm)
 {
-       secdebug("signer", "%p created", this);
 }
 
 
@@ -80,9 +72,10 @@ SecCodeSigner::SecCodeSigner()
 // Clean up a SecCodeSigner
 //
 SecCodeSigner::~SecCodeSigner() throw()
-{
-       secdebug("signer", "%p destroyed", this);
+try {
        ::free((Requirements *)mRequirements);
+} catch (...) {
+       return;
 }
 
 
@@ -91,22 +84,39 @@ SecCodeSigner::~SecCodeSigner() throw()
 //
 void SecCodeSigner::parameters(CFDictionaryRef paramDict)
 {
-       secdebug("signer", "%p loading %d parameters", this, int(CFDictionaryGetCount(paramDict)));
        Parser(*this, paramDict);
        if (!valid())
                MacOSError::throwMe(errSecCSInvalidObjectRef);
 }
 
 
+//
+// 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 (!valid())
-               MacOSError::throwMe(errSecCSInvalidObjectRef);
-       secdebug("signer", "%p will sign %p (flags 0x%x)", this, code, flags);
-       Signer(*this, code).sign(flags);
+       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();
 }
 
@@ -115,7 +125,7 @@ void SecCodeSigner::sign(SecStaticCode *code, SecCSFlags flags)
 // ReturnDetachedSignature is called by writers or editors that try to return
 // detached signature data (rather than annotate the target).
 //
-void SecCodeSigner::returnDetachedSignature(BlobCore *blob)
+void SecCodeSigner::returnDetachedSignature(BlobCore *blob, Signer &signer)
 {
        assert(mDetached);
        if (CFGetTypeID(mDetached) == CFURLGetTypeID()) {
@@ -125,11 +135,32 @@ void SecCodeSigner::returnDetachedSignature(BlobCore *blob)
        } else if (CFGetTypeID(mDetached) == CFDataGetTypeID()) {
                CFDataAppendBytes(CFMutableDataRef(mDetached.get()),
                        (const UInt8 *)blob, blob->length());
+       } else if (CFGetTypeID(mDetached) == CFNullGetTypeID()) {
+               signatureDatabaseWriter().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);
+}
+
+
 //
 // The actual parsing operation is done in the Parser class.
 //
@@ -145,8 +176,6 @@ SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters)
                        state.mSigner = SecIdentityRef(signer);
                else
                        MacOSError::throwMe(errSecCSInvalidObjectRef);
-       else
-               MacOSError::throwMe(errSecCSInvalidObjectRef);
 
        // the flags need some augmentation
        if (CFNumberRef flags = get<CFNumberRef>(kSecCodeSignerFlags)) {
@@ -154,6 +183,10 @@ SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters)
                state.mCdFlags = cfNumber<uint32_t>(flags);
        } else
                state.mCdFlagsGiven = false;
+       
+       // digest algorithms are specified as a numeric code
+       if (CFNumberRef digestAlgorithm = get<CFNumberRef>(kSecCodeSignerDigestAlgorithm))
+               state.mDigestAlgorithm = cfNumber<long>(digestAlgorithm);
 
        if (CFNumberRef cmsSize = get<CFNumberRef>(CFSTR("cmssize")))
                state.mCMSSize = cfNumber<size_t>(cmsSize);
@@ -191,8 +224,8 @@ SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters)
        
        // detached can be (destination) file URL or (mutable) Data to be appended-to
        if (state.mDetached = get<CFTypeRef>(kSecCodeSignerDetached)) {
-               if (CFGetTypeID(state.mDetached) != CFURLGetTypeID()
-                       && CFGetTypeID(state.mDetached) != CFDataGetTypeID())
+               CFTypeID type = CFGetTypeID(state.mDetached);
+               if (type != CFURLGetTypeID() && type != CFDataGetTypeID() && type != CFNullGetTypeID())
                        MacOSError::throwMe(errSecCSInvalidObjectRef);
        }
        
@@ -201,6 +234,9 @@ SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters)
        state.mResourceRules = get<CFDictionaryRef>(kSecCodeSignerResourceRules);
        
        state.mApplicationData = get<CFDataRef>(kSecCodeSignerApplicationData);
+       state.mEntitlementData = get<CFDataRef>(kSecCodeSignerEntitlements);
+       
+       state.mSDKRoot = get<CFURLRef>(kSecCodeSignerSDKRoot);
 }