]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_codesigning/lib/signerutils.cpp
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / libsecurity_codesigning / lib / signerutils.cpp
index d543433ac7cf3e903caf6376f0d4674f461aae8e..f6da5e936cd7142612990322bafe4659a46568b7 100644 (file)
@@ -103,6 +103,7 @@ ArchEditor::~ArchEditor()
 ArchEditor::Arch::Arch(const Architecture &arch, CodeDirectory::HashAlgorithms hashTypes)
        : architecture(arch)
 {
+       blobSize = 0;
        for (auto type = hashTypes.begin(); type != hashTypes.end(); ++type)
                cdBuilders.insert(make_pair(*type, new CodeDirectory::Builder(*type)));
 }
@@ -167,6 +168,7 @@ MachOEditor::~MachOEditor()
        delete mNewCode;
        if (mTempMayExist)
                ::remove(tempPath.c_str());             // ignore error (can't do anything about it)
+
        this->kill();
 }
 
@@ -260,7 +262,11 @@ void MachOEditor::reset(Arch &arch)
 
        for (auto type = mHashTypes.begin(); type != mHashTypes.end(); ++type) {
                arch.eachDigest(^(CodeDirectory::Builder& builder) {
-                       builder.reopen(tempPath, arch.source->offset(), arch.source->signingOffset());
+                       /* Signature editing may have no need for cd builders, and not
+                        * have opened them, so only reopen them conditionally. */
+                       if (builder.opened()) {
+                               builder.reopen(tempPath, arch.source->offset(), arch.source->signingOffset());
+                       }
                });
        }
 }
@@ -311,7 +317,19 @@ void MachOEditor::commit()
                
                // copy metadata from original file...
                copy(sourcePath.c_str(), NULL, COPYFILE_SECURITY | COPYFILE_METADATA);
-               
+
+#if TARGET_OS_OSX
+               // determine AFSC status if we are told to preserve compression
+               bool conductCompression = false;
+               cmpInfo cInfo;
+               if (writer->getPreserveAFSC()) {
+                       if (queryCompressionInfo(sourcePath.c_str(), &cInfo) == 0) {
+                               if (cInfo.compressionType != 0 && cInfo.compressedSize > 0)
+                                       conductCompression = true;
+                       }
+               }
+#endif
+
                // ... but explicitly update the timestamps since we did change the file
                char buf;
                mFd.read(&buf, sizeof(buf), 0);
@@ -320,6 +338,28 @@ void MachOEditor::commit()
                // move the new file into place
                UnixError::check(::rename(tempPath.c_str(), sourcePath.c_str()));
                mTempMayExist = false;          // we renamed it away
+
+#if TARGET_OS_OSX
+               // if the original file was compressed, compress the new file after move
+               if (conductCompression) {
+                       CFMutableDictionaryRef options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                       CFStringRef val = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), cInfo.compressionType);
+                       CFDictionarySetValue(options, kAFSCCompressionTypes, val);
+                       CFRelease(val);
+
+                       CompressionQueueContext compressionQueue = CreateCompressionQueue(NULL, NULL, NULL, NULL, options);
+
+                       if (!CompressFile(compressionQueue, sourcePath.c_str(), NULL)) {
+                               secinfo("signer", "%p Failed to queue compression of file %s", this, sourcePath.c_str());
+                               MacOSError::throwMe(errSecCSInternalError);
+                       }
+                       FinishCompressionAndCleanUp(compressionQueue);
+
+                       compressionQueue = NULL;
+                       CFRelease(options);
+               }
+#endif
+
        }
        this->writer->flush();
 }