2 * Copyright (c) 2012 Apple Computer, 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
));
73 PidDiskRep::PidDiskRep(pid_t pid
, CFDataRef infoPlist
)
76 CODESIGN_DISKREP_CREATE_KERNEL(this);
79 mInfoPlist
= infoPlist
;
83 int rcent
= ::csops(pid
, CS_OPS_BLOB
, &header
, sizeof(header
));
85 MacOSError::throwMe(errSecCSNoSuchCode
);
88 UnixError::throwMe(errno
);
90 if (header
.length() > 1024 * 1024)
91 MacOSError::throwMe(errSecCSNoSuchCode
);
93 uint32_t bufferLen
= (uint32_t)header
.length();
94 mBuffer
= new uint8_t [bufferLen
];
96 UnixError::check(::csops(pid
, CS_OPS_BLOB
, mBuffer
, bufferLen
));
98 const BlobCore
*b
= (const BlobCore
*)mBuffer
;
99 if (b
->magic() != kSecCodeMagicEmbeddedSignature
)
100 MacOSError::throwMe(errSecCSSignatureInvalid
);
101 if (b
->length() < sizeof(*b
))
102 MacOSError::throwMe(errSecCSNoSuchCode
);
105 PidDiskRep::~PidDiskRep()
112 bool PidDiskRep::supportInfoPlist()
118 CFDataRef
PidDiskRep::component(CodeDirectory::SpecialSlot slot
)
120 if (slot
== cdInfoSlot
)
121 return mInfoPlist
.retain();
123 EmbeddedSignatureBlob
*b
= (EmbeddedSignatureBlob
*)this->blob();
124 return b
->component(slot
);
127 CFDataRef
PidDiskRep::identification()
133 CFURLRef
PidDiskRep::canonicalPath()
135 return mBundleURL
.retain();
138 string
PidDiskRep::recommendedIdentifier(const SigningContext
&)
140 return string("pid") + to_string(mPid
);
143 size_t PidDiskRep::signingLimit()
148 string
PidDiskRep::format()
150 return "pid diskrep";
153 UnixPlusPlus::FileDesc
&PidDiskRep::fd()
155 UnixError::throwMe(EINVAL
);
158 string
PidDiskRep::mainExecutablePath()
160 char path
[MAXPATHLEN
* 2];
161 if(::proc_pidpath(mPid
, path
, sizeof(path
)) == 0)
162 UnixError::throwMe(errno
);
168 } // end namespace CodeSigning
169 } // end namespace Security