2 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
23 #include "piddiskrep.h"
25 #include <sys/param.h>
26 #include <sys/utsname.h>
27 #include <System/sys/codesign.h>
32 namespace CodeSigning
{
34 using namespace UnixPlusPlus
;
38 PidDiskRep::setCredentials(const Security::CodeSigning::CodeDirectory
*cd
)
40 // save the Info.plist slot
41 if (cd
->slotIsPresent(cdInfoSlot
)) {
42 mInfoPlistHash
.take(makeCFData(cd
->getSlot(cdInfoSlot
, false), cd
->hashSize
));
47 PidDiskRep::fetchData(void)
49 if (mDataFetched
) // once
52 xpc_connection_t conn
= xpc_connection_create("com.apple.CodeSigningHelper",
53 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0));
54 xpc_connection_set_event_handler(conn
, ^(xpc_object_t object
){ });
55 xpc_connection_resume(conn
);
57 xpc_object_t request
= xpc_dictionary_create(NULL
, NULL
, 0);
58 assert(request
!= NULL
);
59 xpc_dictionary_set_string(request
, "command", "fetchData");
60 xpc_dictionary_set_int64(request
, "pid", mPid
);
61 xpc_dictionary_set_data(request
, "infohash", CFDataGetBytePtr(mInfoPlistHash
), CFDataGetLength(mInfoPlistHash
));
63 xpc_object_t reply
= xpc_connection_send_message_with_reply_sync(conn
, request
);
64 if (reply
&& xpc_get_type(reply
) == XPC_TYPE_DICTIONARY
) {
69 data
= xpc_dictionary_get_data(reply
, "infoPlist", &size
);
70 if (data
&& size
> 0 && size
< 50 * 1024)
71 mInfoPlist
.take(CFDataCreate(NULL
, (const UInt8
*)data
, (CFIndex
)size
));
74 data
= xpc_dictionary_get_data(reply
, "bundleURL", &size
);
75 if (data
&& size
> 0 && size
< 50 * 1024)
76 mBundleURL
.take(CFURLCreateWithBytes(NULL
, (const UInt8
*)data
, (CFIndex
)size
, kCFStringEncodingUTF8
, NULL
));
86 MacOSError::throwMe(errSecCSNoSuchCode
);
92 PidDiskRep::PidDiskRep(pid_t pid
, CFDataRef infoPlist
)
96 CODESIGN_DISKREP_CREATE_KERNEL(this);
99 mInfoPlist
= infoPlist
;
103 int rcent
= ::csops(pid
, CS_OPS_BLOB
, &header
, sizeof(header
));
105 MacOSError::throwMe(errSecCSNoSuchCode
);
108 UnixError::throwMe(errno
);
110 if (header
.length() > 1024 * 1024)
111 MacOSError::throwMe(errSecCSNoSuchCode
);
113 uint32_t bufferLen
= (uint32_t)header
.length();
114 mBuffer
= new uint8_t [bufferLen
];
116 UnixError::check(::csops(pid
, CS_OPS_BLOB
, mBuffer
, bufferLen
));
118 const EmbeddedSignatureBlob
*b
= (const EmbeddedSignatureBlob
*)mBuffer
;
119 if (!b
->validateBlob(bufferLen
))
120 MacOSError::throwMe(errSecCSSignatureInvalid
);
123 PidDiskRep::~PidDiskRep()
130 bool PidDiskRep::supportInfoPlist()
137 CFDataRef
PidDiskRep::component(CodeDirectory::SpecialSlot slot
)
139 if (slot
== cdInfoSlot
) {
141 return mInfoPlist
.retain();
144 EmbeddedSignatureBlob
*b
= (EmbeddedSignatureBlob
*)this->blob();
145 return b
->component(slot
);
148 CFDataRef
PidDiskRep::identification()
154 CFURLRef
PidDiskRep::copyCanonicalPath()
157 return mBundleURL
.retain();
160 string
PidDiskRep::recommendedIdentifier(const SigningContext
&)
162 return string("pid") + to_string(mPid
);
165 size_t PidDiskRep::signingLimit()
170 size_t PidDiskRep::execSegLimit(const Architecture
*)
175 string
PidDiskRep::format()
177 return "pid diskrep";
180 UnixPlusPlus::FileDesc
&PidDiskRep::fd()
182 UnixError::throwMe(EINVAL
);
185 string
PidDiskRep::mainExecutablePath()
187 char path
[MAXPATHLEN
* 2];
188 if(::proc_pidpath(mPid
, path
, sizeof(path
)) == 0)
189 UnixError::throwMe(errno
);
194 bool PidDiskRep::appleInternalForcePlatform() const
197 int rcent
= ::csops(mPid
, CS_OPS_STATUS
, &flags
, sizeof(flags
));
200 MacOSError::throwMe(errSecCSNoSuchCode
);
203 return (flags
& CS_PLATFORM_BINARY
) == CS_PLATFORM_BINARY
;
206 } // end namespace CodeSigning
207 } // end namespace Security