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
;
37 PidDiskRep::fetchData(void)
39 xpc_connection_t conn
= xpc_connection_create("com.apple.CodeSigningHelper",
40 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0));
41 xpc_connection_set_event_handler(conn
, ^(xpc_object_t object
){ });
42 xpc_connection_resume(conn
);
44 xpc_object_t request
= xpc_dictionary_create(NULL
, NULL
, 0);
45 assert(request
!= NULL
);
46 xpc_dictionary_set_string(request
, "command", "fetchData");
47 xpc_dictionary_set_int64(request
, "pid", mPid
);
49 xpc_object_t reply
= xpc_connection_send_message_with_reply_sync(conn
, request
);
50 if (reply
&& xpc_get_type(reply
) == XPC_TYPE_DICTIONARY
) {
55 data
= xpc_dictionary_get_data(reply
, "infoPlist", &size
);
56 if (data
&& size
> 0 && size
< 50 * 1024)
57 mInfoPlist
.take(CFDataCreate(NULL
, (const UInt8
*)data
, (CFIndex
)size
));
60 data
= xpc_dictionary_get_data(reply
, "bundleURL", &size
);
61 if (data
&& size
> 0 && size
< 50 * 1024)
62 mBundleURL
.take(CFURLCreateWithBytes(NULL
, (const UInt8
*)data
, (CFIndex
)size
, kCFStringEncodingUTF8
, NULL
));
72 MacOSError::throwMe(errSecCSNoSuchCode
);
76 PidDiskRep::PidDiskRep(pid_t pid
, CFDataRef infoPlist
)
79 CODESIGN_DISKREP_CREATE_KERNEL(this);
82 mInfoPlist
= infoPlist
;
86 int rcent
= ::csops(pid
, CS_OPS_BLOB
, &header
, sizeof(header
));
88 MacOSError::throwMe(errSecCSNoSuchCode
);
91 UnixError::throwMe(errno
);
93 if (header
.length() > 1024 * 1024)
94 MacOSError::throwMe(errSecCSNoSuchCode
);
96 uint32_t bufferLen
= (uint32_t)header
.length();
97 mBuffer
= new uint8_t [bufferLen
];
99 UnixError::check(::csops(pid
, CS_OPS_BLOB
, mBuffer
, bufferLen
));
101 const EmbeddedSignatureBlob
*b
= (const EmbeddedSignatureBlob
*)mBuffer
;
102 if (!b
->validateBlob(bufferLen
))
103 MacOSError::throwMe(errSecCSSignatureInvalid
);
106 PidDiskRep::~PidDiskRep()
113 bool PidDiskRep::supportInfoPlist()
119 CFDataRef
PidDiskRep::component(CodeDirectory::SpecialSlot slot
)
121 if (slot
== cdInfoSlot
)
122 return mInfoPlist
.retain();
124 EmbeddedSignatureBlob
*b
= (EmbeddedSignatureBlob
*)this->blob();
125 return b
->component(slot
);
128 CFDataRef
PidDiskRep::identification()
134 CFURLRef
PidDiskRep::copyCanonicalPath()
136 return mBundleURL
.retain();
139 string
PidDiskRep::recommendedIdentifier(const SigningContext
&)
141 return string("pid") + to_string(mPid
);
144 size_t PidDiskRep::signingLimit()
149 string
PidDiskRep::format()
151 return "pid diskrep";
154 UnixPlusPlus::FileDesc
&PidDiskRep::fd()
156 UnixError::throwMe(EINVAL
);
159 string
PidDiskRep::mainExecutablePath()
161 char path
[MAXPATHLEN
* 2];
162 if(::proc_pidpath(mPid
, path
, sizeof(path
)) == 0)
163 UnixError::throwMe(errno
);
169 } // end namespace CodeSigning
170 } // end namespace Security