]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_codesigning/lib/piddiskrep.cpp
Security-57337.20.44.tar.gz
[apple/security.git] / OSX / libsecurity_codesigning / lib / piddiskrep.cpp
1 /*
2 * Copyright (c) 2012-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 #include "piddiskrep.h"
24 #include "sigblob.h"
25 #include <sys/param.h>
26 #include <sys/utsname.h>
27 #include <System/sys/codesign.h>
28 #include <libproc.h>
29 #include <xpc/xpc.h>
30
31 namespace Security {
32 namespace CodeSigning {
33
34 using namespace UnixPlusPlus;
35
36 void
37 PidDiskRep::fetchData(void)
38 {
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);
43
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);
48
49 xpc_object_t reply = xpc_connection_send_message_with_reply_sync(conn, request);
50 if (reply && xpc_get_type(reply) == XPC_TYPE_DICTIONARY) {
51 const void *data;
52 size_t size;
53
54 if (!mInfoPlist) {
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));
58 }
59 if (!mBundleURL) {
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));
63 }
64 }
65 if (reply)
66 xpc_release(reply);
67
68 xpc_release(request);
69 xpc_release(conn);
70
71 if (!mBundleURL)
72 MacOSError::throwMe(errSecCSNoSuchCode);
73 }
74
75
76 PidDiskRep::PidDiskRep(pid_t pid, CFDataRef infoPlist)
77 {
78 BlobCore header;
79 CODESIGN_DISKREP_CREATE_KERNEL(this);
80
81 mPid = pid;
82 mInfoPlist = infoPlist;
83
84 fetchData();
85
86 int rcent = ::csops(pid, CS_OPS_BLOB, &header, sizeof(header));
87 if (rcent == 0)
88 MacOSError::throwMe(errSecCSNoSuchCode);
89
90 if (errno != ERANGE)
91 UnixError::throwMe(errno);
92
93 if (header.length() > 1024 * 1024)
94 MacOSError::throwMe(errSecCSNoSuchCode);
95
96 uint32_t bufferLen = (uint32_t)header.length();
97 mBuffer = new uint8_t [bufferLen];
98
99 UnixError::check(::csops(pid, CS_OPS_BLOB, mBuffer, bufferLen));
100
101 const EmbeddedSignatureBlob *b = (const EmbeddedSignatureBlob *)mBuffer;
102 if (!b->validateBlob(bufferLen))
103 MacOSError::throwMe(errSecCSSignatureInvalid);
104 }
105
106 PidDiskRep::~PidDiskRep()
107 {
108 if (mBuffer)
109 delete [] mBuffer;
110 }
111
112
113 bool PidDiskRep::supportInfoPlist()
114 {
115 return mInfoPlist;
116 }
117
118
119 CFDataRef PidDiskRep::component(CodeDirectory::SpecialSlot slot)
120 {
121 if (slot == cdInfoSlot)
122 return mInfoPlist.retain();
123
124 EmbeddedSignatureBlob *b = (EmbeddedSignatureBlob *)this->blob();
125 return b->component(slot);
126 }
127
128 CFDataRef PidDiskRep::identification()
129 {
130 return NULL;
131 }
132
133
134 CFURLRef PidDiskRep::copyCanonicalPath()
135 {
136 return mBundleURL.retain();
137 }
138
139 string PidDiskRep::recommendedIdentifier(const SigningContext &)
140 {
141 return string("pid") + to_string(mPid);
142 }
143
144 size_t PidDiskRep::signingLimit()
145 {
146 return 0;
147 }
148
149 string PidDiskRep::format()
150 {
151 return "pid diskrep";
152 }
153
154 UnixPlusPlus::FileDesc &PidDiskRep::fd()
155 {
156 UnixError::throwMe(EINVAL);
157 }
158
159 string PidDiskRep::mainExecutablePath()
160 {
161 char path[MAXPATHLEN * 2];
162 if(::proc_pidpath(mPid, path, sizeof(path)) == 0)
163 UnixError::throwMe(errno);
164
165 return path;
166 }
167
168
169 } // end namespace CodeSigning
170 } // end namespace Security