Esempio n. 1
0
BlobCore *BlobCore::readBlob(std::FILE *file, uint32_t magic, size_t minSize, size_t maxSize)
{
	BlobCore header;
	if (::fread(&header, sizeof(header), 1, file) == 1)
		if (header.validateBlob(magic, minSize, maxSize))
			if (BlobCore *blob = (BlobCore *)malloc(header.length())) {
				memcpy(blob, &header, sizeof(header));
				if (::fread(blob+1, header.length() - sizeof(header), 1, file) == 1)
					return blob;
				free(blob);
				errno = EINVAL;
			}
	return NULL;
}
Esempio n. 2
0
BlobCore *BlobCore::readBlob(int fd, uint32_t magic, size_t minSize, size_t maxSize)
{
	BlobCore header;
	if (::read(fd, &header, sizeof(header)) == sizeof(header))
		if (header.validateBlob(magic, minSize, maxSize))
			if (BlobCore *blob = (BlobCore *)malloc(header.length())) {
				memcpy(blob, &header, sizeof(header));
				size_t remainder = header.length() - sizeof(header);
				if (::read(fd, blob+1, remainder) == ssize_t(remainder))
					return blob;
				free(blob);
				errno = EINVAL;
			}
	return NULL;
}
Esempio n. 3
0
//
// Provide low-level Code Signing information from the kernel.
// This is only of interest to geeks and testers.
//
void procinfo(const char *target)
{
	if (pid_t pid = (pid_t)atol(target)) {
		char path[MAXPATHLEN * 2];
		uint32_t flags;
		int rcpath = ::proc_pidpath(pid, path, sizeof(path));
		int rcstatus = ::csops(pid, CS_OPS_STATUS, &flags, 0);
		
		if (rcpath == 0 && rcstatus == -1) {	// neither path nor status (probably bad pid)
			perror(target);
			exit(1);
		}
		
		printf("%d:", pid);
		if (rcpath == 0)
			printf(" [path:%s]", strerror(errno));
		else
			printf(" %s", path);
		if (rcstatus == -1) {
			printf(" [flags:%s]", strerror(errno));
		} else {
			if (flags & CS_VALID) printf(" VALID");
			if (flags & CS_HARD) printf(" HARD");
			if (flags & CS_KILL) printf(" KILL");
			if (flags & CS_EXEC_SET_HARD) printf(" HARD(exec)");
			if (flags & CS_EXEC_SET_KILL) printf(" KILL(exec)");
			if (flags & ~(CS_VALID|CS_HARD|CS_KILL|CS_EXEC_SET_HARD|CS_EXEC_SET_KILL))
				printf(" (0x%x)", flags);
		}
		
		SHA1::Digest hash;
		int rchash = ::csops(pid, CS_OPS_CDHASH, hash, sizeof(hash));
		if (rchash == -1)
			printf(" [cdhash:%s]", strerror(errno));
		else
			printf(" cdhash=%s", hashString(hash).c_str());

		printf("\n");

		if (verbose > 0) {
		
			BlobCore header;
			int rcent = ::csops(pid, CS_OPS_ENTITLEMENTS_BLOB, &header, sizeof(header)); // size request
			if (rcent == 0)
				printf("[no entitlement]\n");
			else if (errno == ERANGE) {
				// kernel returns a blob header with magic == 0, length == needed size
				assert(header.magic() == 0);
				uint32_t bufferLen = (uint32_t)header.length();
				if (bufferLen > 1024 * 1024)
					fail("insane entitlement length from kernel");
				uint8_t buffer[bufferLen];

				rcent = ::csops(pid, CS_OPS_ENTITLEMENTS_BLOB, buffer, bufferLen);
				if (rcent == 0) {	// kernel says it's good
					const BlobCore *blob = (const BlobCore *)buffer;
					if (blob->length() < sizeof(*blob))
						fail("runt entitlement blob returned from kernel");
					if (blob->magic() == kSecCodeMagicEntitlement)
						fwrite(blob+1, blob->length() - sizeof(*blob), 1, stdout);
					else
						printf("Entitlement blob type 0x%x not understood\n", blob->magic());
				} else
					printf("[entitlements:%s]\n", strerror(errno));
			} else
				printf("[entitlements:%s]\n", strerror(errno));
		}
	} else {
		fail("%s: not a numeric process id", target);
	}
}