sc-130-resignationticket.c [plain text]
#include <Security/SecBase.h>
#include <Security/SecItem.h>
#include <Security/SecKey.h>
#include <SOSPeerInfoDER.h>
#include <Security/SecureObjectSync/SOSCircle.h>
#include <Security/SecureObjectSync/SOSPeerInfo.h>
#include <Security/SecureObjectSync/SOSInternal.h>
#include <utilities/SecCFWrappers.h>
#include <CoreFoundation/CoreFoundation.h>
#include <stdlib.h>
#include <unistd.h>
#include "SOSCircle_regressions.h"
#include "SOSRegressionUtilities.h"
typedef struct piStuff_t {
SecKeyRef signingKey;
SecKeyRef octagonSigningKey;
SecKeyRef octagonEncryptionKey;
SOSFullPeerInfoRef fpi;
SOSPeerInfoRef pi;
SOSPeerInfoRef resignation_ticket;
} piStuff;
static piStuff *makeSimplePeer(char *name) {
piStuff *pi = malloc(sizeof(piStuff));
if(!pi) return NULL;
pi->signingKey = NULL;
CFStringRef cfName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman);
pi->fpi = SOSCreateFullPeerInfoFromName(cfName, &pi->signingKey, &pi->octagonSigningKey, &pi->octagonEncryptionKey, NULL);
CFReleaseSafe(cfName);
pi->pi = SOSFullPeerInfoGetPeerInfo(pi->fpi);
pi->resignation_ticket = SOSPeerInfoCreateRetirementTicket(kCFAllocatorDefault, pi->signingKey, pi->pi, NULL);
return pi;
}
static void freeSimplePeer(piStuff *pi)
{
CFReleaseSafe(pi->fpi);
CFReleaseSafe(pi->signingKey);
CFReleaseSafe(pi->octagonSigningKey);
CFReleaseSafe(pi->octagonEncryptionKey);
CFReleaseSafe(pi->resignation_ticket);
free(pi);
}
static inline bool retire_me(piStuff *pi, size_t seconds) {
return SOSPeerInfoRetireRetirementTicket(seconds, pi->resignation_ticket);
}
static inline bool chkBasicTicket(piStuff *pi) {
return CFEqual(SOSPeerInfoInspectRetirementTicket(pi->resignation_ticket, NULL), SOSPeerInfoGetPeerID(pi->pi));
}
static bool in_between_time(CFDateRef before, piStuff *pi, CFDateRef after) {
CFDateRef during = SOSPeerInfoGetRetirementDate(pi->resignation_ticket);
CFTimeInterval time1 = CFDateGetTimeIntervalSinceDate(before, during);
CFTimeInterval time2 = CFDateGetTimeIntervalSinceDate(during, after);
CFReleaseNull(during);
if(time1 >= 0.0) return false;
if(time2 >= 0.0) return false;
return true;
}
static bool PeerInfoRoundTrip(SOSPeerInfoRef pi) {
bool retval = false;
size_t size = SOSPeerInfoGetDEREncodedSize(pi, NULL);
uint8_t buffer[size];
const uint8_t *buffer_p = SOSPeerInfoEncodeToDER(pi, NULL, buffer, buffer + sizeof(buffer));
ok(buffer_p != NULL, "encode");
if(buffer_p == NULL) return false;
SOSPeerInfoRef pi2 = SOSPeerInfoCreateFromDER(NULL, NULL, &buffer_p, buffer + sizeof(buffer));
ok(pi2 != NULL, "decode");
if(!pi2) return false;
ok(CFEqual(pi, pi2), "Decode matches");
if(CFEqual(pi, pi2)) retval = true;
CFReleaseNull(pi2);
return retval;
}
static void tests(void)
{
CFDateRef before_time = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
sleep(1);
piStuff *iPhone = makeSimplePeer("iPhone");
piStuff *iPad = makeSimplePeer("iPad");
piStuff *iMac = makeSimplePeer("iMac");
piStuff *iDrone = makeSimplePeer("iDrone");
sleep(1);
CFDateRef after_time = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
ok(in_between_time(before_time, iPhone, after_time), "retirement date recorded correctly");
CFReleaseSafe(before_time);
CFReleaseSafe(after_time);
ok(chkBasicTicket(iPhone), "peer ID's Match");
ok(chkBasicTicket(iPad), "peer ID's Match");
ok(chkBasicTicket(iMac), "peer ID's Match");
ok(chkBasicTicket(iDrone), "peer ID's Match");
ok(!retire_me(iPhone, 10000), "ticket still valid");
sleep(2);
ok(retire_me(iPhone, 1), "ticket not valid");
CFDateRef retdate = SOSPeerInfoGetRetirementDate(iPhone->resignation_ticket);
ok(retdate != NULL, "got retirement date %@", retdate);
CFReleaseSafe(retdate);
ok(PeerInfoRoundTrip(iPhone->resignation_ticket), "retirement ticket safely DERs");
#if 0
CFDateRef appdate = NULL;
ok((appdate = SOSPeerInfoGetApplicationDate(iPhone->resignation_ticket)) != NULL, "got application date %@", appdate);
CFReleaseSafe(appdate);
#endif
freeSimplePeer(iPhone);
freeSimplePeer(iPad);
freeSimplePeer(iMac);
freeSimplePeer(iDrone);
}
static int kTestTestCount = 12;
int sc_130_resignationticket(int argc, char *const *argv)
{
plan_tests(kTestTestCount);
tests();
return 0;
}