1/* 2 * Copyright (c) 2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25#include <stdio.h> 26#include "SecOTRRemote.h" 27#include <Security/SecOTRSession.h> 28#include <Security/SecOTRIdentityPriv.h> 29#include <securityd/SecItemServer.h> 30#include <securityd/SOSCloudCircleServer.h> 31 32#include "SOSAccount.h" 33 34CFDataRef SecOTRSessionCreateRemote_internal(CFDataRef publicAccountData, CFDataRef publicPeerId, CFDataRef privateAccountData, CFErrorRef *error) { 35 SOSDataSourceFactoryRef ds = SecItemDataSourceFactoryGetDefault(); 36 37 SOSAccountRef privateAccount = (privateAccountData == NULL) ? SOSKeychainAccountGetSharedAccount() : SOSAccountCreateFromData(kCFAllocatorDefault, privateAccountData, ds, error); 38 39 SOSAccountRef publicAccount = (publicAccountData == NULL) ? SOSKeychainAccountGetSharedAccount() : SOSAccountCreateFromData(kCFAllocatorDefault, publicAccountData, ds, error); 40 41 if(!privateAccount || !publicAccount) 42 return NULL; 43 44 __block SOSFullPeerInfoRef full_peer_info = NULL; 45 SOSAccountForEachCircle(privateAccount, ^(SOSCircleRef circle) { 46 if (full_peer_info == NULL) { 47 full_peer_info = SOSAccountGetMyFullPeerInCircle(privateAccount, circle, error); 48 } 49 }); 50 51 SecKeyRef privateKeyRef = SOSFullPeerInfoCopyDeviceKey(full_peer_info, error); 52 53 CFStringRef publicKeyString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, publicPeerId, kCFStringEncodingUTF8); 54 __block SOSPeerInfoRef peer_info = NULL; 55 SOSAccountForEachCircle(publicAccount, ^(SOSCircleRef circle) { 56 if (peer_info == NULL) { 57 peer_info = SOSCircleCopyPeerWithID(circle, publicKeyString, error); 58 } 59 }); 60 61 SecKeyRef publicKeyRef = SOSPeerInfoCopyPubKey(peer_info); 62 63 SecOTRFullIdentityRef privateIdentity = SecOTRFullIdentityCreateFromSecKeyRef(kCFAllocatorDefault, privateKeyRef, error); 64 SecOTRPublicIdentityRef publicIdentity = SecOTRPublicIdentityCreateFromSecKeyRef(kCFAllocatorDefault, publicKeyRef, error); 65 66 SecOTRSessionRef ourSession = SecOTRSessionCreateFromID(kCFAllocatorDefault, privateIdentity, publicIdentity); 67 68 CFMutableDataRef exportSession = CFDataCreateMutable(kCFAllocatorDefault, 0); 69 SecOTRSAppendSerialization(ourSession, exportSession); 70 71 return exportSession; 72} 73 74CFDataRef _SecOTRSessionCreateRemote(CFDataRef publicPeerId, CFErrorRef *error) { 75 return SecOTRSessionCreateRemote_internal(NULL, publicPeerId, NULL, error); 76} 77 78bool _SecOTRSessionProcessPacketRemote(CFDataRef sessionData, CFDataRef inputPacket, CFDataRef* outputSessionData, CFDataRef* outputPacket, bool *readyForMessages, CFErrorRef *error) { 79 80 SecOTRSessionRef session = SecOTRSessionCreateFromData(kCFAllocatorDefault, sessionData); 81 82 CFMutableDataRef negotiationResponse = CFDataCreateMutable(kCFAllocatorDefault, 0); 83 84 if (inputPacket) { 85 SecOTRSProcessPacket(session, inputPacket, negotiationResponse); 86 } else { 87 SecOTRSAppendStartPacket(session, negotiationResponse); 88 } 89 90 CFMutableDataRef outputSession = CFDataCreateMutable(kCFAllocatorDefault, 0); 91 92 SecOTRSAppendSerialization(session, outputSession); 93 *outputSessionData = outputSession; 94 95 *outputPacket = negotiationResponse; 96 97 *readyForMessages = SecOTRSGetIsReadyForMessages(session); 98 99 return true; 100} 101 102