]> git.saurik.com Git - apple/libsecurity_codesigning.git/commitdiff
libsecurity_codesigning-32953.tar.gz mac-os-x-1052 v32953
authorApple <opensource@apple.com>
Tue, 15 Jan 2008 22:13:59 +0000 (22:13 +0000)
committerApple <opensource@apple.com>
Tue, 15 Jan 2008 22:13:59 +0000 (22:13 +0000)
lib/CodeSigner.cpp
lib/macho++.cpp
lib/reqinterp.cpp
lib/reqinterp.h
lib/signerutils.cpp
lib/signerutils.h
libsecurity_codesigning.xcodeproj/project.pbxproj

index 6514c24e2e23a32816f1ccd79c97db00f1e78ae9..da3628499b48d5ef2ffe5238ebc4d655939ba45a 100644 (file)
@@ -41,14 +41,6 @@ namespace CodeSigning {
 using namespace UnixPlusPlus;
 
 
 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
 //
 //
 // A helper for parsing out a CFDictionary signing-data specification
 //
index 9c5572b8480a5c506e0f7f060ab0d61d76e74c22..11eb33b669f3a8c502edde2bc9fa857f164caf97 100644 (file)
@@ -62,7 +62,12 @@ const char *Architecture::name() const
 {
        if (const NXArchInfo *info = NXGetArchInfoFromCpuType(cpuType(), cpuSubtype()))
                return info->name;
 {
        if (const NXArchInfo *info = NXGetArchInfoFromCpuType(cpuType(), cpuSubtype()))
                return info->name;
-       else
+       else if (cpuType() == CPU_TYPE_ARM)      {      // work-around for non-ARM Leopard systems
+               if (cpuSubtype() == CPU_SUBTYPE_ARM_V6)
+                       return "armv6";
+               else
+                       return "arm";
+       } else
                return NULL;
 }
 
                return NULL;
 }
 
index 0c20659268b5f29a08ec63f2076d0450d9848558..b661b178ba9910af053f99be03cb020354236f10 100644 (file)
@@ -35,6 +35,10 @@ namespace Security {
 namespace CodeSigning {
 
 
 namespace CodeSigning {
 
 
+static CFStringRef appleIntermediateCN = CFSTR("Apple Code Signing Certification Authority");
+static CFStringRef appleIntermediateO = CFSTR("Apple Inc.");
+
+
 //
 // Construct an interpreter given a Requirement and an evaluation context.
 //
 //
 // Construct an interpreter given a Requirement and an evaluation context.
 //
@@ -61,14 +65,7 @@ bool Requirement::Interpreter::evaluate()
        case opIdent:
                return getString() == mContext->directory->identifier();
        case opAppleAnchor:
        case opIdent:
                return getString() == mContext->directory->identifier();
        case opAppleAnchor:
-               if (SecCertificateRef cert = mContext->cert(anchorCert))
-                       return verifyAnchor(cert, appleAnchorHash())
-#if defined(TEST_APPLE_ANCHOR)
-                               || verifyAnchor(cert, testAppleAnchorHash())
-#endif
-                       ;
-       else
-                       return false;
+               return appleSigned();
        case opAnchorHash:
                {
                        SecCertificateRef cert = mContext->cert(get<int32_t>());
        case opAnchorHash:
                {
                        SecCertificateRef cert = mContext->cert(get<int32_t>());
@@ -189,6 +186,26 @@ bool Requirement::Interpreter::certFieldValue(const string &key, const Match &ma
 }
 
 
 }
 
 
+//
+// Check the Apple-signed condition
+//
+bool Requirement::Interpreter::appleSigned()
+{
+       if (SecCertificateRef cert = mContext->cert(anchorCert))
+               if (verifyAnchor(cert, appleAnchorHash())
+#if defined(TEST_APPLE_ANCHOR)
+                       || verifyAnchor(cert, testAppleAnchorHash())
+#endif
+               )
+                       if (SecCertificateRef intermed = mContext->cert(-2))    // first intermediate
+                               // first intermediate common name match (exact)
+                               if (certFieldValue("subject.CN", Match(appleIntermediateCN, matchEqual), intermed)
+                                       && certFieldValue("subject.O", Match(appleIntermediateO, matchEqual), intermed))
+                                       return true;
+       return false;
+}
+
+
 //
 // Verify an anchor requirement against the context
 //
 //
 // Verify an anchor requirement against the context
 //
index 222bd17bed6ea0fcb808c363cbc5c71aecb4b360..ebeed8dcd985158d0ed0bb7ccd8e02e63cb76f32 100644 (file)
@@ -60,6 +60,7 @@ protected:
        bool infoKeyValue(const std::string &key, const Match &match);
        bool certFieldValue(const string &key, const Match &match, SecCertificateRef cert);
        bool verifyAnchor(SecCertificateRef cert, const unsigned char *digest);
        bool infoKeyValue(const std::string &key, const Match &match);
        bool certFieldValue(const string &key, const Match &match, SecCertificateRef cert);
        bool verifyAnchor(SecCertificateRef cert, const unsigned char *digest);
+       bool appleSigned();
        bool trustedCerts();
        bool trustedCert(int slot);
        
        bool trustedCerts();
        bool trustedCert(int slot);
        
index e005e82700b6e4d2f6713cfa2e34eea25ede015a..c270ed22cb7327c029b57c2af1de6d3aeebb5f41 100644 (file)
 #include <security_utilities/unixchild.h>
 #include <vector>
 
 #include <security_utilities/unixchild.h>
 #include <vector>
 
+// for helper validation
+#include "Code.h"
+#include "cfmunge.h"
+#include <sys/codesign.h>
+
+
 namespace Security {
 namespace CodeSigning {
 
 namespace Security {
 namespace CodeSigning {
 
@@ -43,6 +49,7 @@ namespace CodeSigning {
 //
 static const char helperName[] = "codesign_allocate";
 static const char helperPath[] = "/usr/bin/codesign_allocate";
 //
 static const char helperName[] = "codesign_allocate";
 static const char helperPath[] = "/usr/bin/codesign_allocate";
+static const char helperOverride[] = "CODESIGN_ALLOCATE";
 static const size_t csAlign = 16;
 
 
 static const size_t csAlign = 16;
 
 
@@ -135,6 +142,13 @@ MachOEditor::MachOEditor(DiskRep::Writer *w, Universal &code, std::string srcPat
        : ArchEditor(code, w->attributes()), writer(w), sourcePath(srcPath), tempPath(srcPath + ".cstemp"),
          mNewCode(NULL), mTempMayExist(false)
 {
        : ArchEditor(code, w->attributes()), writer(w), sourcePath(srcPath), tempPath(srcPath + ".cstemp"),
          mNewCode(NULL), mTempMayExist(false)
 {
+       if (const char *path = getenv(helperOverride)) {
+               mHelperPath = path;
+               mHelperOverridden = true;
+       } else {
+               mHelperPath = helperPath;
+               mHelperOverridden = false;
+       }
 }
 
 MachOEditor::~MachOEditor()
 }
 
 MachOEditor::~MachOEditor()
@@ -142,6 +156,24 @@ MachOEditor::~MachOEditor()
        delete mNewCode;
        if (mTempMayExist)
                ::remove(tempPath.c_str());             // ignore error (can't do anything about it)
        delete mNewCode;
        if (mTempMayExist)
                ::remove(tempPath.c_str());             // ignore error (can't do anything about it)
+
+       //@@@ this code should be in UnixChild::kill() -- migrate it there
+       if (state() == alive) {
+               this->kill(SIGTERM);            // shoot it once
+               checkChildren();                        // check for quick death
+               if (state() == alive) {
+                       usleep(500000);                 // give it some grace
+                       if (state() == alive) { // could have been reaped by another thread
+                               checkChildren();        // check again
+                               if (state() == alive) { // it... just... won't... die...
+                                       this->kill(SIGKILL); // take THAT!
+                                       checkChildren();
+                                       if (state() == alive) // stuck zombie
+                                               abandon();      // leave the body behind
+                               }
+                       }
+               }
+       }
 }
 
 
 }
 
 
@@ -170,6 +202,23 @@ void MachOEditor::allocate()
        mNewCode = new Universal(mFd);
 }
 
        mNewCode = new Universal(mFd);
 }
 
+static const unsigned char appleReq[] = {      // anchor apple
+       0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+};
+
+void MachOEditor::parentAction()
+{
+       if (mHelperOverridden) {
+               secdebug("machoedit", "validating alternate codesign_allocate at %s (pid=%d)", mHelperPath, this->pid());
+               // check code identity of an overridden allocation helper
+               SecPointer<SecStaticCode> code = new SecStaticCode(DiskRep::bestGuess(mHelperPath));
+               code->validateDirectory();
+               code->validateExecutable();
+               code->validateResources();
+               code->validateRequirements((const Requirement *)appleReq, errSecCSReqFailed);
+       }
+}
+
 void MachOEditor::childAction()
 {
        vector<const char *> arguments;
 void MachOEditor::childAction()
 {
        vector<const char *> arguments;
@@ -183,13 +232,26 @@ void MachOEditor::childAction()
                char *size;                             // we'll leak this (execv is coming soon)
                asprintf(&size, "%d", LowLevelMemoryUtilities::alignUp(it->second->blobSize, csAlign));
                secdebug("machoedit", "preparing %s size=%s", it->first.name(), size);
                char *size;                             // we'll leak this (execv is coming soon)
                asprintf(&size, "%d", LowLevelMemoryUtilities::alignUp(it->second->blobSize, csAlign));
                secdebug("machoedit", "preparing %s size=%s", it->first.name(), size);
-               arguments.push_back("-a");
-               arguments.push_back(it->first.name());
+
+               if (const char *arch = it->first.name()) {
+                       arguments.push_back("-a");
+                       arguments.push_back(arch);
+               } else {
+                       arguments.push_back("-A");
+                       char *anum;
+                       asprintf(&anum, "%d", it->first.cpuType());
+                       arguments.push_back(anum);
+                       asprintf(&anum, "%d", it->first.cpuSubtype());
+                       arguments.push_back(anum);
+               }
                arguments.push_back(size);
        }
        arguments.push_back(NULL);
                arguments.push_back(size);
        }
        arguments.push_back(NULL);
+       
+       if (mHelperOverridden)
+               ::csops(0, CS_EXEC_SET_KILL, NULL, 0);          // force code integrity
        ::seteuid(0);   // activate privilege if caller has it; ignore error if not
        ::seteuid(0);   // activate privilege if caller has it; ignore error if not
-       execv(helperPath, (char * const *)&arguments[0]);
+       execv(mHelperPath, (char * const *)&arguments[0]);
 }
 
 void MachOEditor::reset(Arch &arch)
 }
 
 void MachOEditor::reset(Arch &arch)
index 827c11ed2fb3509ba247b39d98a9b9cc38b2f8ff..2c0f958c7299348f5b0bca457499a3e65e2e599d 100644 (file)
@@ -168,9 +168,14 @@ public:
        
 private:
        void childAction();
        
 private:
        void childAction();
+       void parentAction();
+       
        Universal *mNewCode;
        UnixPlusPlus::AutoFileDesc mFd;
        bool mTempMayExist;
        Universal *mNewCode;
        UnixPlusPlus::AutoFileDesc mFd;
        bool mTempMayExist;
+       
+       const char *mHelperPath;
+       bool mHelperOverridden;
 };
 
 
 };
 
 
index 6de0c934ad42c651430b061b5eec2e5464a43ecc..98e944db9879caaa0facd79059c16cb43ca611fc 100644 (file)
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                BUILD_VARIANTS = debug;
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                BUILD_VARIANTS = debug;
-                               CURRENT_PROJECT_VERSION = 32568;
+                               CURRENT_PROJECT_VERSION = 32953;
                                FRAMEWORK_SEARCH_PATHS = (
                                        /usr/local/SecurityPieces/Frameworks,
                                        /usr/local/SecurityPieces/Components/Security,
                                FRAMEWORK_SEARCH_PATHS = (
                                        /usr/local/SecurityPieces/Frameworks,
                                        /usr/local/SecurityPieces/Components/Security,
                                        normal,
                                        debug,
                                );
                                        normal,
                                        debug,
                                );
-                               CURRENT_PROJECT_VERSION = 32568;
+                               CURRENT_PROJECT_VERSION = 32953;
                                FRAMEWORK_SEARCH_PATHS = (
                                        /usr/local/SecurityPieces/Frameworks,
                                        /usr/local/SecurityPieces/Components/Security,
                                FRAMEWORK_SEARCH_PATHS = (
                                        /usr/local/SecurityPieces/Frameworks,
                                        /usr/local/SecurityPieces/Components/Security,
                                        normal,
                                        debug,
                                );
                                        normal,
                                        debug,
                                );
-                               CURRENT_PROJECT_VERSION = 32568;
+                               CURRENT_PROJECT_VERSION = 32953;
                                FRAMEWORK_SEARCH_PATHS = (
                                        /usr/local/SecurityPieces/Frameworks,
                                        /usr/local/SecurityPieces/Components/Security,
                                FRAMEWORK_SEARCH_PATHS = (
                                        /usr/local/SecurityPieces/Frameworks,
                                        /usr/local/SecurityPieces/Components/Security,