#include <stdio.h>
#include "SecOTRRemote.h"
#include <Security/SecOTRSession.h>
#include <Security/SecOTRIdentityPriv.h>
#include <securityd/SecItemServer.h>
#include <securityd/SOSCloudCircleServer.h>
#include "SOSAccountPriv.h"
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(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;
}
CFDataRef _SecOTRSessionCreateRemote(CFDataRef publicPeerId, CFErrorRef *error) {
return SecOTRSessionCreateRemote_internal(NULL, publicPeerId, NULL, error);
}
bool _SecOTRSessionProcessPacketRemote(CFDataRef sessionData, CFDataRef inputPacket, CFDataRef* outputSessionData, CFDataRef* outputPacket, bool *readyForMessages, CFErrorRef *error) {
SecOTRSessionRef session = SecOTRSessionCreateFromData(kCFAllocatorDefault, sessionData);
CFMutableDataRef negotiationResponse = CFDataCreateMutable(kCFAllocatorDefault, 0);
if (inputPacket) {
SecOTRSProcessPacket(session, inputPacket, negotiationResponse);
} else {
SecOTRSAppendStartPacket(session, negotiationResponse);
}
CFMutableDataRef outputSession = CFDataCreateMutable(kCFAllocatorDefault, 0);
SecOTRSAppendSerialization(session, outputSession);
*outputSessionData = outputSession;
*outputPacket = negotiationResponse;
*readyForMessages = SecOTRSGetIsReadyForMessages(session);
return true;
}