singlediskrep.cpp
1 /* 2 * Copyright (c) 2006-2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 // 25 // singlediskrep - semi-abstract diskrep for a single file of some kind 26 // 27 #include "singlediskrep.h" 28 #include "csutilities.h" 29 #include <security_utilities/cfutilities.h> 30 #include <sys/stat.h> 31 32 namespace Security { 33 namespace CodeSigning { 34 35 using namespace UnixPlusPlus; 36 37 38 // 39 // Construct a SingleDiskRep 40 // 41 SingleDiskRep::SingleDiskRep(const std::string &path) 42 : mPath(path) 43 { 44 } 45 46 47 // 48 // The default binary identification of a SingleDiskRep is the (SHA-1) hash 49 // of the entire file itself. 50 // 51 CFDataRef SingleDiskRep::identification() 52 { 53 SHA1 hash; 54 this->fd().seek(0); 55 hashFileData(this->fd(), &hash); 56 SHA1::Digest digest; 57 hash.finish(digest); 58 return makeCFData(digest, sizeof(digest)); 59 } 60 61 62 // 63 // Both the canonical and main executable path of a SingleDiskRep is, well, its path. 64 // 65 CFURLRef SingleDiskRep::copyCanonicalPath() 66 { 67 return makeCFURL(mPath); 68 } 69 70 string SingleDiskRep::mainExecutablePath() 71 { 72 return mPath; 73 } 74 75 76 // 77 // The default signing limit is the size of the file. 78 // This will do unless the signing data gets creatively stuck in there somewhere. 79 // 80 size_t SingleDiskRep::signingLimit() 81 { 82 return fd().fileSize(); 83 } 84 85 // 86 // No executable segment in non-machO files. 87 // 88 size_t SingleDiskRep::execSegLimit(const Architecture *) 89 { 90 return 0; 91 } 92 93 // 94 // A lazily opened read-only file descriptor for the path. 95 // 96 FileDesc &SingleDiskRep::fd() 97 { 98 if (!mFd) 99 mFd.open(mPath, O_RDONLY); 100 return mFd; 101 } 102 103 // 104 // Flush cached state 105 // 106 void SingleDiskRep::flush() 107 { 108 mFd.close(); 109 } 110 111 //Check the magic darwinup xattr 112 bool SingleDiskRep::appleInternalForcePlatform() const 113 { 114 return mFd.hasExtendedAttribute("com.apple.root.installed"); 115 } 116 117 // 118 // The recommended identifier of a SingleDiskRep is, absent any better clue, 119 // the basename of its path. 120 // 121 string SingleDiskRep::recommendedIdentifier(const SigningContext &) 122 { 123 return canonicalIdentifier(mPath); 124 } 125 126 127 // 128 // Paranoid validation 129 // 130 void SingleDiskRep::strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags) 131 { 132 DiskRep::strictValidate(cd, tolerated, flags); 133 134 if (flags & kSecCSRestrictSidebandData) 135 if (fd().hasExtendedAttribute(XATTR_RESOURCEFORK_NAME) || fd().hasExtendedAttribute(XATTR_FINDERINFO_NAME)) 136 if (tolerated.find(errSecCSInvalidAssociatedFileData) == tolerated.end()) 137 MacOSError::throwMe(errSecCSInvalidAssociatedFileData); 138 139 // code limit must cover (exactly) the entire file 140 if (cd && cd->signingLimit() != signingLimit()) 141 MacOSError::throwMe(errSecCSSignatureInvalid); 142 } 143 144 145 146 // 147 // Prototype Writers 148 // 149 FileDesc &SingleDiskRep::Writer::fd() 150 { 151 if (!mFd) 152 mFd.open(rep->path(), O_RDWR); 153 return mFd; 154 } 155 156 157 } // end namespace CodeSigning 158 } // end namespace Security