SOSCoderRef SOSCoderCreate(SOSPeerInfoRef peerInfo, SOSFullPeerInfoRef myPeerInfo, CFErrorRef *error) { CFAllocatorRef allocator = CFGetAllocator(peerInfo); SOSCoderRef coder = calloc(1, sizeof(struct __OpaqueSOSCoder)); CFErrorRef localError = NULL; SecOTRFullIdentityRef myRef = NULL; SecOTRPublicIdentityRef peerRef = NULL; SecKeyRef privateKey = NULL; SecKeyRef publicKey = NULL; if (myPeerInfo && peerInfo) { privateKey = SOSFullPeerInfoCopyDeviceKey(myPeerInfo, &localError); require_quiet(privateKey, errOut); myRef = SecOTRFullIdentityCreateFromSecKeyRef(allocator, privateKey, &localError); require_quiet(myRef, errOut); CFReleaseNull(privateKey); publicKey = SOSPeerInfoCopyPubKey(peerInfo); peerRef = SecOTRPublicIdentityCreateFromSecKeyRef(allocator, publicKey, &localError); require_quiet(peerRef, errOut); coder->sessRef = SecOTRSessionCreateFromID(allocator, myRef, peerRef); require(coder->sessRef, errOut); coder->waitingForDataPacket = false; coder->pendingResponse = NULL; CFReleaseNull(publicKey); CFReleaseNull(privateKey); CFReleaseNull(myRef); CFReleaseNull(peerRef); } else { secnotice("coder", "NULL Coder requested, no transport security"); } SOSCoderStart(coder, NULL); return coder; errOut: secerror("Coder create failed: %@\n", localError ? localError : (CFTypeRef)CFSTR("No local error in SOSCoderCreate")); secerror("Coder create failed: %@\n", error ? *error : (CFTypeRef)CFSTR("WTF NULL?")); CFReleaseNull(myRef); CFReleaseNull(peerRef); CFReleaseNull(publicKey); CFReleaseNull(privateKey); free(coder); return NULL; }
CFDataRef SecOTRSessionCreateRemote_internal(CFDataRef publicAccountData, CFDataRef publicPeerId, CFDataRef privateAccountData, CFErrorRef *error) { SOSDataSourceFactoryRef ds = SecItemDataSourceFactoryGetDefault(); SOSAccountRef privateAccount = NULL; SOSAccountRef publicAccount = NULL; CFStringRef publicKeyString = NULL; SecKeyRef privateKeyRef = NULL; SecKeyRef publicKeyRef = NULL; SecOTRFullIdentityRef privateIdentity = NULL; SecOTRPublicIdentityRef publicIdentity = NULL; CFDataRef result = NULL; SecOTRSessionRef ourSession = NULL; require_quiet(ds, fail); require_quiet(publicPeerId, fail); privateAccount = (privateAccountData == NULL) ? CFRetainSafe(SOSKeychainAccountGetSharedAccount()) : SOSAccountCreateFromData(kCFAllocatorDefault, privateAccountData, ds, error); require_quiet(privateAccount, fail); privateKeyRef = SOSAccountCopyDeviceKey(privateAccount, error); require_quiet(privateKeyRef, fail); CFReleaseNull(privateAccount); privateIdentity = SecOTRFullIdentityCreateFromSecKeyRef(kCFAllocatorDefault, privateKeyRef, error); require_quiet(privateIdentity, fail); CFReleaseNull(privateKeyRef); publicKeyString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, publicPeerId, kCFStringEncodingUTF8); require_quiet(publicKeyString, fail); publicAccount = (publicAccountData == NULL) ? CFRetainSafe(SOSKeychainAccountGetSharedAccount()) : SOSAccountCreateFromData(kCFAllocatorDefault, publicAccountData, ds, error); require_quiet(publicAccount, fail); publicKeyRef = SOSAccountCopyPublicKeyForPeer(publicAccount, publicKeyString, error); require_quiet(publicKeyRef, fail); CFReleaseNull(publicAccount); publicIdentity = SecOTRPublicIdentityCreateFromSecKeyRef(kCFAllocatorDefault, publicKeyRef, error); require_quiet(publicIdentity, fail); CFReleaseNull(publicKeyRef); ourSession = SecOTRSessionCreateFromID(kCFAllocatorDefault, privateIdentity, publicIdentity); CFMutableDataRef exportSession = CFDataCreateMutable(kCFAllocatorDefault, 0); SecOTRSAppendSerialization(ourSession, exportSession); result = exportSession; exportSession = NULL; fail: CFReleaseNull(ourSession); CFReleaseNull(publicKeyString); CFReleaseNull(privateAccount); CFReleaseNull(publicAccount); CFReleaseNull(privateKeyRef); CFReleaseNull(publicKeyRef); CFReleaseNull(publicIdentity); CFReleaseNull(privateIdentity); return result; }