]> git.saurik.com Git - apple/security.git/blob - libsecurity_codesigning/lib/piddiskrep.cpp
Security-55471.14.8.tar.gz
[apple/security.git] / libsecurity_codesigning / lib / piddiskrep.cpp
1 /*
2 * Copyright (c) 2012 Apple Computer, 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
72
73 PidDiskRep::PidDiskRep(pid_t pid, CFDataRef infoPlist)
74 {
75 BlobCore header;
76 CODESIGN_DISKREP_CREATE_KERNEL(this);
77
78 mPid = pid;
79 mInfoPlist = infoPlist;
80
81 fetchData();
82
83 int rcent = ::csops(pid, CS_OPS_BLOB, &header, sizeof(header));
84 if (rcent == 0)
85 MacOSError::throwMe(errSecCSNoSuchCode);
86
87 if (errno != ERANGE)
88 UnixError::throwMe(errno);
89
90 if (header.length() > 1024 * 1024)
91 MacOSError::throwMe(errSecCSNoSuchCode);
92
93 uint32_t bufferLen = (uint32_t)header.length();
94 mBuffer = new uint8_t [bufferLen];
95
96 UnixError::check(::csops(pid, CS_OPS_BLOB, mBuffer, bufferLen));
97
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);
103 }
104
105 PidDiskRep::~PidDiskRep()
106 {
107 if (mBuffer)
108 delete [] mBuffer;
109 }
110
111
112 bool PidDiskRep::supportInfoPlist()
113 {
114 return mInfoPlist;
115 }
116
117
118 CFDataRef PidDiskRep::component(CodeDirectory::SpecialSlot slot)
119 {
120 if (slot == cdInfoSlot)
121 return mInfoPlist.retain();
122
123 EmbeddedSignatureBlob *b = (EmbeddedSignatureBlob *)this->blob();
124 return b->component(slot);
125 }
126
127 CFDataRef PidDiskRep::identification()
128 {
129 return NULL;
130 }
131
132
133 CFURLRef PidDiskRep::canonicalPath()
134 {
135 return mBundleURL.retain();
136 }
137
138 string PidDiskRep::recommendedIdentifier(const SigningContext &)
139 {
140 return string("pid") + to_string(mPid);
141 }
142
143 size_t PidDiskRep::signingLimit()
144 {
145 return 0;
146 }
147
148 string PidDiskRep::format()
149 {
150 return "pid diskrep";
151 }
152
153 UnixPlusPlus::FileDesc &PidDiskRep::fd()
154 {
155 UnixError::throwMe(EINVAL);
156 }
157
158 string PidDiskRep::mainExecutablePath()
159 {
160 char path[MAXPATHLEN * 2];
161 if(::proc_pidpath(mPid, path, sizeof(path)) == 0)
162 UnixError::throwMe(errno);
163
164 return path;
165 }
166
167
168 } // end namespace CodeSigning
169 } // end namespace Security