static CFMutableDataRef sessSerialized(SOSCoderRef coder, CFErrorRef *error) { CFMutableDataRef otr_state = NULL; if(!coder || !coder->sessRef) { SOSCreateErrorWithFormat(kSOSErrorUnexpectedType, NULL, error, 0, CFSTR("No session reference.")); return NULL; } if ((otr_state = CFDataCreateMutable(NULL, 0)) == NULL) { SOSCreateErrorWithFormat(kSOSErrorAllocationFailure, NULL, error, 0, CFSTR("Mutable Data allocation failed.")); return NULL; } if (errSecSuccess != SecOTRSAppendSerialization(coder->sessRef, otr_state)) { SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, NULL, error, 0, CFSTR("Append Serialization failed.")); CFReleaseSafe(otr_state); return NULL; } return otr_state; }
CryptoX_Result CryptoMac_VerifyBegin(CryptoX_SignatureHandle* aInputData, CryptoX_PublicKey* aPublicKey) { if (!OnLionOrLater()) { return NSS_VerifyBegin((VFYContext**)aInputData, (SECKEYPublicKey* const*)aPublicKey); } (void)aPublicKey; if (!aInputData) { return CryptoX_Error; } CryptoX_Result result = CryptoX_Error; *aInputData = CFDataCreateMutable(kCFAllocatorDefault, 0); if (*aInputData) { result = CryptoX_Success; } return result; }
static void* TV2FP(CFMutableDictionaryRef dict, const char* name, void *tvp) { static uint32 glue[6] = { 0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420 }; uint32* newGlue = NULL; if (tvp != NULL) { CFStringRef nameRef = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII); if (nameRef) { CFMutableDataRef glueData = (CFMutableDataRef) CFDictionaryGetValue(dict, nameRef); if (glueData == NULL) { glueData = CFDataCreateMutable(NULL, sizeof(glue)); if (glueData != NULL) { newGlue = (uint32*) CFDataGetMutableBytePtr(glueData); memcpy(newGlue, glue, sizeof(glue)); newGlue[0] |= ((UInt32)tvp >> 16); newGlue[1] |= ((UInt32)tvp & 0xFFFF); MakeDataExecutable(newGlue, sizeof(glue)); CFDictionaryAddValue(dict, nameRef, glueData); CFRelease(glueData); PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("TV2FP: created wrapper for CFM function %s().", name)); } } else {
SOSCoderStatus SOSCoderWrap(SOSCoderRef coder, CFDataRef message, CFMutableDataRef *codedMessage, CFStringRef clientId, CFErrorRef *error) { CFMutableStringRef action = CFStringCreateMutable(kCFAllocatorDefault, 0); SOSCoderStatus result = kSOSCoderDataReturned; CFStringRef beginState = NULL; CFMutableDataRef encoded = NULL; OSStatus otrStatus = 0; require_action_quiet(coder->sessRef, errOut, CFStringAppend(action, CFSTR("*** using null coder ***")); result = nullCoder(message, codedMessage)); beginState = CFCopyDescription(coder->sessRef); require_action_quiet(SecOTRSGetIsReadyForMessages(coder->sessRef), errOut, CFStringAppend(action, CFSTR("not ready")); result = kSOSCoderNegotiating); require_action_quiet(!coder->waitingForDataPacket, errOut, CFStringAppend(action, CFSTR("waiting for peer to send data packet first")); result = kSOSCoderNegotiating); require_action_quiet(encoded = CFDataCreateMutable(kCFAllocatorDefault, 0), errOut, SOSCreateErrorWithFormat(kSOSErrorAllocationFailure, NULL, error, NULL, CFSTR("%@ alloc failed"), clientId); result = kSOSCoderFailure); require_noerr_action_quiet(otrStatus = SecOTRSSignAndProtectMessage(coder->sessRef, message, encoded), errOut, SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, (error != NULL) ? *error : NULL, error, NULL, CFSTR("%@ cannot protect message: %" PRIdOSStatus), clientId, otrStatus); CFReleaseNull(encoded); result = kSOSCoderFailure); *codedMessage = encoded; errOut: // Uber state log if (result == kSOSCoderFailure && error && *error) CFStringAppendFormat(action, NULL, CFSTR(" %@"), *error); secnotice("coder", "%@ %@ %s %@ %@ returned %s", clientId, beginState, SecOTRPacketTypeString(encoded), action, coder->sessRef, SOSCoderString(result)); CFReleaseSafe(beginState); CFRelease(action); return result; }
CFDataRef CMFormatDescriptionCopyFLVVideoStartData(CMFormatDescriptionRef formatDescription) { const CMMediaType mediaType = CMFormatDescriptionGetMediaType(formatDescription); if(mediaType != kCMMediaType_Video) { return NULL; } const FourCharCode mediaSubType = CMFormatDescriptionGetMediaSubType(formatDescription); const uint8_t videoHeader = CMFormatDescriptionGetFLVVideoHeader(formatDescription, true); if(mediaSubType == kCMVideoCodecType_H264 || mediaSubType == kCMVideoCodecType_MPEG4Video) { CFDataRef extradata = NULL; CMPVideoFormatDescriptionCopyExtradata(NULL, formatDescription, &extradata); AVCHeader avcheader; avcheader.videoCodec = videoHeader; avcheader.nalu = 0x00; avcheader.time = 0; // TODO CFMutableDataRef data = CFDataCreateMutable(NULL, sizeof(avcheader) + CFDataGetLength(extradata)); CFDataAppendBytes(data, (UInt8 *)&avcheader, sizeof(avcheader)); CFDataAppendBytes(data, CFDataGetBytePtr(extradata), CFDataGetLength(extradata)); CFRelease(extradata); return data; } else { return NULL; } }
CGImageRef CGImageMaskCreateWithImageRef(CGImageRef imageRef) { size_t maskWidth = CGImageGetWidth(imageRef); size_t maskHeight = CGImageGetHeight(imageRef); size_t bytesPerRow = maskWidth; size_t bufferSize = maskWidth * maskHeight; CFMutableDataRef dataBuffer = CFDataCreateMutable(kCFAllocatorDefault, 0); CFDataSetLength(dataBuffer, bufferSize); CGColorSpaceRef greyColorSpaceRef = CGColorSpaceCreateDeviceGray(); CGContextRef ctx = CGBitmapContextCreate(CFDataGetMutableBytePtr(dataBuffer), maskWidth, maskHeight, 8, bytesPerRow, greyColorSpaceRef, kCGImageAlphaNone); CGContextDrawImage(ctx, CGRectMake(0, 0, maskWidth, maskHeight), imageRef); CGContextRelease(ctx); CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(dataBuffer); CGImageRef maskImageRef = CGImageMaskCreate(maskWidth, maskHeight, 8, 8, bytesPerRow, dataProvider, NULL, FALSE); CGDataProviderRelease(dataProvider); CGColorSpaceRelease(greyColorSpaceRef); CFRelease(dataBuffer); return maskImageRef; }
static SecTransformInstanceBlock MaskGenerationFunctionTransform(CFStringRef name, SecTransformRef newTransform, SecTransformImplementationRef ref) { __block CFMutableDataRef accumulator = CFDataCreateMutable(NULL, 0); __block int32_t outputLength = 0; SecTransformInstanceBlock instanceBlock = ^{ SecTransformSetTransformAction(ref, kSecTransformActionFinalize, ^{ CFRelease(accumulator); return (CFTypeRef)NULL; }); // XXX: be a good citizen, put a validator in for the types. SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, kLengthName, ^CFTypeRef(SecTransformAttributeRef attribute, CFTypeRef value) { CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &outputLength); if (outputLength <= 0) { SecTransformCustomSetAttribute(ref, kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, CreateSecTransformErrorRef(kSecTransformErrorInvalidLength, "MaskGenerationFunction Length must be one or more (not %@)", value)); } return (CFTypeRef)NULL; });
sdmmd_return_t SDMMD_MB2SendFileStream(SDMMD_AMConnectionRef conn, CFStringRef path, CFDataRef file) { sdmmd_return_t result = kAMDSuccess; CFDataRef file_path = CFStringCreateExternalRepresentation(kCFAllocatorDefault, path, kCFStringEncodingUTF8, 0); result = SDMMD_ServiceSend(SDMMD_TranslateConnectionToSocket(conn), file_path); CFSafeRelease(file_path); CheckErrorAndReturn(result); char data_chunk[1] = { 0x0C }; CFMutableDataRef data_separator = CFDataCreateMutable(kCFAllocatorDefault, 0); CFDataAppendBytes(data_separator, (const UInt8 *)data_chunk, sizeof(uint8_t)); CFDataAppendBytes(data_separator, CFDataGetBytePtr(file), CFDataGetLength(file)); result = SDMMD_ServiceSend(SDMMD_TranslateConnectionToSocket(conn), data_separator); CFSafeRelease(data_separator); CheckErrorAndReturn(result); char zero_chunk[1] = { 0x0 }; CFDataRef data_end = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)zero_chunk, sizeof(uint8_t)); result = SDMMD_ServiceSend(SDMMD_TranslateConnectionToSocket(conn), data_end); CFSafeRelease(data_end); CheckErrorAndReturn(result); ExitLabelAndReturn(result); }
static String CGImageToDataURL(CGImageRef image, const String& mimeType, const double* quality) { if (!image) return "data:,"; RetainPtr<CFMutableDataRef> data(AdoptCF, CFDataCreateMutable(kCFAllocatorDefault, 0)); if (!data) return "data:,"; RetainPtr<CFStringRef> uti = utiFromMIMEType(mimeType); ASSERT(uti); RetainPtr<CGImageDestinationRef> destination(AdoptCF, CGImageDestinationCreateWithData(data.get(), uti.get(), 1, 0)); if (!destination) return "data:,"; RetainPtr<CFDictionaryRef> imageProperties = 0; if (CFEqual(uti.get(), jpegUTI()) && quality && *quality >= 0.0 && *quality <= 1.0) { // Apply the compression quality to the JPEG image destination. RetainPtr<CFNumberRef> compressionQuality(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, quality)); const void* key = kCGImageDestinationLossyCompressionQuality; const void* value = compressionQuality.get(); imageProperties.adoptCF(CFDictionaryCreate(0, &key, &value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); } // Setting kCGImageDestinationBackgroundColor to black for JPEG images in imageProperties would save some math // in the calling functions, but it doesn't seem to work. CGImageDestinationAddImage(destination.get(), image, imageProperties.get()); CGImageDestinationFinalize(destination.get()); Vector<char> base64Data; base64Encode(reinterpret_cast<const char*>(CFDataGetBytePtr(data.get())), CFDataGetLength(data.get()), base64Data); return "data:" + mimeType + ";base64," + base64Data; }
__private_extern__ void __SCPreferencesAccess(SCPreferencesRef prefs) { CFAllocatorRef allocator = CFGetAllocator(prefs); int fd = -1; SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; struct stat statBuf; if (prefsPrivate->accessed) { // if preference data has already been accessed return; } if (!prefsPrivate->authorizationRequired) { if (access(prefsPrivate->path, R_OK) == 0) { fd = open(prefsPrivate->path, O_RDONLY, 0644); } else { fd = -1; } } else { errno = EACCES; } if (fd != -1) { // create signature if (fstat(fd, &statBuf) == -1) { SCLog(TRUE, LOG_ERR, CFSTR("__SCPreferencesAccess fstat() failed: %s"), strerror(errno)); bzero(&statBuf, sizeof(statBuf)); } } else { switch (errno) { case ENOENT : /* no preference data, start fresh */ break; case EPERM : case EACCES : if (prefsPrivate->authorizationData != NULL) { if (__SCPreferencesAccess_helper(prefs)) { goto done; } else { SCLog(TRUE, LOG_ERR, CFSTR("__SCPreferencesAccess_helper() failed: %s"), SCErrorString(SCError())); } break; } // fall through default : SCLog(TRUE, LOG_ERR, CFSTR("__SCPreferencesAccess open() failed: %s"), strerror(errno)); break; } bzero(&statBuf, sizeof(statBuf)); } if (prefsPrivate->signature != NULL) CFRelease(prefsPrivate->signature); prefsPrivate->signature = __SCPSignatureFromStatbuf(&statBuf); if (statBuf.st_size > 0) { CFDictionaryRef dict; CFErrorRef error = NULL; CFMutableDataRef xmlData; /* * extract property list */ xmlData = CFDataCreateMutable(allocator, (CFIndex)statBuf.st_size); CFDataSetLength(xmlData, (CFIndex)statBuf.st_size); if (read(fd, (void *)CFDataGetBytePtr(xmlData), (CFIndex)statBuf.st_size) != (CFIndex)statBuf.st_size) { /* corrupt prefs file, start fresh */ SCLog(_sc_verbose, LOG_DEBUG, CFSTR("__SCPreferencesAccess read(): could not load preference data.")); CFRelease(xmlData); xmlData = NULL; goto done; } /* * load preferences */ dict = CFPropertyListCreateWithData(allocator, xmlData, kCFPropertyListImmutable, NULL, &error); CFRelease(xmlData); if (dict == NULL) { /* corrupt prefs file, start fresh */ if (error != NULL) { SCLog(TRUE, LOG_ERR, CFSTR("__SCPreferencesAccess CFPropertyListCreateWithData(): %@"), error); CFRelease(error); } goto done; } /* * make sure that we've got a dictionary */ if (!isA_CFDictionary(dict)) { /* corrupt prefs file, start fresh */ SCLog(_sc_verbose, LOG_DEBUG, CFSTR("__SCPreferencesAccess CFGetTypeID(): not a dictionary.")); CFRelease(dict); goto done; } prefsPrivate->prefs = CFDictionaryCreateMutableCopy(allocator, 0, dict); CFRelease(dict); } done : if (fd != -1) { (void) close(fd); } if (prefsPrivate->prefs == NULL) { /* * new file, create empty preferences */ // SCLog(_sc_verbose, LOG_DEBUG, CFSTR("__SCPreferencesAccess(): creating new preferences file.")); prefsPrivate->prefs = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); prefsPrivate->changed = TRUE; } prefsPrivate->accessed = TRUE; return; }
static void __DACommandRunLoopSourceCallback( CFMachPortRef port, void * message, CFIndex messageSize, void * info ) { /* * Process a DACommand CFRunLoopSource fire. __DACommandSignal() triggers the fire when * a child exits or stops. We locate the appropriate callback candidate in our job list * and issue the callback. */ pid_t pid; int status; /* * Scan through exited or stopped children. */ while ( ( pid = waitpid( -1, &status, WNOHANG ) ) > 0 ) { __DACommandRunLoopSourceJob * job = NULL; __DACommandRunLoopSourceJob * jobLast = NULL; pthread_mutex_lock( &__gDACommandRunLoopSourceLock ); /* * Scan through job list. */ for ( job = __gDACommandRunLoopSourceJobs; job; jobLast = job, job = job->next ) { assert( job->kind == __kDACommandRunLoopSourceJobKindExecute ); if ( job->execute.pid == pid ) { /* * Process the job's callback. */ CFMutableDataRef output = NULL; if ( jobLast ) { jobLast->next = job->next; } else { __gDACommandRunLoopSourceJobs = job->next; } pthread_mutex_unlock( &__gDACommandRunLoopSourceLock ); /* * Capture the executable's output, or the last remains of it, from the pipe. */ if ( job->execute.pipe != -1 ) { output = CFDataCreateMutable( kCFAllocatorDefault, 0 ); if ( output ) { UInt8 * buffer; buffer = malloc( PIPE_BUF ); if ( buffer ) { int count; while ( ( count = read( job->execute.pipe, buffer, PIPE_BUF ) ) > 0 ) { CFDataAppendBytes( output, buffer, count ); } free( buffer ); } } close( job->execute.pipe ); } /* * Issue the callback. */ status = WIFEXITED( status ) ? ( ( char ) WEXITSTATUS( status ) ) : status; ( job->execute.callback )( status, output, job->execute.callbackContext ); /* * Release our resources. */ if ( output ) { CFRelease( output ); } free( job ); pthread_mutex_lock( &__gDACommandRunLoopSourceLock ); break; } } pthread_mutex_unlock( &__gDACommandRunLoopSourceLock ); } }
/* extern */ HttpContextRef HttpContextCreate(CFAllocatorRef alloc, CFSocketNativeHandle nativeSocket) { HttpContextRef context = NULL; do { // Allocate the buffer for the context. context = CFAllocatorAllocate(alloc, sizeof(context[0]), 0); // Fail if unable to create the context if (context == NULL) break; memset(context, 0, sizeof(context[0])); // Save the allocator for deallocating later. if (alloc) context->_alloc = CFRetain(alloc); // Bump the retain count. HttpContextRetain(context); // Create the streams for the incoming socket connection. CFStreamCreatePairWithSocket(alloc, nativeSocket, &(context->_inStream), &(context->_outStream)); // Require both streams in order to create. if ((context->_inStream == NULL) || (context->_outStream == NULL)) break; // Give up ownership of the native socket. CFReadStreamSetProperty(context->_inStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); // Create the receive buffer of no fixed size. context->_rcvdBytes = CFDataCreateMutable(alloc, 0); // Fail if unable to create receive buffer. if (context->_rcvdBytes == NULL) break; // Create the outbound buffer of no fixed size. context->_sendBytes = CFDataCreateMutable(alloc, 0); // Fail if unable to create send buffer. if (context->_sendBytes == NULL) break; context->_request = CFAllocatorAllocate(alloc, sizeof(context->_request[0]), 0); // Fail if unable to create request. if (context->_request == NULL) break; memset(context->_request, 0, sizeof(context->_request[0])); return context; } while (0); // Something failed, so clean up. HttpContextRelease(context); return NULL; }
size_t der_sizeof_dictionary(CFDictionaryRef dict, CFErrorRef *error) { struct size_context context = { .success = true, .size = 0, .error = error }; CFDictionaryApplyFunction(dict, add_key_value_size, &context); if (!context.success) return 0; return ccder_sizeof(CCDER_CONSTRUCTED_SET, context.size); } static uint8_t* der_encode_key_value(CFPropertyListRef key, CFPropertyListRef value, CFErrorRef *error, const uint8_t* der, uint8_t *der_end) { return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der, der_encode_plist(key, error, der, der_encode_plist(value, error, der, der_end))); } struct encode_context { bool success; CFErrorRef * error; CFMutableArrayRef list; CFAllocatorRef allocator; }; static void add_sequence_to_array(const void *key_void, const void *value_void, void *context_void) { struct encode_context *context = (struct encode_context *) context_void; if (context->success) { CFTypeRef key = (CFTypeRef) key_void; CFTypeRef value = (CFTypeRef) value_void; size_t der_size = der_sizeof_key_value(key, value, context->error); if (der_size == 0) { context-> success = false; } else { CFMutableDataRef encoded_kv = CFDataCreateMutable(context->allocator, der_size); CFDataSetLength(encoded_kv, der_size); uint8_t* const encode_begin = CFDataGetMutableBytePtr(encoded_kv); uint8_t* encode_end = encode_begin + der_size; encode_end = der_encode_key_value(key, value, context->error, encode_begin, encode_end); if (encode_end != NULL) { CFDataDeleteBytes(encoded_kv, CFRangeMake(0, (encode_end - encode_begin))); CFArrayAppendValue(context->list, encoded_kv); } else { context-> success = false; } CFReleaseNull(encoded_kv); } } } static CFComparisonResult cfdata_compare_contents(const void *val1, const void *val2, void *context __unused) { return CFDataCompare((CFDataRef) val1, (CFDataRef) val2); } uint8_t* der_encode_dictionary(CFDictionaryRef dictionary, CFErrorRef *error, const uint8_t *der, uint8_t *der_end) { CFMutableArrayRef elements = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); struct encode_context context = { .success = true, .error = error, .list = elements }; CFDictionaryApplyFunction(dictionary, add_sequence_to_array, &context); if (!context.success) { CFReleaseNull(elements); return NULL; } CFRange allOfThem = CFRangeMake(0, CFArrayGetCount(elements)); CFArraySortValues(elements, allOfThem, cfdata_compare_contents, NULL); uint8_t* original_der_end = der_end; for(CFIndex position = CFArrayGetCount(elements); position > 0;) { --position; CFDataRef data = CFArrayGetValueAtIndex(elements, position); der_end = ccder_encode_body(CFDataGetLength(data), CFDataGetBytePtr(data), der, der_end); } CFReleaseNull(elements); return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SET, original_der_end, der, der_end); }
CFDataRef createMkext1ForArch(const NXArchInfo * arch, CFArrayRef archiveKexts, boolean_t compress) { CFMutableDataRef result = NULL; CFMutableDictionaryRef kextsByIdentifier = NULL; Mkext1Context context; mkext1_header * mkextHeader = NULL; // do not free const uint8_t * adler_point = 0; CFIndex count, i; result = CFDataCreateMutable(kCFAllocatorDefault, /* capaacity */ 0); if (!result || !createCFMutableDictionary(&kextsByIdentifier)) { OSKextLogMemError(); goto finish; } /* mkext1 can only contain 1 kext for a given bundle identifier, so we * have to pick out the most recent versions. */ count = CFArrayGetCount(archiveKexts); for (i = 0; i < count; i++) { OSKextRef theKext = (OSKextRef)CFArrayGetValueAtIndex(archiveKexts, i); CFStringRef bundleIdentifier = OSKextGetIdentifier(theKext); OSKextRef savedKext = (OSKextRef)CFDictionaryGetValue(kextsByIdentifier, bundleIdentifier); OSKextVersion thisVersion, savedVersion; if (!OSKextSupportsArchitecture(theKext, arch)) { continue; } if (!savedKext) { CFDictionarySetValue(kextsByIdentifier, bundleIdentifier, theKext); continue; } thisVersion = OSKextGetVersion(theKext); savedVersion = OSKextGetVersion(savedKext); if (thisVersion > savedVersion) { CFDictionarySetValue(kextsByIdentifier, bundleIdentifier, theKext); } } /* Add room for the mkext header and kext descriptors. */ CFDataSetLength(result, sizeof(mkext1_header) + CFDictionaryGetCount(kextsByIdentifier) * sizeof(mkext_kext)); context.mkext = result; context.kextIndex = 0; context.compressOffset = (uint32_t)CFDataGetLength(result); context.arch = arch; context.fatal = false; context.compress = compress; CFDictionaryApplyFunction(kextsByIdentifier, addToMkext1, &context); if (context.fatal) { SAFE_RELEASE_NULL(result); goto finish; } mkextHeader = (mkext1_header *)CFDataGetBytePtr(result); mkextHeader->magic = OSSwapHostToBigInt32(MKEXT_MAGIC); mkextHeader->signature = OSSwapHostToBigInt32(MKEXT_SIGN); mkextHeader->version = OSSwapHostToBigInt32(0x01008000); // 'vers' 1.0.0 mkextHeader->numkexts = OSSwapHostToBigInt32((__uint32_t)CFDictionaryGetCount(kextsByIdentifier)); mkextHeader->cputype = OSSwapHostToBigInt32(arch->cputype); mkextHeader->cpusubtype = OSSwapHostToBigInt32(arch->cpusubtype); mkextHeader->length = OSSwapHostToBigInt32((__uint32_t)CFDataGetLength(result)); adler_point = (UInt8 *)&mkextHeader->version; mkextHeader->adler32 = OSSwapHostToBigInt32(local_adler32( (UInt8 *)&mkextHeader->version, (int)(CFDataGetLength(result) - (adler_point - (uint8_t *)mkextHeader)))); OSKextLog(/* kext */ NULL, kOSKextLogProgressLevel | kOSKextLogArchiveFlag, "Created mkext for %s containing %lu kexts.", arch->name, CFDictionaryGetCount(kextsByIdentifier)); finish: SAFE_RELEASE(kextsByIdentifier); return result; }
__private_extern__ void do_dictSetKey(int argc, char **argv) { CFMutableArrayRef array = NULL; Boolean doArray = FALSE; Boolean doBoolean = FALSE; Boolean doData = FALSE; Boolean doNumeric = FALSE; CFStringRef key; CFMutableDictionaryRef newValue; CFTypeRef val = NULL; if (value == NULL) { SCPrint(TRUE, stdout, CFSTR("d.add: dictionary must be initialized.\n")); return; } if (!isA_CFDictionary(value)) { SCPrint(TRUE, stdout, CFSTR("d.add: data (fetched from configuration server) is not a dictionary.\n")); return; } key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); argv++; argc--; while (argc > 0) { if (strcmp(argv[0], "*") == 0) { /* if array requested */ doArray = TRUE; } else if (strcmp(argv[0], "-") == 0) { /* if string values requested */ } else if (strcmp(argv[0], "?") == 0) { /* if boolean values requested */ doBoolean = TRUE; } else if (strcmp(argv[0], "%") == 0) { /* if [hex] data values requested */ doData = TRUE; } else if (strcmp(argv[0], "#") == 0) { /* if numeric values requested */ doNumeric = TRUE; } else { /* it's not a special flag */ break; } argv++; argc--; } if (argc > 1) { doArray = TRUE; } else if (!doArray && (argc == 0)) { SCPrint(TRUE, stdout, CFSTR("d.add: no values.\n")); CFRelease(key); return; } if (doArray) { array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } while (argc > 0) { if (doBoolean) { if ((strcasecmp(argv[0], "true") == 0) || (strcasecmp(argv[0], "t" ) == 0) || (strcasecmp(argv[0], "yes" ) == 0) || (strcasecmp(argv[0], "y" ) == 0) || (strcmp (argv[0], "1" ) == 0)) { val = CFRetain(kCFBooleanTrue); } else if ((strcasecmp(argv[0], "false") == 0) || (strcasecmp(argv[0], "f" ) == 0) || (strcasecmp(argv[0], "no" ) == 0) || (strcasecmp(argv[0], "n" ) == 0) || (strcmp (argv[0], "0" ) == 0)) { val = CFRetain(kCFBooleanFalse); } else { SCPrint(TRUE, stdout, CFSTR("d.add: invalid data.\n")); if (doArray) CFRelease(array); CFRelease(key); return; } } else if (doData) { uint8_t *bytes; CFMutableDataRef data; int i; int j; int n; n = strlen(argv[0]); if ((n % 2) == 1) { SCPrint(TRUE, stdout, CFSTR("d.add: not enough bytes.\n")); if (doArray) CFRelease(array); CFRelease(key); return; } data = CFDataCreateMutable(NULL, (n / 2)); CFDataSetLength(data, (n / 2)); bytes = (uint8_t *)CFDataGetBytePtr(data); for (i = 0, j = 0; i < n; i += 2, j++) { unsigned long byte; char *end; char str[3] = { 0 }; str[0] = argv[0][i]; str[1] = argv[0][i + 1]; errno = 0; byte = strtoul(str, &end, 16); if ((*end != '\0') || (errno != 0)) { CFRelease(data); data = NULL; break; } bytes[j] = byte; } if (data == NULL) { SCPrint(TRUE, stdout, CFSTR("d.add: invalid data.\n")); if (doArray) CFRelease(array); CFRelease(key); return; } val = data; } else if (doNumeric) { int intValue; if (sscanf(argv[0], "%d", &intValue) == 1) { val = CFNumberCreate(NULL, kCFNumberIntType, &intValue); } else { SCPrint(TRUE, stdout, CFSTR("d.add: invalid data.\n")); if (doArray) CFRelease(array); CFRelease(key); return; } } else { val = (CFPropertyListRef)CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); } if (doArray) { CFArrayAppendValue(array, val); CFRelease(val); argv++; argc--; } else { break; } } newValue = CFDictionaryCreateMutableCopy(NULL, 0, value); if (doArray) { CFDictionarySetValue(newValue, key, array); CFRelease(array); } else if (val != NULL) { CFDictionarySetValue(newValue, key, val); CFRelease(val); } CFRelease(key); CFRelease(value); value = newValue; return; }
KXKextManagerError PreLink(KXKextManagerRef theKextManager, CFDictionaryRef kextDict, const char * kernelCacheFilename, const char * kernel_file_name, const char * platform_name, const char * root_path, CFSetRef kernel_requests, Boolean all_plists, const NXArchInfo * arch, int verbose_level, Boolean debug_mode) { KXKextManagerError result = kKXKextManagerErrorFileAccess; CFIndex kexts_count, i; KXKextRef * kexts = NULL; // must free KXKextRef theKext = NULL; // don't release char symbol_dir[1 + strlen(TEMP_DIR)]; const char * temp_file = "cache.out"; int outfd = -1, curwd = -1; CFBundleRef kextBundle = NULL; // don't release CFMutableArrayRef moduleList; CFMutableDictionaryRef infoDict; vm_offset_t nextKernelVM; Boolean use_existing, kernel_swapped, includeInfo; vm_offset_t kernel_file, kernel_map; off_t kernel_size; vm_size_t kernel_file_size, bytes, totalBytes; vm_size_t totalModuleBytes, totalInfoBytes; vm_size_t totalSymbolBytes, totalSymbolSetBytes, totalSymbolDiscardedBytes; vm_size_t remainingModuleBytes, fileoffset, vmoffset, tailoffset; CFIndex idx, ncmds, cmd; IOReturn err; struct segment_command * seg; struct segment_command * prelinkseg; struct section * prelinksects; struct PrelinkState { kmod_info_t modules[1]; }; struct PrelinkState prelink_state_init; struct PrelinkState * prelink_state; vm_size_t prelink_size; int * prelink_dependencies; vm_size_t prelink_dependencies_size; kmod_info_t * lastInfo; struct FileInfo { vm_offset_t mapped; vm_size_t mappedSize; vm_offset_t symtaboffset; vm_offset_t symbolsetoffset; vm_size_t symtabsize; vm_size_t symtabdiscarded; CFStringRef key; KXKextRef kext; Boolean code; Boolean swapped; }; struct FileInfo * files = NULL; // -- symbol_dir[0] = 0; moduleList = CFArrayCreateMutable( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks ); if (kKXKextManagerErrorNone != (err = readFile(kernel_file_name, &kernel_file, &kernel_file_size))) goto finish; find_arch( (u_int8_t **) &kernel_map, &kernel_size, arch->cputype, arch->cpusubtype, (u_int8_t *) kernel_file, kernel_file_size); if (!kernel_size) { fprintf(stderr, "can't find architecture %s in %s\n", arch->name, kernel_file_name); err = kKXKextManagerErrorLinkLoad; goto finish; } if (arch->cputype != CPU_TYPE_ANY) kld_set_architecture(arch); kernel_swapped = kld_macho_swap((struct mach_header *)kernel_map); ncmds = ((struct mach_header *)kernel_map)->ncmds; seg = (struct segment_command *)(((struct mach_header *)kernel_map) + 1); for (cmd = 0; cmd < ncmds; cmd++, seg = (struct segment_command *)(((vm_offset_t)seg) + seg->cmdsize)) { if (LC_SEGMENT != seg->cmd) continue; if (strcmp("__PRELINK", seg->segname)) continue; break; } if (cmd >= ncmds) { fprintf(stderr, "no __PRELINK segment in %s\n", kernel_file_name); err = kKXKextManagerErrorLinkLoad; goto finish; } prelinkseg = seg; prelinksects = (struct section *) (prelinkseg + 1); if ((prelinkseg->nsects != 3) || (strcmp("__text", prelinksects[0].sectname)) || (strcmp("__symtab", prelinksects[1].sectname)) || (strcmp("__info", prelinksects[2].sectname))) { fprintf(stderr, "unexpected __PRELINK sections in %s\n", kernel_file_name); err = kKXKextManagerErrorLinkLoad; goto finish; } if (!prelinkseg->fileoff) prelinkseg->fileoff = prelinksects[0].offset; strcpy(symbol_dir, TEMP_DIR); mktemp(symbol_dir); if (0 != mkdir(symbol_dir, 0755)) { fprintf(stderr, "mkdir(%s) failed: %s\n", symbol_dir, strerror(errno)); symbol_dir[0] = 0; err = kKXKextManagerErrorFileAccess; goto finish; } curwd = open(".", O_RDONLY, 0); if (0 != chdir(symbol_dir)) { perror("chdir"); err = kKXKextManagerErrorFileAccess; goto finish; } use_existing = false; if (!use_existing) { int fd; bzero(&prelink_state_init, sizeof(prelink_state_init)); prelink_state_init.modules[0].address = prelinkseg->vmaddr; fd = open("prelinkstate", O_WRONLY|O_CREAT|O_TRUNC, 0755); if (-1 == fd) { perror("create prelinkstate failed"); err = kKXKextManagerErrorFileAccess; goto finish; } err = writeFile(fd, &prelink_state_init, sizeof(prelink_state_init)); close(fd); if (kKXKextManagerErrorNone != err) goto finish; } /* Prepare to iterate over the kexts in the dictionary. */ kexts_count = CFDictionaryGetCount(kextDict); kexts = (KXKextRef *) calloc(kexts_count, sizeof(KXKextRef)); if (!kexts) { fprintf(stderr, "memory allocation failure\n"); err = kKXKextManagerErrorNoMemory; goto finish; } CFDictionaryGetKeysAndValues(kextDict, (const void **)NULL, (const void **)kexts); for (i = 0; i < kexts_count; i++) { Boolean linkit; theKext = (KXKextRef) kexts[i]; linkit = KXKextGetDeclaresExecutable(theKext) && (kextBundle = KXKextGetBundle(theKext)); if (linkit && kernel_requests) { CFStringRef bundleIdentifier = CFBundleGetIdentifier(kextBundle); linkit = (bundleIdentifier && CFSetContainsValue(kernel_requests, bundleIdentifier)); } if (linkit) { result = _KXKextManagerPrepareKextForLoading( theKextManager, theKext, NULL /*kext_name*/, FALSE /*check_loaded_for_dependencies*/, FALSE /*do_load*/, NULL /*inauthenticKexts*/); if (!use_existing && (result == kKXKextManagerErrorNone)) { result = _KXKextManagerLoadKextUsingOptions( theKextManager, theKext, NULL /*kext_name*/, kernel_file_name, NULL /*patch_dir*/, symbol_dir, kKXKextManagerLoadPrelink /*load_options*/, FALSE /*do_start_kmod*/, 0 /*interactive_level*/, FALSE /*ask_overwrite_symbols*/, FALSE /*overwrite_symbols*/, FALSE /*get_addrs_from_kernel*/, 0 /*num_addresses*/, NULL /*addresses*/); } if ((result != kKXKextManagerErrorNone) && (verbose_level > 0)) { const char * kext_path = NULL; // must free kext_path = _KXKextCopyCanonicalPathnameAsCString(theKext); if (kext_path) { fprintf(stderr, kext_path); free((char *)kext_path); } fprintf(stderr, " error 0x%x\n", result); } } } { struct module_header { struct mach_header h; struct segment_command seg[1]; }; struct module_header * header; int num_modules; if (kKXKextManagerErrorNone != (err = readFile("prelinkstate", (vm_offset_t *) &prelink_state, &prelink_size))) goto finish; if (kKXKextManagerErrorNone != (err = readFile("prelinkdependencies", (vm_offset_t *) &prelink_dependencies, &prelink_dependencies_size))) goto finish; num_modules = prelink_state->modules[0].id; nextKernelVM = prelink_state->modules[0].address; if (!num_modules || (prelink_size < ((num_modules + 1) * sizeof(kmod_info_t)))) { fprintf(stderr, "read prelinkstate failed\n"); err = kKXKextManagerErrorFileAccess; goto finish; } if (verbose_level > 0) { verbose_log("%d modules - code VM 0x%lx - 0x%x (0x%lx, %.2f Mb)", num_modules, prelinkseg->vmaddr, nextKernelVM, nextKernelVM - prelinkseg->vmaddr, ((float)(nextKernelVM - prelinkseg->vmaddr)) / 1024.0 / 1024.0 ); } // map files, get sizes files = (struct FileInfo *) calloc(num_modules, sizeof(struct FileInfo)); totalModuleBytes = 0; for (idx = 0; idx < num_modules; idx++) { files[idx].key = CFStringCreateWithCString(kCFAllocatorDefault, prelink_state->modules[1+idx].name, kCFStringEncodingMacRoman); files[idx].kext = KXKextManagerGetKextWithIdentifier(theKextManager, files[idx].key); if (!prelink_state->modules[1+idx].size) continue; if (kKXKextManagerErrorNone != (err = readFile(prelink_state->modules[1+idx].name, &files[idx].mapped, &files[idx].mappedSize))) goto finish; header = (struct module_header *) files[idx].mapped; files[idx].swapped = kld_macho_swap(&header->h); files[idx].code = (LC_SEGMENT == header->seg[0].cmd); if (files[idx].code) totalModuleBytes += header->seg[0].vmaddr + round_page(header->seg[0].vmsize) - prelink_state->modules[1+idx].address; } totalSymbolBytes = 0; totalSymbolDiscardedBytes = 0; totalSymbolSetBytes = 0; remainingModuleBytes = totalModuleBytes; // create prelinked kernel file outfd = open("mach_kernel.prelink", O_WRONLY|O_CREAT|O_TRUNC, 0666); if (-1 == outfd) { fprintf(stderr, "can't create %s: %s\n", "mach_kernel.prelink", strerror(errno)); err = kKXKextManagerErrorFileAccess; goto finish; } // start writing at the prelink segs file offset if (-1 == lseek(outfd, prelinkseg->fileoff, SEEK_SET)) { perror("couldn't write output"); err = kKXKextManagerErrorFileAccess; goto finish; } for (idx = 0, lastInfo = NULL; idx < num_modules; idx++) { kmod_info_t * info; unsigned long modcmd; struct symtab_command * symcmd; struct section * sect; vm_size_t headerOffset; if (!files[idx].code && prelink_state->modules[1+idx].size) { // for symbol sets the whole file ends up in the symbol sect files[idx].symtaboffset = 0; files[idx].symtabsize = prelink_state->modules[1+idx].size; files[idx].symbolsetoffset = totalSymbolBytes; totalSymbolBytes += files[idx].symtabsize; totalSymbolSetBytes += files[idx].symtabsize; continue; } header = (struct module_header *) files[idx].mapped; // patch kmod_info info = (kmod_info_t *) (prelink_state->modules[1+idx].id - header->seg[0].vmaddr + header->seg[0].fileoff + files[idx].mapped); info->next = lastInfo; lastInfo = info; bcopy(prelink_state->modules[1+idx].name, info->name, sizeof(info->name)); bcopy(prelink_state->modules[1+idx].version, info->version, sizeof(info->version)); info->address = prelink_state->modules[1+idx].address; info->size = prelink_state->modules[1+idx].size; info->id = prelink_state->modules[1+idx].id; info->hdr_size = header->seg[0].vmaddr - prelink_state->modules[1+idx].address; // patch offsets // how far back the header moves headerOffset = info->hdr_size - header->seg[0].fileoff; header->seg[0].fileoff += headerOffset; header->seg[0].filesize += headerOffset; // module code size tailoffset = round_page(header->seg[0].vmsize) + info->hdr_size - headerOffset; for (modcmd = 0, sect = (struct section *) &header->seg[1]; modcmd < header->seg[0].nsects; modcmd++, sect++) sect->offset += headerOffset; for (modcmd = 0, seg = &header->seg[0]; (modcmd < header->h.ncmds) && (LC_SYMTAB != seg->cmd); modcmd++, seg = (struct segment_command *)(((vm_offset_t)seg) + seg->cmdsize)) {} if (modcmd >= header->h.ncmds) { fprintf(stderr, "No LC_SYMTAB in %s\n", prelink_state->modules[1+idx].name); err = kKXKextManagerErrorLinkLoad; goto finish; } symcmd = (struct symtab_command *) seg; theKext = files[idx].kext; if (false && theKext && (kextBundle = KXKextGetBundle(theKext)) && CFBundleGetValueForInfoDictionaryKey(kextBundle, CFSTR("OSBundleCompatibleVersion"))) { // keeping symbols for this module struct nlist * sym; long align, lastUsedOffset = 0; const char * lastUsedString; unsigned int strIdx; files[idx].symtaboffset = symcmd->symoff; files[idx].symtabsize = symcmd->nsyms * sizeof(struct nlist); // .. but just the external strings sym = (struct nlist *) (symcmd->symoff + files[idx].mapped); for(strIdx = 0; strIdx < symcmd->nsyms; strIdx++, sym++) { if (!lastUsedOffset) lastUsedOffset = sym->n_un.n_strx; else if (!(sym->n_type & N_EXT)) sym->n_un.n_strx = 0; else if (sym->n_un.n_strx > lastUsedOffset) lastUsedOffset = sym->n_un.n_strx; } lastUsedString = (const char *) (symcmd->stroff + lastUsedOffset + files[idx].mapped); lastUsedOffset += (1 + strlen(lastUsedString)); align = lastUsedOffset % sizeof(long); if (align) { align = sizeof(long) - align; bzero((void *) (symcmd->stroff + lastUsedOffset + files[idx].mapped), align); lastUsedOffset += align; } files[idx].symtabsize += lastUsedOffset; files[idx].symtabdiscarded = symcmd->strsize - lastUsedOffset; symcmd->strsize = lastUsedOffset; // unswap symbols kld_macho_unswap(&header->h, files[idx].swapped, 1); // patch offset to symbols // how far ahead the symtab moves bytes = remainingModuleBytes + totalSymbolBytes; symcmd->symoff = bytes; symcmd->stroff += bytes - files[idx].symtaboffset; totalSymbolBytes += files[idx].symtabsize; totalSymbolDiscardedBytes += files[idx].symtabdiscarded; } else { // ditching symbols for this module files[idx].symtaboffset = 0; files[idx].symtabsize = 0; symcmd->nsyms = 0; symcmd->symoff = 0; symcmd->stroff = 0; } remainingModuleBytes -= prelink_state->modules[1+idx].size; // unswap rest of module if (files[idx].swapped) { info->next = (void *) NXSwapLong((long) info->next); info->address = NXSwapLong(info->address); info->size = NXSwapLong(info->size); info->hdr_size = NXSwapLong(info->hdr_size); info->id = NXSwapLong(info->id); } kld_macho_unswap(&header->h, files[idx].swapped, -1); files[idx].swapped = false; header = 0; info = 0; // copy header to start of VM allocation if (kKXKextManagerErrorNone != (err = writeFile(outfd, (const void *) files[idx].mapped, headerOffset))) goto finish; // write the module if (kKXKextManagerErrorNone != (err = writeFile(outfd, (const void *) files[idx].mapped, tailoffset ))) goto finish; } // write the symtabs, get info, unmap for (idx = 0; idx < num_modules; idx++) { bytes = files[idx].symtabsize; if (bytes && prelink_state->modules[1+idx].size) { if (files[idx].mappedSize < (files[idx].symtaboffset + bytes)) { fprintf(stderr, "%s is truncated\n", prelink_state->modules[1+idx].name); result = kKXKextManagerErrorFileAccess; goto finish; } else if (files[idx].mappedSize > (files[idx].symtaboffset + bytes + files[idx].symtabdiscarded)) fprintf(stderr, "%s has extra data\n", prelink_state->modules[1+idx].name); // write symtab if (kKXKextManagerErrorNone != (err = writeFile(outfd, (const void *) files[idx].mapped + files[idx].symtaboffset, bytes))) goto finish; } // unmap file if (files[idx].mappedSize) { vm_deallocate(mach_task_self(), files[idx].mapped, files[idx].mappedSize); files[idx].mapped = 0; files[idx].mappedSize = 0; } // make info dict theKext = files[idx].kext; infoDict = NULL; includeInfo = (theKext && (kextBundle = KXKextGetBundle(theKext))); if (includeInfo && !all_plists) { CFStringRef str; // check OSBundleRequired to see if safe for boot time matching str = CFBundleGetValueForInfoDictionaryKey(kextBundle, CFSTR("OSBundleRequired")); includeInfo = (str && (kCFCompareEqualTo != CFStringCompare(str, CFSTR("Safe Boot"), 0))); } if (includeInfo) infoDict = copyInfoDict(kextBundle); if (!infoDict) { if (debug_mode > 0) { verbose_log("skip info for %s", prelink_state->modules[1+idx].name); } infoDict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(infoDict, CFSTR("CFBundleIdentifier"), files[idx].key); } CFRelease(files[idx].key); files[idx].key = 0; if (prelink_state->modules[1+idx].address) { CFMutableDataRef data; enum { kPrelinkReservedCount = 4 }; UInt32 prelinkInfo[kPrelinkReservedCount]; prelinkInfo[0] = NXSwapHostIntToBig(prelink_state->modules[1+idx].id); prelinkInfo[1] = NXSwapHostIntToBig(0); prelinkInfo[2] = NXSwapHostIntToBig(sizeof(prelinkInfo)); prelinkInfo[3] = NXSwapHostIntToBig( prelink_state->modules[1+idx].reference_count * sizeof(UInt32) + sizeof(prelinkInfo)); data = CFDataCreateMutable(kCFAllocatorDefault, 0); CFDataAppendBytes( data, (const UInt8 *) prelinkInfo, sizeof(prelinkInfo) ); if (prelink_state->modules[1+idx].reference_count) { CFIndex start = (CFIndex) prelink_state->modules[1+idx].reference_list; CFDataAppendBytes( data, (const UInt8 *) &prelink_dependencies[start], prelink_state->modules[1+idx].reference_count * sizeof(CFIndex) ); } CFDictionarySetValue(infoDict, CFSTR("OSBundlePrelink"), data); CFRelease(data); } else if (files[idx].symtabsize) { CFNumberRef num; num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, (const void *) &files[idx].symbolsetoffset); CFDictionarySetValue(infoDict, CFSTR("OSBundlePrelinkSymbols"), num); CFRelease(num); } CFArrayAppendValue(moduleList, infoDict); CFRelease(infoDict); } bytes = round_page(totalSymbolBytes) - totalSymbolBytes; totalSymbolBytes += bytes; if (-1 == lseek(outfd, bytes, SEEK_CUR)) { perror("couldn't write output"); err = kKXKextManagerErrorFileAccess; goto finish; } // deferred load __info if (!all_plists) for (i = 0; i < kexts_count; i++) { theKext = (KXKextRef) kexts[i]; for (idx = 0; (idx < num_modules) && (theKext != files[idx].kext); idx++) {} if (idx < num_modules) continue; includeInfo = (theKext && (kextBundle = KXKextGetBundle(theKext))); if (includeInfo) { CFStringRef str; // check OSBundleRequired to see if safe for boot time matching str = CFBundleGetValueForInfoDictionaryKey(kextBundle, CFSTR("OSBundleRequired")); includeInfo = (str && (kCFCompareEqualTo != CFStringCompare(str, CFSTR("Safe Boot"), 0))); if (includeInfo) { infoDict = copyInfoDict(kextBundle); if (infoDict) { CFDictionarySetValue(infoDict, CFSTR("OSBundleDefer"), kCFBooleanTrue); CFArrayAppendValue(moduleList, infoDict); CFRelease(infoDict); } } } } // write __info { CFDataRef data; data = IOCFSerialize(moduleList, kNilOptions); if (!data) { fprintf(stderr, "couldn't serialize property lists\n"); err = kKXKextManagerErrorSerialization; goto finish; } totalInfoBytes = round_page(CFDataGetLength(data)); if (kKXKextManagerErrorNone != (err = writeFile(outfd, CFDataGetBytePtr(data), CFDataGetLength(data)))) goto finish; if (-1 == lseek(outfd, totalInfoBytes - CFDataGetLength(data), SEEK_CUR)) { perror("couldn't write output"); err = kKXKextManagerErrorFileAccess; goto finish; } CFRelease(data); } totalBytes = totalModuleBytes + totalSymbolBytes + totalInfoBytes; if (verbose_level > 0) { verbose_log("added 0x%x bytes %.2f Mb (code 0x%x + symbol 0x%x + sets 0x%x - strings 0x%x + info 0x%x)", totalBytes, ((float) totalBytes) / 1024.0 / 1024.0, totalModuleBytes, totalSymbolBytes, totalSymbolSetBytes, totalSymbolDiscardedBytes, totalInfoBytes); } fileoffset = totalBytes - prelinkseg->filesize; vmoffset = totalBytes - round_page(prelinkseg->filesize); // unswap kernel symbols kld_macho_unswap((struct mach_header *)kernel_map, kernel_swapped, 1); // write tail of base kernel tailoffset = prelinkseg->fileoff + prelinkseg->filesize; if (kKXKextManagerErrorNone != (err = writeFile(outfd, (const void *) (kernel_map + tailoffset), kernel_size - tailoffset))) goto finish; // patch prelink sects sizes and offsets prelinkseg->vmsize = totalBytes; prelinkseg->filesize = totalBytes; prelinksects[0].size = totalModuleBytes; prelinksects[1].addr = prelinksects[0].addr + totalModuleBytes; prelinksects[1].size = totalSymbolBytes; prelinksects[1].offset = prelinksects[0].offset + totalModuleBytes; prelinksects[2].addr = prelinksects[1].addr + totalSymbolBytes; prelinksects[2].size = totalInfoBytes; prelinksects[2].offset = prelinksects[1].offset + totalSymbolBytes; // patch following segs address & offsets seg = prelinkseg; for (; cmd < ncmds; cmd++) { seg = (struct segment_command *)(((vm_offset_t)seg) + seg->cmdsize); if (LC_SYMTAB == seg->cmd) { ((struct symtab_command *)seg)->symoff += fileoffset; ((struct symtab_command *)seg)->stroff += fileoffset; } else if (LC_SEGMENT == seg->cmd) { seg->fileoff += fileoffset; seg->vmaddr += vmoffset; } } bytes = prelinkseg->fileoff; // unswap kernel headers kld_macho_unswap((struct mach_header *)kernel_map, kernel_swapped, -1); kernel_swapped = false; prelinkseg = 0; // write head of base kernel, & free it if (-1 == lseek(outfd, 0, SEEK_SET)) { perror("couldn't write output"); err = kKXKextManagerErrorFileAccess; goto finish; } if (kKXKextManagerErrorNone != (err = writeFile(outfd, (const void *) kernel_map, bytes))) goto finish; close(outfd); outfd = -1; vm_deallocate( mach_task_self(), kernel_file, kernel_file_size ); kernel_file = 0; kernel_map = 0; } // compresss { char * buf; char * bufend; vm_size_t bufsize; struct { uint32_t signature; uint32_t compress_type; uint32_t adler32; vm_size_t uncompressed_size; vm_size_t compressed_size; uint32_t reserved[11]; char platform_name[64]; char root_path[256]; char data[0]; } kernel_header = { 0 }; if (kKXKextManagerErrorNone != (err = readFile("mach_kernel.prelink", &kernel_file, &kernel_file_size))) goto finish; bufsize = kernel_file_size; buf = malloc(bufsize); kernel_header.signature = NXSwapHostIntToBig('comp'); kernel_header.compress_type = NXSwapHostIntToBig('lzss'); kernel_header.adler32 = NXSwapHostIntToBig(local_adler32( (u_int8_t *) kernel_file, kernel_file_size)); kernel_header.uncompressed_size = NXSwapHostIntToBig(kernel_file_size); strcpy(kernel_header.platform_name, platform_name); strcpy(kernel_header.root_path, root_path); if (verbose_level > 0) verbose_log("adler32 0x%08x, compressing...", NXSwapBigIntToHost(kernel_header.adler32)); bufend = compress_lzss(buf, bufsize, (u_int8_t *) kernel_file, kernel_file_size); totalBytes = bufend - buf; kernel_header.compressed_size = NXSwapHostIntToBig(totalBytes); if (verbose_level > 0) verbose_log("final size 0x%x bytes %.2f Mb", totalBytes, ((float) totalBytes) / 1024.0 / 1024.0); vm_deallocate( mach_task_self(), kernel_file, kernel_file_size ); outfd = open(temp_file, O_WRONLY|O_CREAT|O_TRUNC, 0666); if (-1 == outfd) { fprintf(stderr, "can't create %s - %s\n", temp_file, strerror(errno)); err = kKXKextManagerErrorFileAccess; goto finish; } // write header if (kKXKextManagerErrorNone != (err = writeFile(outfd, &kernel_header, sizeof(kernel_header)))) goto finish; // write compressed data if (kKXKextManagerErrorNone != (err = writeFile(outfd, buf, bufend - buf))) goto finish; close(outfd); outfd = -1; } // move it to the final destination if (-1 == rename(temp_file, kernelCacheFilename)) { fprintf(stderr, "can't create file %s: %s\n", kernelCacheFilename, strerror(errno)); err = kKXKextManagerErrorFileAccess; goto finish; } if (verbose_level > 0) verbose_log("created cache: %s", kernelCacheFilename); result = kKXKextManagerErrorNone; finish: if (-1 != outfd) close(outfd); if (debug_mode) symbol_dir[0] = 0; if (symbol_dir[0]) { FTS * fts; FTSENT * fts_entry; char * paths[2]; paths[0] = symbol_dir; paths[1] = 0; fts = fts_open(paths, FTS_NOCHDIR, NULL); if (fts) { while ((fts_entry = fts_read(fts))) { if (fts_entry->fts_errno) continue; if (FTS_F != fts_entry->fts_info) continue; if (-1 == unlink(fts_entry->fts_path)) fprintf(stderr, "can't remove file %s: %s\n", fts_entry->fts_path, strerror(errno)); } fts_close(fts); } } if (-1 != curwd) fchdir(curwd); if (symbol_dir[0] && (-1 == rmdir(symbol_dir))) perror("rmdir"); if (kexts) free(kexts); if (files) free(files); return result; }
static void sendMessages(int howMany, SecOTRSessionRef *bobSession, SecOTRSessionRef *aliceSession, bool serialize) { for(int count = howMany; count > 0; --count) { const char* aliceToBob = "aliceToBob"; CFDataRef rawAliceToBob = CFDataCreate(kCFAllocatorDefault, (const uint8_t*)aliceToBob, (CFIndex) strlen(aliceToBob)); CFMutableDataRef protectedAliceToBob = CFDataCreateMutable(kCFAllocatorDefault, 0); CFMutableDataRef bobDecode = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSSignAndProtectMessage(*aliceSession, rawAliceToBob, protectedAliceToBob), "encode message"); ok_status(SecOTRSVerifyAndExposeMessage(*bobSession, protectedAliceToBob, bobDecode), "Decode message"); if (serialize) { serializeAndDeserialize(bobSession); serializeAndDeserialize(aliceSession); } ok(CFDataGetLength(rawAliceToBob) == CFDataGetLength(bobDecode) && 0 == memcmp(CFDataGetBytePtr(rawAliceToBob), CFDataGetBytePtr(bobDecode), (size_t)CFDataGetLength(rawAliceToBob)), "Didn't match!"); CFReleaseNull(rawAliceToBob); CFReleaseNull(protectedAliceToBob); CFReleaseNull(bobDecode); const char* bobToAlice = "i liked your silly message from me to you"; CFDataRef rawBobToAlice = CFDataCreate(kCFAllocatorDefault, (const uint8_t*)bobToAlice, (CFIndex) strlen(bobToAlice)); CFMutableDataRef protectedBobToAlice = CFDataCreateMutable(kCFAllocatorDefault, 0); CFMutableDataRef aliceDecode = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSSignAndProtectMessage(*aliceSession, rawBobToAlice, protectedBobToAlice), "encode reply"); ok_status(SecOTRSVerifyAndExposeMessage(*bobSession, protectedBobToAlice, aliceDecode), "decode reply"); if (serialize) { serializeAndDeserialize(bobSession); serializeAndDeserialize(aliceSession); } ok(CFDataGetLength(rawBobToAlice) == CFDataGetLength(aliceDecode) && 0 == memcmp(CFDataGetBytePtr(rawBobToAlice), CFDataGetBytePtr(aliceDecode), (size_t)CFDataGetLength(rawBobToAlice)), "reply matched"); CFReleaseNull(rawAliceToBob); CFReleaseNull(rawBobToAlice); CFReleaseNull(protectedBobToAlice); CFReleaseNull(protectedAliceToBob); CFReleaseNull(aliceDecode); rawAliceToBob = CFDataCreate(kCFAllocatorDefault, (const uint8_t*)aliceToBob, (CFIndex) strlen(aliceToBob)); protectedAliceToBob = CFDataCreateMutable(kCFAllocatorDefault, 0); bobDecode = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSSignAndProtectMessage(*aliceSession, rawAliceToBob, protectedAliceToBob), "encode message"); ok_status(SecOTRSVerifyAndExposeMessage(*bobSession, protectedAliceToBob, bobDecode), "Decode message"); if (serialize) { serializeAndDeserialize(bobSession); serializeAndDeserialize(aliceSession); } ok(CFDataGetLength(rawAliceToBob) == CFDataGetLength(bobDecode) && 0 == memcmp(CFDataGetBytePtr(rawAliceToBob), CFDataGetBytePtr(bobDecode), (size_t)CFDataGetLength(rawAliceToBob)), "Didn't match!"); CFReleaseNull(rawAliceToBob); CFReleaseNull(protectedAliceToBob); CFReleaseNull(bobDecode); bobToAlice = "i liked your silly message from me to you"; rawBobToAlice = CFDataCreate(kCFAllocatorDefault, (const uint8_t*)bobToAlice, (CFIndex) strlen(bobToAlice)); protectedBobToAlice = CFDataCreateMutable(kCFAllocatorDefault, 0); aliceDecode = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSSignAndProtectMessage(*aliceSession, rawBobToAlice, protectedBobToAlice), "encode reply"); ok_status(SecOTRSVerifyAndExposeMessage(*bobSession, protectedBobToAlice, aliceDecode), "decode reply"); if (serialize) { serializeAndDeserialize(bobSession); serializeAndDeserialize(aliceSession); } ok(CFDataGetLength(rawBobToAlice) == CFDataGetLength(aliceDecode) && 0 == memcmp(CFDataGetBytePtr(rawBobToAlice), CFDataGetBytePtr(aliceDecode), (size_t)CFDataGetLength(rawBobToAlice)), "reply matched"); CFReleaseNull(rawAliceToBob); CFReleaseNull(rawBobToAlice); CFReleaseNull(protectedBobToAlice); CFReleaseNull(protectedAliceToBob); CFReleaseNull(aliceDecode); CFStringRef stateString = CFCopyDescription(*bobSession); ok(stateString, "getting state from bob"); CFReleaseNull(stateString); stateString = CFCopyDescription(*aliceSession); ok(stateString, "getting state from alice"); CFReleaseNull(stateString); } }
static void negotiate(SecOTRSessionRef* aliceSession, SecOTRSessionRef* bobSession, bool serializeNegotiating, bool serializeMessaging, bool textMode, bool compact) { const int kEmptyMessageSize = textMode ? 6 : 0; // Step 1: Create a start packet for each side of the transaction CFMutableDataRef bobStartPacket = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSAppendStartPacket(*bobSession, bobStartPacket), "Bob start packet"); if (serializeNegotiating) serializeAndDeserialize(bobSession); CFMutableDataRef aliceStartPacket = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSAppendStartPacket(*aliceSession, aliceStartPacket), "Alice start packet"); if (serializeNegotiating) serializeAndDeserialize(aliceSession); // Step 2: Exchange the start packets, forcing the DH commit messages to collide CFMutableDataRef aliceDHKeyResponse = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSProcessPacket(*aliceSession, bobStartPacket, aliceDHKeyResponse), "Bob DH packet failed"); if (serializeNegotiating) serializeAndDeserialize(aliceSession); CFReleaseNull(bobStartPacket); CFMutableDataRef bobDHKeyResponse = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSProcessPacket(*bobSession, aliceStartPacket, bobDHKeyResponse), "Alice DH packet failed"); if (serializeNegotiating) serializeAndDeserialize(bobSession); CFReleaseNull(aliceStartPacket); // Step 3: With one "real" DH key message, and one replayed DH commit message, try to get a "reveal sig" out of one side CFMutableDataRef bobRevealSigResponse = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSProcessPacket(*bobSession, aliceDHKeyResponse, bobRevealSigResponse), "Alice DH Key packet failed"); if (serializeNegotiating) serializeAndDeserialize(bobSession); CFReleaseNull(aliceDHKeyResponse); CFMutableDataRef aliceRevealSigResponse = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSProcessPacket(*aliceSession, bobDHKeyResponse, aliceRevealSigResponse), "Bob DH Key packet failed"); if (serializeNegotiating) serializeAndDeserialize(aliceSession); CFReleaseNull(bobDHKeyResponse); // Step 4: Having gotten the reveal signature, now work for the signature CFMutableDataRef aliceSigResponse = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSProcessPacket(*aliceSession, bobRevealSigResponse, aliceSigResponse), "Bob Reveal sig failed"); if (serializeNegotiating) serializeAndDeserialize(aliceSession); CFReleaseNull(bobRevealSigResponse); CFMutableDataRef bobSigResponse = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSProcessPacket(*bobSession, aliceRevealSigResponse, bobSigResponse), "Alice Reveal sig failed"); if (serializeNegotiating) serializeAndDeserialize(bobSession); CFReleaseNull(aliceRevealSigResponse); // Step 5: All the messages have been sent, now deal with any replays from the collision handling CFMutableDataRef bobFinalResponse = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSProcessPacket(*bobSession, aliceSigResponse, bobFinalResponse), "Alice Final Sig failed"); if (serializeNegotiating) serializeAndDeserialize(bobSession); CFMutableDataRef aliceFinalResponse = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSProcessPacket(*aliceSession, bobSigResponse, aliceFinalResponse), "Bob Final Sig failed"); is(kEmptyMessageSize, CFDataGetLength(aliceFinalResponse), "Alice had nothing left to say"); CFReleaseNull(aliceFinalResponse); CFReleaseNull(bobSigResponse); if (serializeNegotiating) serializeAndDeserialize(aliceSession); is(kEmptyMessageSize, CFDataGetLength(bobFinalResponse), "Bob had nothing left to say"); ok(SecOTRSGetIsReadyForMessages(*bobSession), "Bob is ready"); ok(SecOTRSGetIsReadyForMessages(*aliceSession), "Alice is ready"); CFReleaseNull(aliceSigResponse); CFReleaseNull(bobFinalResponse); sendMessages(5, bobSession, aliceSession, serializeMessaging); const char* aliceToBob = "deferredMessage"; CFDataRef rawAliceToBob = CFDataCreate(kCFAllocatorDefault, (const uint8_t*)aliceToBob, (CFIndex) strlen(aliceToBob)); CFMutableDataRef protectedAliceToBob = CFDataCreateMutable(kCFAllocatorDefault, 0); CFMutableDataRef bobDecode = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecOTRSSignAndProtectMessage(*aliceSession, rawAliceToBob, protectedAliceToBob), "encode message"); sendMessages(1, bobSession, aliceSession, serializeMessaging); is(SecOTRSVerifyAndExposeMessage(*bobSession, protectedAliceToBob, bobDecode), errSecOTRTooOld, "Decode old message"); sendMessages(1, bobSession, aliceSession, serializeMessaging); is(SecOTRSVerifyAndExposeMessage(*bobSession, protectedAliceToBob, bobDecode), errSecOTRTooOld, "Decode excessively old message"); sendMessages(3, bobSession, aliceSession, serializeMessaging); CFReleaseNull(rawAliceToBob); CFReleaseNull(protectedAliceToBob); CFReleaseNull(bobDecode); }
CFDataRef TSystemUtils::ReadDataFromURL ( CFURLRef url ) { CFMutableDataRef data = NULL; Boolean result = false; CFNumberRef fileSizeNumber = NULL; CFIndex fileSize = 0; UInt8 * dataPtr = NULL; UInt8 * endPtr = NULL; CFReadStreamRef readStream = NULL; CFIndex bytesRead = 0; result = CFURLCopyResourcePropertyForKey ( url, kCFURLFileSizeKey, &fileSizeNumber, NULL ); require ( result, ErrorExit ); result = CFNumberGetValue ( fileSizeNumber, kCFNumberCFIndexType, &fileSize ); require ( result, ReleaseNumber ); data = CFDataCreateMutable ( kCFAllocatorDefault, fileSize ); require ( data, ReleaseNumber ); CFDataSetLength ( data, fileSize ); dataPtr = CFDataGetMutableBytePtr ( data ); require ( dataPtr, ReleaseNumber ); readStream = CFReadStreamCreateWithFile ( kCFAllocatorDefault, url ); require ( readStream, ErrorExit ); result = CFReadStreamOpen ( readStream ); require ( result, ReleaseStream ); endPtr = ( UInt8 * ) dataPtr + fileSize; while ( dataPtr < endPtr ) { bytesRead = CFReadStreamRead ( readStream, dataPtr, endPtr - dataPtr ); if ( bytesRead > 0 ) { dataPtr += bytesRead; } } CFReadStreamClose ( readStream ); ReleaseStream: CFRelease ( readStream ); readStream = NULL; ReleaseNumber: CFRelease ( fileSizeNumber ); fileSizeNumber = NULL; ErrorExit: return data; }
static void tests(void) { CFErrorRef testError = NULL; SecOTRFullIdentityRef idToPurge = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError); RegressionsLogError(testError); CFReleaseNull(testError); ok(idToPurge != NULL, "Make Identity"); CFMutableDataRef purgeExport = CFDataCreateMutable(kCFAllocatorDefault, 0); ok(SecOTRFIAppendSerialization(idToPurge, purgeExport, &testError), "First export"); RegressionsLogError(testError); CFReleaseNull(testError); SecOTRFullIdentityRef purgeIdInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError); RegressionsLogError(testError); CFReleaseNull(testError); ok(purgeIdInflate != NULL, "Inflate Identity"); SecOTRFIPurgeFromKeychain(idToPurge, &testError); RegressionsLogError(testError); CFReleaseNull(testError); SecOTRFullIdentityRef failIDInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError); RegressionsLogError(testError); CFReleaseNull(testError); ok(failIDInflate == NULL, "Should fail"); CFReleaseSafe(idToPurge); idToPurge = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError); RegressionsLogError(testError); CFReleaseNull(testError); ok(idToPurge != NULL, "Make Identity again"); SecOTRFIPurgeAllFromKeychain(&testError); RegressionsLogError(testError); CFReleaseNull(testError); SecOTRFullIdentityRef failIDInflate2 = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError); RegressionsLogError(testError); CFReleaseNull(testError); ok(failIDInflate2 == NULL, "Should fail 2"); SecOTRFullIdentityRef id = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError); RegressionsLogError(testError); CFReleaseNull(testError); ok(id != NULL, "Make Identity"); CFMutableDataRef firstExport = CFDataCreateMutable(kCFAllocatorDefault, 0); ok(SecOTRFIAppendSerialization(id, firstExport, &testError), "First export"); RegressionsLogError(testError); CFReleaseNull(testError); SecOTRFullIdentityRef idInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, firstExport, &testError); RegressionsLogError(testError); CFReleaseNull(testError); ok(idInflate != NULL, "Inflate Identity"); CFMutableDataRef secondExport = CFDataCreateMutable(kCFAllocatorDefault, 0); ok(SecOTRFIAppendSerialization(idInflate, secondExport, &testError), "second export"); RegressionsLogError(testError); CFReleaseNull(testError); ok(CFDataGetLength(firstExport) == CFDataGetLength(secondExport) && 0 == memcmp(CFDataGetBytePtr(firstExport), CFDataGetBytePtr(secondExport), (size_t)CFDataGetLength(firstExport)), "Different exports"); SecOTRPublicIdentityRef pubID = SecOTRPublicIdentityCopyFromPrivate(kCFAllocatorDefault, id, &testError); RegressionsLogError(testError); CFReleaseNull(testError); ok(id != NULL, "Failed to copy public identity"); CFMutableDataRef firstPublicExport = CFDataCreateMutable(kCFAllocatorDefault, 0); ok(SecOTRPIAppendSerialization(pubID, firstPublicExport, &testError), "failed first public export"); RegressionsLogError(testError); CFReleaseNull(testError); SecOTRPublicIdentityRef pubIDInflate = SecOTRPublicIdentityCreateFromData(kCFAllocatorDefault, firstPublicExport, &testError); RegressionsLogError(testError); CFReleaseNull(testError); ok(pubIDInflate != NULL, "Pub inflate failed"); CFMutableDataRef secondPublicExport = CFDataCreateMutable(kCFAllocatorDefault, 0); ok(SecOTRPIAppendSerialization(pubID, secondPublicExport, &testError), "failed second public export"); RegressionsLogError(testError); CFReleaseNull(testError); ok(CFDataGetLength(firstPublicExport) == CFDataGetLength(secondPublicExport) && 0 == memcmp(CFDataGetBytePtr(firstPublicExport), CFDataGetBytePtr(secondPublicExport), (size_t)CFDataGetLength(firstPublicExport)), "Different public exports"); uint8_t sampleByteString[] = { 0x30, 0x81, 0xf6, 0x81, 0x43, 0x00, 0x41, 0x04, 0xc6, 0x8a, 0x2a, 0x5c, 0x29, 0xa4, 0xb7, 0x58, 0xe1, 0x3c, 0x07, 0x19, 0x20, 0xf3, 0x0b, 0xb8, 0xb3, 0x40, 0x41, 0x29, 0x4a, 0xa6, 0x7a, 0x56, 0x28, 0x6d, 0x10, 0x85, 0x2b, 0x14, 0x83, 0xaa, 0x1f, 0x6a, 0x47, 0xbc, 0x19, 0x26, 0x39, 0x1c, 0xd4, 0xbb, 0x8c, 0xd6, 0x94, 0x24, 0x79, 0x60, 0xfb, 0x8e, 0x4b, 0xf4, 0x0f, 0xbf, 0x38, 0x81, 0x78, 0xce, 0x1d, 0xd9, 0x03, 0xec, 0x65, 0xcd, 0x82, 0x81, 0xae, 0x00, 0xac, 0x30, 0x81, 0xa9, 0x02, 0x81, 0xa1, 0x00, 0xd2, 0xf4, 0x40, 0x8b, 0x2f, 0x09, 0x75, 0x2c, 0x68, 0x12, 0x76, 0xb9, 0xfb, 0x1b, 0x02, 0x91, 0x6d, 0xd7, 0x86, 0x49, 0xdc, 0xef, 0x38, 0xf3, 0x50, 0x58, 0xb5, 0xff, 0x5c, 0x02, 0x8a, 0xb0, 0xcd, 0xb3, 0x3d, 0x94, 0x71, 0x7d, 0x32, 0x53, 0xed, 0x43, 0xfb, 0xde, 0xbc, 0x20, 0x21, 0x33, 0xe3, 0xeb, 0x93, 0x48, 0xe8, 0xd1, 0x32, 0x2f, 0x40, 0x40, 0x47, 0x1f, 0xeb, 0x7e, 0xf6, 0x43, 0x81, 0x51, 0xd6, 0x4f, 0xe0, 0x57, 0xbf, 0x12, 0xeb, 0x18, 0x2e, 0x81, 0x0b, 0x3a, 0x04, 0xf1, 0xeb, 0x3c, 0xe1, 0xb9, 0xf4, 0x87, 0x37, 0x83, 0x5a, 0x2e, 0x09, 0xf8, 0xd5, 0xa0, 0x12, 0xfb, 0x35, 0xe4, 0xd4, 0x3f, 0xef, 0x24, 0x3e, 0x6c, 0xff, 0xb1, 0x35, 0x7e, 0x9f, 0xe7, 0x6d, 0x2f, 0xf8, 0x0d, 0xc6, 0xbc, 0x19, 0xe2, 0x78, 0xb3, 0x71, 0xe1, 0x35, 0xe7, 0xc7, 0x22, 0x6b, 0x4d, 0x92, 0xc4, 0x10, 0x75, 0x1a, 0x9b, 0x9f, 0x7f, 0xac, 0x2d, 0xfb, 0xc9, 0x64, 0x1e, 0x80, 0x11, 0x7f, 0x75, 0x8a, 0x86, 0x7e, 0x09, 0x44, 0xc4, 0x71, 0xbf, 0xd4, 0xfa, 0x8b, 0x6a, 0xb8, 0x9f, 0x02, 0x03, 0x01, 0x00, 0x01}; CFDataRef testInteropImport = CFDataCreate(kCFAllocatorDefault, sampleByteString, sizeof(sampleByteString)); SecOTRPublicIdentityRef interopIDInflate = SecOTRPublicIdentityCreateFromData(kCFAllocatorDefault, testInteropImport, &testError); RegressionsLogError(testError); CFReleaseNull(testError); ok(interopIDInflate != NULL, "Interop inflate failed"); /* cleanup keychain */ ok(SecOTRFIPurgeAllFromKeychain(&testError),"cleanup keychain"); RegressionsLogError(testError); CFReleaseNull(testError); CFReleaseSafe(pubID); CFReleaseSafe(pubIDInflate); CFReleaseSafe(firstPublicExport); CFReleaseSafe(secondPublicExport); CFReleaseSafe(id); CFReleaseSafe(idToPurge); CFReleaseSafe(idInflate); CFReleaseSafe(firstExport); CFReleaseSafe(secondExport); CFReleaseSafe(purgeExport); CFReleaseSafe(purgeIdInflate); CFReleaseSafe(failIDInflate); CFReleaseSafe(failIDInflate2); CFReleaseSafe(testInteropImport); CFReleaseSafe(interopIDInflate); }
CFMutableDictionaryRef decrypt_data_ios5(const uint8_t* datab, uint32_t len, uint32_t* pclass) { CFMutableDictionaryRef plist = NULL; CFErrorRef err = NULL; uint8_t aes_key[48]; uint32_t version, protection_class, wrapped_length, item_length; CCCryptorStatus cs = 0; IOReturn ret; int taglen = 16; char tag[16]; if (len < 68) { fprintf(stderr, "decrypt_data_ios5 : keychain item len < 68\n"); return NULL; } version = ((uint32_t*) datab)[0]; protection_class = ((uint32_t*) datab)[1]; if (pclass != NULL) *pclass = protection_class; wrapped_length = ((uint32_t*) datab)[2]; item_length = len - 48 - 4 - 16; if (version != 2 && version != 3) { fprintf(stderr, "decrypt_data_ios5 : version = %d\n", version); return NULL; } if (wrapped_length != 40) { fprintf(stderr, "decrypt_data_ios5 : wrapped_length != 0x28\n"); return NULL; } if((ret = AppleKeyStore_keyUnwrap(protection_class, &datab[12], 40, aes_key))) { fprintf(stderr, "decrypt_data_ios5 : AppleKeyStore_keyUnwrap = %x\n", ret); return NULL; } CFMutableDataRef item = CFDataCreateMutable(kCFAllocatorDefault, item_length); if (item == NULL) { memset(aes_key, 0, 48); return NULL; } CFDataSetLength(item, item_length); if (CCCryptorGCM == NULL) getCCCryptorGCM(); if (CCCryptorGCM != NULL) cs = CCCryptorGCM(kCCDecrypt, kCCAlgorithmAES128, aes_key, 32, 0, 0, 0, 0, &datab[52], item_length, (void*) CFDataGetBytePtr(item), tag, &taglen); memset(aes_key, 0, 48); if (cs != 0) { fprintf(stderr, "decrypt_data_ios5 : CCCryptorGCM failed, CCCryptorStatus = %x\n", cs); CFRelease(item); return NULL; } if (version == 3) { der_decode_plist(kCFAllocatorDefault, 1, (CFPropertyListRef*) &plist, &err, (const uint8_t*) CFDataGetBytePtr(item), (const uint8_t*) CFDataGetBytePtr(item) + item_length); } else { plist = (CFMutableDictionaryRef) CFPropertyListCreateFromXMLData(NULL, item, kCFPropertyListMutableContainersAndLeaves, NULL); } CFRelease(item); if (plist != NULL && CFGetTypeID(plist) != CFDictionaryGetTypeID()) { fprintf(stderr, "decrypt_data_ios5 : CFPropertyListCreateFromXMLData did not return a dictionary\n"); CFRelease(plist); return NULL; } return plist; }
// Each MIDIPacket can contain more than one midi messages. // This function processes the packet and adds the messages to the specified message queue. // @see also src/share/native/com/sun/media/sound/PlatformMidi.h. static void processMessagesForPacket(const MIDIPacket* packet, MacMidiDeviceHandle* handle) { const UInt8* data; UInt16 length; UInt8 byte; UInt8 pendingMessageStatus; UInt8 pendingData[2]; UInt16 pendingDataIndex, pendingDataLength; UINT32 packedMsg; MIDITimeStamp ts = packet->timeStamp; pendingMessageStatus = 0; pendingDataIndex = pendingDataLength = 0; data = packet->data; length = packet->length; while (length--) { bool byteIsInvalid = FALSE; byte = *data++; packedMsg = byte; if (byte >= 0xF8) { // Each RealTime Category message (ie, Status of 0xF8 to 0xFF) consists of only 1 byte, the Status. // Except that 0xFD is an invalid status code. // // 0xF8 -> Midi clock // 0xF9 -> Midi tick // 0xFA -> Midi start // 0xFB -> Midi continue // 0xFC -> Midi stop // 0xFE -> Active sense // 0xFF -> Reset if (byte == 0xFD) { byteIsInvalid = TRUE; } else { pendingDataLength = 0; } } else { if (byte < 0x80) { // Not a status byte -- check our history. if (handle->readingSysExData) { CFDataAppendBytes(handle->readingSysExData, &byte, 1); } else if (pendingDataIndex < pendingDataLength) { pendingData[pendingDataIndex] = byte; pendingDataIndex++; if (pendingDataIndex == pendingDataLength) { // This message is now done -- do the final processing. if (pendingDataLength == 2) { packedMsg = pendingMessageStatus | pendingData[0] << 8 | pendingData[1] << 16; } else if (pendingDataLength == 1) { packedMsg = pendingMessageStatus | pendingData[0] << 8; } else { fprintf(stderr, "%s: %d->internal error: pendingMessageStatus=0x%X, pendingDataLength=%d\n", __FILE__, __LINE__, pendingMessageStatus, pendingDataLength); byteIsInvalid = TRUE; } pendingDataLength = 0; } } else { // Skip this byte -- it is invalid. byteIsInvalid = TRUE; } } else { if (handle->readingSysExData /* && (byte == 0xF7) */) { // We have reached the end of system exclusive message -- send it finally. const UInt8* bytes = CFDataGetBytePtr(handle->readingSysExData); CFIndex size = CFDataGetLength(handle->readingSysExData); MIDI_QueueAddLong(handle->h.queue, (UBYTE*) bytes, (UINT32) size, 0, // Don't care, windowish porting only. (INT64) (AudioConvertHostTimeToNanos(ts) + 500) / 1000, TRUE); CFRelease(handle->readingSysExData); handle->readingSysExData = NULL; } pendingMessageStatus = byte; pendingDataLength = 0; pendingDataIndex = 0; switch (byte & 0xF0) { case 0x80: // Note off case 0x90: // Note on case 0xA0: // Aftertouch case 0xB0: // Controller case 0xE0: // Pitch wheel pendingDataLength = 2; break; case 0xC0: // Program change case 0xD0: // Channel pressure pendingDataLength = 1; break; case 0xF0: { // System common message switch (byte) { case 0xF0: // System exclusive // Allocates a CFMutableData reference to accumulate the SysEx data until EOX (0xF7) is reached. handle->readingSysExData = CFDataCreateMutable(NULL, 0); break; case 0xF7: // System exclusive ends--already handled above. // But if this is showing up outside of sysex, it's invalid. byteIsInvalid = TRUE; break; case 0xF1: // MTC quarter frame message case 0xF3: // Song select pendingDataLength = 1; break; case 0xF2: // Song position pointer pendingDataLength = 2; break; case 0xF6: // Tune request pendingDataLength = 0; break; default: // Invalid message byteIsInvalid = TRUE; break; } break; } default: // This can't happen, but handle it anyway. byteIsInvalid = TRUE; break; } } } if (byteIsInvalid) continue; // If the byte is valid and pendingDataLength is 0, we are ready to send the message. if (pendingDataLength == 0) { MIDI_QueueAddShort(handle->h.queue, packedMsg, (INT64) (AudioConvertHostTimeToNanos(ts) + 500) / 1000, TRUE); } } }
int main() { if (geteuid()) { syslog(LOG_ERR,"Error: Daemon must run as root."); exit(geteuid()); } encrypt_buffer = CFDataCreateMutable(kCFAllocatorDefault,8); /*********Set up File**********/ if (!(pathName = (CFStringRef)CFPreferencesCopyAppValue(PATHNAME_PREF_KEY,PREF_DOMAIN))) { pathName = CFSTR(DEFAULT_PATHNAME); CFPreferencesSetAppValue(PATHNAME_PREF_KEY,pathName,PREF_DOMAIN); } CFURLRef logPathURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,pathName,kCFURLPOSIXPathStyle,false); logStream = CFWriteStreamCreateWithFile(kCFAllocatorDefault,logPathURL); CFRelease(logPathURL); if (!logStream) { syslog(LOG_ERR,"Error: Couldn't open file stream at start."); return 1; } /*********Check encryption & keymap**********/ updateEncryption(); updateKeymap(); /*********Check space**********/ if (outOfSpace(pathName)) { stamp_file(CFSTR("Not enough disk space remaining!")); CFRunLoopStop(CFRunLoopGetCurrent()); } /*********Connect to kernel extension**********/ if (!connectToKext()) { if (load_kext()) { stamp_file(CFSTR("Could not load KEXT")); return 1; } if (!connectToKext()) { stamp_file(CFSTR("Could not connect with KEXT")); return 1; } } sleep(1); // just a little time to let the kernel notification handlers finish stamp_file(CFSTR("LogKext Daemon starting up")); // stamp login file with initial user LoginLogoutCallBackFunction(NULL, NULL, NULL); CFPreferencesAppSynchronize(PREF_DOMAIN); /*********Create Daemon Timer source**********/ CFRunLoopTimerContext timerContext = { 0 }; CFRunLoopSourceRef loginLogoutSource; if (InstallLoginLogoutNotifiers(&loginLogoutSource)) syslog(LOG_ERR,"Error: could not install login notifier"); else CFRunLoopAddSource(CFRunLoopGetCurrent(),loginLogoutSource, kCFRunLoopDefaultMode); CFRunLoopTimerRef daemonTimer = CFRunLoopTimerCreate(NULL, 0, TIME_TO_SLEEP, 0, 0, DaemonTimerCallback, &timerContext); CFRunLoopAddTimer(CFRunLoopGetCurrent(), daemonTimer, kCFRunLoopCommonModes); CFRunLoopRun(); stamp_file(CFSTR("Server error: closing Daemon")); CFWriteStreamClose(logStream); }
// // Executable code. // Read from disk, evaluate properly, cache as indicated. The whole thing, so far. // void PolicyEngine::evaluateCode(CFURLRef path, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context, CFMutableDictionaryRef result, bool handleUnsignedCode /* = true */) { FileQuarantine qtn(cfString(path).c_str()); if (qtn.flag(QTN_FLAG_HARD)) MacOSError::throwMe(errSecCSFileHardQuarantined); CFRef<SecStaticCodeRef> code; MacOSError::check(SecStaticCodeCreateWithPath(path, kSecCSDefaultFlags, &code.aref())); OSStatus rc = noErr; // last validation error const SecCSFlags validationFlags = kSecCSEnforceRevocationChecks; WhitelistPrescreen whitelistScreen(code); // pre-screening filter for whitelist pre-screening (only) SQLite::Statement query(*this, "SELECT allow, requirement, id, label, expires, flags, disabled, filter_unsigned, remarks FROM scan_authority" " WHERE type = :type" " ORDER BY priority DESC;"); query.bind(":type").integer(type); SQLite3::int64 latentID = 0; // first (highest priority) disabled matching ID std::string latentLabel; // ... and associated label, if any while (query.nextRow()) { bool allow = int(query[0]); const char *reqString = query[1]; SQLite3::int64 id = query[2]; const char *label = query[3]; double expires = query[4]; sqlite3_int64 ruleFlags = query[5]; SQLite3::int64 disabled = query[6]; const char *filter = query[7]; const char *remarks = query[8]; CFRef<SecRequirementRef> requirement; MacOSError::check(SecRequirementCreateWithString(CFTempString(reqString), kSecCSDefaultFlags, &requirement.aref())); rc = SecStaticCodeCheckValidity(code, validationFlags, requirement); // ad-hoc sign unsigned code, skip of Gatekeeper is off or the rule is disabled; but always do it for whitelist recording if (rc == errSecCSUnsigned && handleUnsignedCode && (!(disabled || overrideAssessment()) || SYSPOLICY_RECORDER_MODE_ENABLED())) { if (!SYSPOLICY_RECORDER_MODE_ENABLED()) { // apply whitelist pre-screening to speed things up for non-matches if (ruleFlags & kAuthorityFlagDefault) // can't ever match standard rules with unsigned code continue; if (whitelistScreen.reject(filter, remarks)) // apply whitelist pre-filter continue; } try { // ad-hoc sign the code and attach the signature CFRef<CFDataRef> signature = CFDataCreateMutable(NULL, 0); CFTemp<CFDictionaryRef> arguments("{%O=%O, %O=#N}", kSecCodeSignerDetached, signature.get(), kSecCodeSignerIdentity); CFRef<SecCodeSignerRef> signer; MacOSError::check(SecCodeSignerCreate(arguments, kSecCSDefaultFlags, &signer.aref())); MacOSError::check(SecCodeSignerAddSignature(signer, code, kSecCSDefaultFlags)); MacOSError::check(SecCodeSetDetachedSignature(code, signature, kSecCSDefaultFlags)); // if we're in GKE recording mode, save that signature and report its location if (SYSPOLICY_RECORDER_MODE_ENABLED()) { int status = recorder_code_unable; // ephemeral signature (not recorded) if (geteuid() == 0) { CFRef<CFUUIDRef> uuid = CFUUIDCreate(NULL); std::string sigfile = RECORDER_DIR + cfStringRelease(CFUUIDCreateString(NULL, uuid)) + ".tsig"; try { UnixPlusPlus::AutoFileDesc fd(sigfile, O_WRONLY | O_CREAT); fd.write(CFDataGetBytePtr(signature), CFDataGetLength(signature)); status = recorder_code_adhoc; // recorded signature SYSPOLICY_RECORDER_MODE_ADHOC_PATH(cfString(path).c_str(), type, sigfile.c_str()); } catch (...) { } } // now report the D probe itself CFRef<CFDictionaryRef> info; MacOSError::check(SecCodeCopySigningInformation(code, kSecCSDefaultFlags, &info.aref())); CFDataRef cdhash = CFDataRef(CFDictionaryGetValue(info, kSecCodeInfoUnique)); SYSPOLICY_RECORDER_MODE(cfString(path).c_str(), type, "", cdhash ? CFDataGetBytePtr(cdhash) : NULL, status); } // rerun the validation to update state rc = SecStaticCodeCheckValidity(code, validationFlags | kSecCSBasicValidateOnly, requirement); } catch (...) { } } switch (rc) { case noErr: // well signed and satisfies requirement... break; // ... continue below case errSecCSSignatureFailed: if (!codeInvalidityExceptions(code, result)) { if (SYSPOLICY_ASSESS_OUTCOME_BROKEN_ENABLED()) SYSPOLICY_ASSESS_OUTCOME_BROKEN(cfString(path).c_str(), type, false); MacOSError::throwMe(rc); } if (SYSPOLICY_ASSESS_OUTCOME_BROKEN_ENABLED()) SYSPOLICY_ASSESS_OUTCOME_BROKEN(cfString(path).c_str(), type, true); // treat as unsigned to fix problems in the field case errSecCSUnsigned: if (handleUnsignedCode) { cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict); addAuthority(result, "no usable signature"); } return; case errSecCSReqFailed: // requirement missed, but otherwise okay continue; default: // broken in some way; all tests will fail like this so bail out MacOSError::throwMe(rc); } if (disabled) { if (latentID == 0) { latentID = id; if (label) latentLabel = label; } continue; // the loop } CFRef<CFDictionaryRef> info; // as needed if (flags & kSecAssessmentFlagRequestOrigin) { if (!info) MacOSError::check(SecCodeCopySigningInformation(code, kSecCSSigningInformation, &info.aref())); if (CFArrayRef chain = CFArrayRef(CFDictionaryGetValue(info, kSecCodeInfoCertificates))) setOrigin(chain, result); } if (!(ruleFlags & kAuthorityFlagInhibitCache) && !(flags & kSecAssessmentFlagNoCache)) { // cache inhibit if (!info) MacOSError::check(SecCodeCopySigningInformation(code, kSecCSSigningInformation, &info.aref())); if (SecTrustRef trust = SecTrustRef(CFDictionaryGetValue(info, kSecCodeInfoTrust))) { CFRef<CFDictionaryRef> xinfo; MacOSError::check(SecTrustCopyExtendedResult(trust, &xinfo.aref())); if (CFDateRef limit = CFDateRef(CFDictionaryGetValue(xinfo, kSecTrustExpirationDate))) { this->recordOutcome(code, allow, type, min(expires, dateToJulian(limit)), id); } } } if (allow) { if (SYSPOLICY_ASSESS_OUTCOME_ACCEPT_ENABLED()) { if (!info) MacOSError::check(SecCodeCopySigningInformation(code, kSecCSSigningInformation, &info.aref())); CFDataRef cdhash = CFDataRef(CFDictionaryGetValue(info, kSecCodeInfoUnique)); SYSPOLICY_ASSESS_OUTCOME_ACCEPT(cfString(path).c_str(), type, label, cdhash ? CFDataGetBytePtr(cdhash) : NULL); } } else { if (SYSPOLICY_ASSESS_OUTCOME_DENY_ENABLED() || SYSPOLICY_RECORDER_MODE_ENABLED()) { if (!info) MacOSError::check(SecCodeCopySigningInformation(code, kSecCSSigningInformation, &info.aref())); CFDataRef cdhash = CFDataRef(CFDictionaryGetValue(info, kSecCodeInfoUnique)); std::string cpath = cfString(path); const void *hashp = cdhash ? CFDataGetBytePtr(cdhash) : NULL; SYSPOLICY_ASSESS_OUTCOME_DENY(cpath.c_str(), type, label, hashp); SYSPOLICY_RECORDER_MODE(cpath.c_str(), type, label, hashp, recorder_code_untrusted); } } cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, allow); addAuthority(result, label, id); return; } if (rc == errSecCSUnsigned) { // skipped all applicable rules due to pre-screening cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict); addAuthority(result, "no usable signature"); return; } // no applicable authority (but signed, perhaps temporarily). Deny by default CFRef<CFDictionaryRef> info; MacOSError::check(SecCodeCopySigningInformation(code, kSecCSSigningInformation, &info.aref())); if (flags & kSecAssessmentFlagRequestOrigin) { if (CFArrayRef chain = CFArrayRef(CFDictionaryGetValue(info, kSecCodeInfoCertificates))) setOrigin(chain, result); } if (SYSPOLICY_ASSESS_OUTCOME_DEFAULT_ENABLED() || SYSPOLICY_RECORDER_MODE_ENABLED()) { CFDataRef cdhash = CFDataRef(CFDictionaryGetValue(info, kSecCodeInfoUnique)); const void *hashp = cdhash ? CFDataGetBytePtr(cdhash) : NULL; std::string cpath = cfString(path); SYSPOLICY_ASSESS_OUTCOME_DEFAULT(cpath.c_str(), type, latentLabel.c_str(), hashp); SYSPOLICY_RECORDER_MODE(cpath.c_str(), type, latentLabel.c_str(), hashp, 0); } if (!(flags & kSecAssessmentFlagNoCache)) this->recordOutcome(code, false, type, this->julianNow() + NEGATIVE_HOLD, latentID); cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, false); addAuthority(result, latentLabel.c_str(), latentID); }
static CFArrayRef getTargets(CFBundleRef bundle) { int fd; Boolean ok; struct stat statBuf; CFArrayRef targets; /* The array of dictionaries representing targets with a "kick me" sign posted on their backs. */ char targetPath[MAXPATHLEN]; CFURLRef url; CFStringRef xmlError; CFMutableDataRef xmlTargets; /* locate the Kicker targets */ url = CFBundleCopyResourceURL(bundle, CFSTR("Kicker"), CFSTR("xml"), NULL); if (!url) { return NULL; } ok = CFURLGetFileSystemRepresentation(url, TRUE, (UInt8 *)&targetPath, sizeof(targetPath)); CFRelease(url); if (!ok) { return NULL; } /* open the file */ if ((fd = open(targetPath, O_RDONLY, 0)) == -1) { SCLog(TRUE, LOG_NOTICE, CFSTR("%@ load(): %s not found"), CFBundleGetIdentifier(bundle), targetPath); return NULL; } /* get the type and size of the XML data file */ if (fstat(fd, &statBuf) < 0) { (void) close(fd); return NULL; } /* check that its a regular file */ if ((statBuf.st_mode & S_IFMT) != S_IFREG) { (void) close(fd); return NULL; } /* load the file contents */ xmlTargets = CFDataCreateMutable(NULL, statBuf.st_size); CFDataSetLength(xmlTargets, statBuf.st_size); if (read(fd, (void *)CFDataGetMutableBytePtr(xmlTargets), statBuf.st_size) != statBuf.st_size) { CFRelease(xmlTargets); (void) close(fd); return NULL; } (void) close(fd); /* convert the XML data into a property list */ targets = CFPropertyListCreateFromXMLData(NULL, xmlTargets, kCFPropertyListImmutable, &xmlError); CFRelease(xmlTargets); if (!targets) { if (xmlError) { SCLog(TRUE, LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() start: %@"), xmlError); CFRelease(xmlError); } return NULL; } if (!isA_CFArray(targets)) { CFRelease(targets); targets = NULL; } return targets; }
uint32_t AMAuthInstallCryptoRegisterKeysFromPEMBuffer(CFDictionaryRef dict, CFStringRef key, CFTypeRef value, void* context) { LODWORD(r14) = LODWORD(rcx); r12 = rdx; rbx = rsi; r13 = rdi; uint32_t result = AMAuthInstallCryptoGetKeyIdType(key); if ((result & 0x8) == 0x0) { // loc_428fc; if ((result & 0x4) == 0x0) { // loc_4291d; CFStringRef pub_key_name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@.public"), key); LODWORD(r15) = 0x2; if (!pub_key_name) { // loc_42cf2; LODWORD(r13) = 0x0; LODWORD(rbx) = 0x0; var_24 = 0x0; LODWORD(r14) = 0x0; LODWORD(r12) = 0x0; // loc_42c0d; // goto exit } // loc_4295c; CFStringRef private_key_name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@.private"), key); if (!private_key_name) { // loc_42d0d; LODWORD(r13) = 0x0; var_24 = 0x0; // loc_42bc9: LODWORD(r14) = 0x0; LODWORD(r12) = 0x0; rbx = var_40; // loc_42c0d; // goto exit } // loc_4298e; LOBYTE(r15) = 0x1; var_16 = 0x1; } else { // loc_42900; var_40 = CFRetain(rbx); LOBYTE(r15) = 0x0; var_16 = 0x1; LODWORD(rax) = 0x0; // loc_42998; } } else { // loc_428da; rax = CFRetain(rbx); LOBYTE(r15) = 0x1; var_16 = 0x0; var_40 = 0x0; } // loc_42998; var_8 = r13; var_24 = rax; rbx = BIO_new_mem_buf(r12, LODWORD(r14)); if (rbx == 0x0) { // loc_42be7; var_32 = 0x0; LODWORD(r13) = 0x0; LODWORD(r14) = 0x0; // loc_42bf8: LODWORD(r12) = 0x0; // loc_42c00: rbx = var_40; LODWORD(r15) = 0x2; // loc_42c0d; // goto exit } // loc_429bd; rdi = rbx; if (LOBYTE(r15) != 0x0) { rax = PEM_read_bio_RSAPrivateKey(rdi, 0x0, 0x0, 0x0); } else { rax = PEM_read_bio_RSA_PUBKEY(rdi, 0x0, 0x0, 0x0); } r13 = rax; var_32 = rbx; if (r13 == 0x0) { // loc_42b77; rax = ERR_get_error(); rbx = &var_64; ERR_error_string(rax, rbx); if (LOBYTE(r15) != 0x0) { } _AMAuthInstallLog(0x3, "AMAuthInstallCryptoRegisterKeysFromPEMBuffer", "PEM_read_bio_RSA%sKey() failed: %s"); LODWORD(r15) = 0x6; LODWORD(r13) = 0x0; // loc_42bc9; LODWORD(r14) = 0x0; LODWORD(r12) = 0x0; rbx = var_40; // loc_42c0d; // goto exit } else { // loc_429ea; LODWORD(r14) = 0x0; uint32_t private_key_length = i2d_RSAPrivateKey(r13, NULL); CFDataRef private_key = CFDataCreateMutable(kCFAllocatorDefault, private_key_length); if (private_key) { // loc_42a2c; CFDataSetLength(private_key, private_key_length); UInt8 *data_ptr = CFDataGetMutableBytePtr(private_key); i2d_RSAPrivateKey(r13, data_ptr); CFDictionarySetValue(*(r15 + 0x140), private_key_name, private_key); // loc_42a6b; } if (LOBYTE(r15) == 0x0 || private_key) { // loc_42a6b; if (var_16 == 0x0) { // loc_42bd8; LODWORD(r12) = 0x0; LODWORD(r15) = 0x0; rbx = var_40; // loc_42c0d; // goto exit } else { // loc_42a78; uint32_t pub_key_length = i2d_RSAPublicKey(r13, NULL); CFDataRef pub_key = CFDataCreateMutable(kCFAllocatorDefault, pub_key_length); if (pub_key == 0x0) { // loc_42bf8; LODWORD(r12) = 0x0; // loc_42c00: rbx = var_40; LODWORD(r15) = 0x2; // loc_42c0d; // goto exit } var_0 = r14; CFDataSetLength(pub_key, pub_key_length); UInt8 *pub_key_ptr = CFDataGetMutableBytePtr(pub_key); i2d_RSAPublicKey(r13, pub_key_ptr); CFDictionarySetValue(dict, pub_key_name, pub_key); Pointer digest = NULL; LODWORD(r15) = AMAuthInstallCryptoCreateDigestForKey(dict, pub_key_name, &digest)); if (LODWORD(r15) == 0x0) { var_16 = r13; if (var_64 != 0x0) { CFDictionarySetValue(install->ivars.digests, var_64, rbx); LODWORD(r13) = 0x0; } else { _AMAuthInstallLog(0x3, "_AMAuthInstallCryptoRegisterKeyHash", "keyHashData is NULL"); LODWORD(r13) = 0x0; LODWORD(r15) = 0x0; } } else { var_16 = r13; AMAuthInstallLog(0x3, "_AMAuthInstallCryptoRegisterKeyHash", "AMAuthInstallCryptoCreateDigestForKey(%@) failed", rbx); LODWORD(r13) = LODWORD(r15); r15 = var_64; } _SafeRelease(r15); LODWORD(r15) = LODWORD(r13); r14 = var_0; if (LODWORD(r13) == 0x0) { LODWORD(r15) = 0x0; } else { AMAuthInstallLog(0x3, "AMAuthInstallCryptoRegisterKeysFromPEMBuffer", "AMAuthInstallCryptoRegisterKeyHash(%@) failed", rbx); } r13 = var_16; // loc_42c0d; // goto exit } } } // loc_42c0d: _SafeRelease(rbx); _SafeRelease(var_24); _SafeRelease(r14); _SafeRelease(r12); if (r13 != 0x0) { RSA_free(r13); } rdi = var_32; if (rdi != 0x0) { BIO_free(rdi); } return result; }
static int ConnectionRegisterListener( ConnectionRef conn, CFRunLoopRef runLoop, CFStringRef runLoopMode, ConnectionCallbackProcPtr callback, void * refCon ) // Register a listener to be called when packets arrive. Once you've done // this, you can no longer use conn for RPCs. // // conn must be a valid connection // // runLoop and runLoopMode specify the context in which the callback will // be called; in most cases you specify CFRunLoopGetCurrent() and // kCFRunLoopDefaultMode // // callback is the function you want to be called when packets arrive; it // must not be NULL // // refCon is passed to callback // // Returns an errno-style error code // On success, the connection has been converted to a listener and your // callback will be called from the context of the specific runloop when // a packet arrives; on error, the connection is no longer useful (conn is // still valid, but you can't use it to transmit any more data) { int err; assert(conn != NULL); assert(runLoop != NULL); assert(runLoopMode != NULL); assert(callback != NULL); assert(conn->fSockFD != -1); // connection must not be shut down assert(conn->fSockCF == NULL); // can't register twice // Create the packet buffer. err = 0; conn->fBufferedPackets = CFDataCreateMutable(NULL, 0); if (conn->fBufferedPackets == NULL) { err = ENOMEM; } // Add the source to the runloop. if (err == 0) { CFSocketContext context; memset(&context, 0, sizeof(context)); context.info = conn; conn->fSockCF = CFSocketCreateWithNative( NULL, (CFSocketNativeHandle) conn->fSockFD, kCFSocketDataCallBack, ConnectionGotData, &context ); if (conn->fSockCF == NULL) { err = EINVAL; } } if (err == 0) { conn->fRunLoopSource = CFSocketCreateRunLoopSource(NULL, conn->fSockCF, 0); if (conn->fRunLoopSource == NULL) { err = EINVAL; } } if (err == 0) { conn->fCallback = callback; conn->fCallbackRefCon = refCon; CFRunLoopAddSource( runLoop, conn->fRunLoopSource, runLoopMode); } // Any failure means the entire connection is dead; again, this is the // draconian approach to error handling. But hey, connections are // (relatively) cheap. if (err != 0) { ConnectionShutdown(conn); } return err; }
static CFDataRef SecRSAPrivateKeyCreatePKCS1(CFAllocatorRef allocator, ccrsa_full_ctx_t fullkey) { ccrsa_priv_ctx_t privkey = ccrsa_ctx_private(fullkey); const cc_size np = cczp_n(ccrsa_ctx_private_zp(privkey)); const cc_size nq = cczp_n(ccrsa_ctx_private_zq(privkey)); size_t m_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey)); size_t e_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_e(fullkey)); size_t d_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_d(fullkey)); size_t p_size = ccn_write_int_size(np, cczp_prime(ccrsa_ctx_private_zp(privkey))); size_t q_size = ccn_write_int_size(nq, cczp_prime(ccrsa_ctx_private_zq(privkey))); size_t dp_size = ccn_write_int_size(np, ccrsa_ctx_private_dp(privkey)); size_t dq_size = ccn_write_int_size(nq, ccrsa_ctx_private_dq(privkey)); size_t qinv_size = ccn_write_int_size(np, ccrsa_ctx_private_qinv(privkey)); const size_t seq_size = 3 + DERLengthOfItem(ASN1_INTEGER, m_size) + DERLengthOfItem(ASN1_INTEGER, e_size) + DERLengthOfItem(ASN1_INTEGER, d_size) + DERLengthOfItem(ASN1_INTEGER, p_size) + DERLengthOfItem(ASN1_INTEGER, q_size) + DERLengthOfItem(ASN1_INTEGER, dp_size) + DERLengthOfItem(ASN1_INTEGER, dq_size) + DERLengthOfItem(ASN1_INTEGER, qinv_size); const size_t result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size); CFMutableDataRef pkcs1 = CFDataCreateMutable(allocator, result_size); if (pkcs1 == NULL) return NULL; CFDataSetLength(pkcs1, result_size); uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1); *bytes++ = ASN1_CONSTR_SEQUENCE; DERSize itemLength = 4; DEREncodeLength(seq_size, bytes, &itemLength); bytes += itemLength; *bytes++ = ASN1_INTEGER; *bytes++ = 0x01; *bytes++ = 0x00; ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey), m_size, &bytes); ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_e(fullkey), e_size, &bytes); ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_d(fullkey), d_size, &bytes); ccasn_encode_int(np, cczp_prime(ccrsa_ctx_private_zp(privkey)), p_size, &bytes); ccasn_encode_int(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)), q_size, &bytes); ccasn_encode_int(np, ccrsa_ctx_private_dp(privkey), dp_size, &bytes); ccasn_encode_int(nq, ccrsa_ctx_private_dq(privkey), dq_size, &bytes); ccasn_encode_int(np, ccrsa_ctx_private_qinv(privkey), qinv_size, &bytes); return pkcs1; }
CFDataRef createHTMLData(CFDataRef nfo) { // Load HTML constants (UCS2) CFDataRef preNfo = createUCS2FromConst(PRE_NFO_HTML, sizeof(PRE_NFO_HTML)); CFDataRef postNfo = createUCS2FromConst(POST_NFO_HTML, sizeof(POST_NFO_HTML)); CFDataRef preBlock = createUCS2FromConst(PRE_BLOCK_HTML, sizeof(PRE_BLOCK_HTML)); CFDataRef postBlock = createUCS2FromConst(POST_BLOCK_HTML, sizeof(POST_BLOCK_HTML)); CFMutableDataRef result = CFDataCreateMutable(NULL, 0); appendCFData(result, preNfo); CFRelease(preNfo); const UInt8* inPtr = CFDataGetBytePtr(nfo); size_t inCharsLeft = CFDataGetLength(nfo) / sizeof(UInt16); const UInt8* bsPtr = inPtr; bool inRun = false; while (inCharsLeft-- > 0) { UInt16 chr = *((const UInt16*)inPtr); // Look ahead for new state bool newState = inRun; if(!inRun) { if(ISBLOCKORBOX(chr)) { newState = true; } } else { if(!ISBLOCKORBOX(chr) && !ISWHITESPACE(chr)) { newState = false; } } // Process change of state, append data if(inRun != newState) { if(inPtr != bsPtr) { if(inRun) { appendCFData(result, preBlock); CFDataAppendBytes(result, (const UInt8*)bsPtr, (inPtr - bsPtr)); appendCFData(result, postBlock); } else { CFDataAppendBytes(result, (const UInt8*)bsPtr, (inPtr - bsPtr)); } bsPtr = inPtr; } inRun = newState; } inPtr += sizeof(UInt16); } // Append trailing data if(inPtr > bsPtr) { if(inRun) { appendCFData(result, preBlock); CFDataAppendBytes(result, (const UInt8*)bsPtr, (inPtr - bsPtr)); appendCFData(result, postBlock); } else { CFDataAppendBytes(result, (const UInt8*)bsPtr, (inPtr - bsPtr)); } } CFRelease(preBlock); CFRelease(postBlock); appendCFData(result, postNfo); CFRelease(postNfo); return result; }
void WebCoreSynchronousLoaderClient::didReceiveData(ResourceHandle*, const char* data, int length, int /*encodedDataLength*/) { if (!m_data) m_data.adoptCF(CFDataCreateMutable(kCFAllocatorDefault, 0)); CFDataAppendBytes(m_data.get(), reinterpret_cast<const UInt8*>(data), length); }