1/* 2 * Copyright (c) 2013-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 <Security/SecBase.h> 26#include <Security/SecItem.h> 27#include <Security/SecKey.h> 28 29#include <SecureObjectSync/SOSCircle.h> 30#include <SecureObjectSync/SOSPeerInfo.h> 31#include <SecureObjectSync/SOSInternal.h> 32 33#include <utilities/SecCFWrappers.h> 34 35#include <CoreFoundation/CoreFoundation.h> 36 37#include <stdlib.h> 38#include <unistd.h> 39 40#include "SOSCircle_regressions.h" 41 42#include "SOSRegressionUtilities.h" 43 44typedef struct piStuff_t { 45 SecKeyRef signingKey; 46 SOSFullPeerInfoRef fpi; 47 SOSPeerInfoRef pi; 48 SOSPeerInfoRef resignation_ticket; 49} piStuff; 50 51static piStuff *makeSimplePeer(char *name) { 52 piStuff *pi = malloc(sizeof(piStuff)); 53 54 if(!pi) return NULL; 55 pi->signingKey = NULL; 56 CFStringRef cfName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman); 57 pi->fpi = SOSCreateFullPeerInfoFromName(cfName, &pi->signingKey, NULL); 58 CFReleaseSafe(cfName); 59 pi->pi = SOSFullPeerInfoGetPeerInfo(pi->fpi); 60 pi->resignation_ticket = SOSPeerInfoCreateRetirementTicket(kCFAllocatorDefault, pi->signingKey, pi->pi, NULL); 61 return pi; 62} 63 64static inline bool retire_me(piStuff *pi, size_t seconds) { 65 return SOSPeerInfoRetireRetirementTicket(seconds, pi->resignation_ticket); 66} 67 68// Copied from SOSPeerInfo.c 69static CFStringRef sFlatticket = CFSTR("flatticket"); 70static CFStringRef sSignature = CFSTR("RetirementPsig"); 71static CFStringRef sPeerid = CFSTR("peerid"); 72 73 74static inline bool chkBasicTicket(piStuff *pi) { 75 return CFEqual(SOSPeerInfoInspectRetirementTicket(pi->resignation_ticket, NULL), SOSPeerInfoGetPeerID(pi->pi)); 76} 77 78static bool in_between_time(CFDateRef before, piStuff *pi, CFDateRef after) { 79 CFDateRef during = SOSPeerInfoGetRetirementDate(pi->resignation_ticket); 80 CFTimeInterval time1 = CFDateGetTimeIntervalSinceDate(before, during); 81 CFTimeInterval time2 = CFDateGetTimeIntervalSinceDate(during, after); 82 CFReleaseNull(during); 83 if(time1 >= 0.0) return false; 84 if(time2 >= 0.0) return false; 85 return true; 86} 87 88static void tests(void) 89{ 90 CFDateRef before_time = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent()); 91 sleep(1); 92 piStuff *iPhone = makeSimplePeer("iPhone"); 93 piStuff *iPad = makeSimplePeer("iPad"); 94 piStuff *iMac = makeSimplePeer("iMac"); 95 piStuff *iDrone = makeSimplePeer("iDrone"); 96 sleep(1); 97 CFDateRef after_time = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent()); 98 99 ok(in_between_time(before_time, iPhone, after_time), "retirement date recorded correctly"); 100 CFReleaseSafe(before_time); 101 CFReleaseSafe(after_time); 102 ok(chkBasicTicket(iPhone), "peer ID's Match"); 103 ok(chkBasicTicket(iPad), "peer ID's Match"); 104 ok(chkBasicTicket(iMac), "peer ID's Match"); 105 ok(chkBasicTicket(iDrone), "peer ID's Match"); 106 107 // ok(miss_signature(iDrone, iPad), "signature failure detected"); 108 109 ok(!retire_me(iPhone, 10000), "ticket still valid"); 110 sleep(2); 111 ok(retire_me(iPhone, 1), "ticket not valid"); 112 113 CFDateRef retdate = NULL; 114 ok((retdate = SOSPeerInfoGetRetirementDate(iPhone->resignation_ticket)) != NULL, "got retirement date %@", retdate); 115 CFReleaseSafe(retdate); 116 117#if 0 118 CFDateRef appdate = NULL; 119 ok((appdate = SOSPeerInfoGetApplicationDate(iPhone->resignation_ticket)) != NULL, "got application date %@", appdate); 120 CFReleaseSafe(appdate); 121#endif 122} 123 124static int kTestTestCount = 8; 125 126int sc_130_resignationticket(int argc, char *const *argv) 127{ 128 plan_tests(kTestTestCount); 129 130 tests(); 131 132 return 0; 133} 134