//
// sc-150-ring.c
// sec
//
// Created by Richard Murphy on 3/3/15.
//
//
#include <stdio.h>
/*
* Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#include <Security/SecBase.h>
#include <Security/SecItem.h>
#include <Security/SecKeyPriv.h>
#include <Security/SecureObjectSync/SOSRing.h>
#include <Security/SecureObjectSync/SOSRingTypes.h>
#include <Security/SecureObjectSync/SOSRingUtils.h>
#include <Security/SecureObjectSync/SOSPeerInfo.h>
#include <Security/SecureObjectSync/SOSInternal.h>
#include <Security/SecureObjectSync/SOSUserKeygen.h>
#include <utilities/SecCFWrappers.h>
#include <CoreFoundation/CoreFoundation.h>
#include <stdlib.h>
#include <unistd.h>
#include "SOSCircle_regressions.h"
#include "SOSRegressionUtilities.h"
static SOSFullPeerInfoRef SOSCreateApplicantFullPeerInfoFromName(CFStringRef peerName,
SecKeyRef user_private_key,
SecKeyRef* outSigningKey,
SecKeyRef* outOctagonSigningKey,
SecKeyRef* outOctagonEncryptionKey,
CFErrorRef *error)
{
SOSFullPeerInfoRef result = NULL;
SOSFullPeerInfoRef fullPeer = SOSCreateFullPeerInfoFromName(peerName, outSigningKey, outOctagonSigningKey, outOctagonEncryptionKey, error);
if (fullPeer && SOSFullPeerInfoPromoteToApplication(fullPeer, user_private_key, error))
CFTransferRetained(result, fullPeer);
CFReleaseNull(fullPeer);
return result;
}
static int kTestTestCount = 24;
static void tests(void)
{
//SecKeyRef publicKey = NULL;
SecKeyRef dev_a_key = NULL;
SecKeyRef dev_b_key = NULL;
SecKeyRef dev_c_key = NULL;
SecKeyRef oct_dev_as_key = NULL;
SecKeyRef oct_dev_aw_key = NULL;
SecKeyRef oct_dev_bs_key = NULL;
SecKeyRef oct_dev_bw_key = NULL;
SecKeyRef oct_dev_cs_key = NULL;
SecKeyRef oct_dev_cw_key = NULL;
CFErrorRef error = NULL;
CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
ok(cfpassword, "no password");
CFDataRef parameters = SOSUserKeyCreateGenerateParameters(&error);
ok(parameters, "No parameters!");
ok(error == NULL, "Error: ( CFReleaseNull(error);
SecKeyRef user_privkey = SOSUserKeygen(cfpassword, parameters, &error);
CFReleaseNull(parameters);
SecKeyRef user_pubkey = SecKeyCreatePublicFromPrivate(user_privkey);
SOSFullPeerInfoRef peer_a_full_info = SOSCreateApplicantFullPeerInfoFromName(CFSTR("Peer A"), user_privkey, &dev_a_key, &oct_dev_as_key, &oct_dev_aw_key, NULL);
SOSFullPeerInfoRef peer_b_full_info = SOSCreateApplicantFullPeerInfoFromName(CFSTR("Peer B"), user_privkey, &dev_b_key, &oct_dev_bs_key, &oct_dev_bw_key, NULL);
SOSFullPeerInfoRef peer_c_full_info = SOSCreateApplicantFullPeerInfoFromName(CFSTR("Peer C"), user_privkey, &dev_c_key, &oct_dev_cs_key, &oct_dev_cw_key, NULL);
CFStringRef peerID_a = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(peer_a_full_info));
CFStringRef peerID_b = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(peer_b_full_info));
SOSRingRef Ring = SOSRingCreate(CFSTR("TESTRING"), peerID_a, kSOSRingBase, NULL);
ok(Ring, "Ring creation");
ok(0 == SOSRingCountPeers(Ring), "Zero peers");
ok(SOSRingApply(Ring, user_pubkey, peer_a_full_info, NULL));
ok(SOSRingApply(Ring, user_pubkey, peer_b_full_info, NULL));
ok(2 == SOSRingCountPeers(Ring), "Two peers");
ok(SOSRingWithdraw(Ring, user_privkey, peer_b_full_info, NULL));
ok(1 == SOSRingCountPeers(Ring), "One peer");
ok(kSOSRingMember == SOSRingDeviceIsInRing(Ring, peerID_a), "peer_a is in Ring");
ok(kSOSRingNotInRing == SOSRingDeviceIsInRing(Ring, peerID_b), "peer_b is not in Ring");
CFStringRef lastmod = SOSRingGetLastModifier(Ring);
ok(CFEqual(lastmod, peerID_b), "peer_b_full_info did last mod");
ok(SOSRingResetToEmpty(Ring, peerID_a, NULL), "Reset the circle");
ok(kSOSRingNotInRing == SOSRingDeviceIsInRing(Ring, peerID_a), "peer_a is not in Ring");
ok(SOSRingResetToOffering(Ring, NULL, peer_a_full_info, NULL), "Reset Ring to Offering for PeerA");
ok(kSOSRingMember == SOSRingDeviceIsInRing(Ring, peerID_a), "peer_a is in Ring");
ok(kSOSRingNotInRing == SOSRingDeviceIsInRing(Ring, peerID_b), "peer_b is not in Ring");
CFDataRef ringDER = SOSRingCopyEncodedData(Ring, NULL);
ok(ringDER, "Successful encoding to DER of Ring");
SOSRingRef Ring2 = SOSRingCreateFromData(NULL, ringDER);
ok(Ring2, "Successful decoding of DER to Ring");
ok(CFEqualSafe(Ring, Ring2), "Compares");
ok(SOSRingApply(Ring, user_pubkey, peer_c_full_info, NULL));
ok(SOSRingApply(Ring, user_pubkey, peer_b_full_info, NULL));
CFReleaseNull(ringDER);
CFReleaseNull(Ring2);
ringDER = SOSRingCopyEncodedData(Ring, NULL);
Ring2 = SOSRingCreateFromData(NULL, ringDER);
ok(CFEqualSafe(Ring, Ring2), "Compares");
CFReleaseNull(ringDER);
CFReleaseNull(Ring2);
CFReleaseNull(dev_a_key);
CFReleaseNull(dev_b_key);
CFReleaseNull(dev_c_key);
CFReleaseNull(oct_dev_as_key);
CFReleaseNull(oct_dev_aw_key);
CFReleaseNull(oct_dev_bs_key);
CFReleaseNull(oct_dev_bw_key);
CFReleaseNull(oct_dev_cs_key);
CFReleaseNull(oct_dev_cw_key);
CFReleaseNull(cfpassword);
CFReleaseNull(user_privkey);
CFReleaseNull(user_pubkey);
CFReleaseNull(peer_a_full_info);
CFReleaseNull(peer_b_full_info);
CFReleaseNull(peer_c_full_info);
CFReleaseNull(Ring);
}
int sc_150_Ring(int argc, char *const *argv)
{
plan_tests(kTestTestCount);
tests();
return 0;
}