]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_codesigning/lib/diskimagerep.cpp
Security-59306.140.5.tar.gz
[apple/security.git] / OSX / libsecurity_codesigning / lib / diskimagerep.cpp
index 7bc89b48a43a717634c7604f40d71dd25060ac35..86b056c063f6ac11d54cc424a14ceaddad3de7ad 100644 (file)
@@ -25,6 +25,7 @@
 // diskimagerep - DiskRep representing a single read-only compressed disk image file
 //
 #include "diskimagerep.h"
+#include "notarization.h"
 #include "sigblob.h"
 #include "CodeSigner.h"
 #include <security_utilities/endian.h>
@@ -45,24 +46,6 @@ static const int32_t udifVersion = 4;                // supported image file version
 //
 // Temporary hack to imply a fUDIFCryptosigFieldsset at the start of the "reserved" area of an UDIF header
 //
-struct UDIFSigning {
-       uint64_t fCodeSignatureOffset;
-       uint64_t fCodeSignatureLength;
-};
-       
-UDIFSigning& sigFields(UDIFFileHeader& header);
-const UDIFSigning& sigFields(const UDIFFileHeader& header);
-       
-UDIFSigning& sigFields(UDIFFileHeader& header)
-{
-       return *(UDIFSigning*)&header.fReserved;
-}
-
-const UDIFSigning& sigFields(const UDIFFileHeader& header)
-{
-       return *(UDIFSigning*)&header.fReserved;
-}
-       
 bool DiskImageRep::readHeader(FileDesc& fd, UDIFFileHeader& header)
 {
        // the UDIF "header" is in fact the last 512 bytes of the file, with no particular alignment
@@ -86,13 +69,19 @@ bool DiskImageRep::readHeader(FileDesc& fd, UDIFFileHeader& header)
 // Object management.
 //
 DiskImageRep::DiskImageRep(const char *path)
-       : SingleDiskRep(path)
+       : SingleDiskRep(path), mSigningData(NULL)
 {
        this->setup();
 }
 
+DiskImageRep::~DiskImageRep()
+{
+       free((void*)mSigningData);
+}
+
 void DiskImageRep::setup()
 {
+       free((void*)mSigningData);
        mSigningData = NULL;
        
        // the UDIF "header" is in fact the last 512 bytes of the file, with no particular alignment
@@ -100,12 +89,12 @@ void DiskImageRep::setup()
                UnixError::throwMe(errSecCSBadDiskImageFormat);
 
        mHeaderOffset = fd().fileSize() - sizeof(UDIFFileHeader);
-       size_t signatureOffset = size_t(n2h(sigFields(this->mHeader).fCodeSignatureOffset));
-       size_t signatureLength = size_t(n2h(sigFields(this->mHeader).fCodeSignatureLength));
-       sigFields(this->mHeader).fCodeSignatureLength = 0;              // blind length (signature covers header)
+       size_t signatureOffset = size_t(n2h(this->mHeader.fUDIFCodeSignOffset));
+       size_t signatureLength = size_t(n2h(this->mHeader.fUDIFCodeSignLength));
+       this->mHeader.fUDIFCodeSignLength = 0;          // blind length (signature covers header)
        if (signatureOffset == 0) {
                mEndOfDataOffset = mHeaderOffset;
-               sigFields(mHeader).fCodeSignatureOffset = h2n(mHeaderOffset);
+               mHeader.fUDIFCodeSignOffset = h2n(mHeaderOffset);
                return;         // unsigned, header prepared for possible signing
        } else {
                mEndOfDataOffset = signatureOffset;
@@ -114,7 +103,9 @@ void DiskImageRep::setup()
        // read the signature superblob
        const size_t frameLength = mHeaderOffset - signatureOffset;             // room to following header
        if (EmbeddedSignatureBlob* blob = EmbeddedSignatureBlob::readBlob(fd(), signatureOffset, frameLength)) {
-               if (blob->length() != frameLength || frameLength != signatureLength) {
+               if (blob->length() != frameLength
+                               || frameLength != signatureLength
+                               || !blob->strictValidateBlob(frameLength)) {
                        free(blob);
                        MacOSError::throwMe(errSecCSBadDiskImageFormat);
                }
@@ -226,7 +217,7 @@ void DiskImageRep::Writer::component(CodeDirectory::SpecialSlot slot, CFDataRef
 //
 void DiskImageRep::Writer::flush()
 {
-       delete mSigningData;                    // ditch previous blob just in case
+       free((void*)mSigningData);              // ditch previous blob just in case
        mSigningData = Maker::make();   // assemble new signature SuperBlob
        
        // write signature superblob
@@ -237,9 +228,10 @@ void DiskImageRep::Writer::flush()
        
        // now (re)write disk image header after it
        UDIFFileHeader fullHeader = rep->mHeader;
-       sigFields(fullHeader).fCodeSignatureOffset = h2n(location);
-       sigFields(fullHeader).fCodeSignatureLength = h2n(mSigningData->length());
+       fullHeader.fUDIFCodeSignOffset = h2n(location);
+       fullHeader.fUDIFCodeSignLength = h2n(mSigningData->length());
        fd().writeAll(&fullHeader, sizeof(rep->mHeader));
+    fd().truncate(fd().position());
 }
 
 
@@ -250,6 +242,15 @@ void DiskImageRep::Writer::addDiscretionary(CodeDirectory::Builder &builder)
 {
 }
 
+void DiskImageRep::registerStapledTicket()
+{
+       CFRef<CFDataRef> data = NULL;
+       if (mSigningData) {
+               data.take(mSigningData->component(cdTicketSlot));
+               registerStapledTicketInDMG(data);
+       }
+}
+
 
 } // end namespace CodeSigning
 } // end namespace Security