]> git.saurik.com Git - apple/security.git/blame - OSX/sec/SOSCircle/SecureObjectSync/SOSGenCount.c
Security-57740.20.22.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSGenCount.c
CommitLineData
5c19dc3a
A
1//
2// SOSGenCount.c
3// sec
4//
5// Created by Richard Murphy on 1/29/15.
6//
7//
8
9#include "SOSGenCount.h"
10#include <utilities/SecCFWrappers.h>
11#include <CoreFoundation/CFLocale.h>
12
13static CFAbsoluteTime SOSGenerationCountGetDateBits(int64_t genValue) {
14 return (uint32_t) ((((uint64_t) genValue) >> 32) << 1);
15}
16
17void SOSGenerationCountWithDescription(SOSGenCountRef gen, void (^operation)(CFStringRef description)) {
18 CFStringRef description = SOSGenerationCountCopyDescription(gen);
19
20 operation(description);
21
22 CFReleaseSafe(description);
23}
24
25CFStringRef SOSGenerationCountCopyDescription(SOSGenCountRef gen) {
26 int64_t value = SOSGetGenerationSint(gen);
27
28 CFMutableStringRef gcDecsription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("["));
29
30 withStringOfAbsoluteTime(SOSGenerationCountGetDateBits(value), ^(CFStringRef decription) {
31 CFStringAppend(gcDecsription, decription);
32 });
33
34 CFStringAppendFormat(gcDecsription, NULL, CFSTR(" %u]"), (uint32_t)(value & 0xFFFFFFFF));
35
36 return gcDecsription;
37}
38
39int64_t SOSGetGenerationSint(SOSGenCountRef gen) {
40 int64_t value;
41 if(!gen) return 0;
42 CFNumberGetValue(gen, kCFNumberSInt64Type, &value);
43 return value;
44}
45
46static int64_t sosGenerationSetHighBits(int64_t value, int32_t high_31)
47{
48 value &= 0xFFFFFFFF; // Keep the low 32 bits.
49 value |= ((int64_t) high_31) << 32;
50
51 return value;
52}
53
54static SOSGenCountRef sosGenerationCreateOrIncrement(SOSGenCountRef gen) {
55 int64_t value = 0;
56
57 if(gen) {
58 value = SOSGetGenerationSint(gen);
59 }
60
61 if((value >> 32) == 0) {
62 uint32_t seconds = CFAbsoluteTimeGetCurrent(); // seconds
63 value = sosGenerationSetHighBits(value, (seconds >> 1));
64 }
65
66 value++;
67 return CFNumberCreate(NULL, kCFNumberSInt64Type, &value);
68}
69
70SOSGenCountRef SOSGenerationCreate() {
71 return sosGenerationCreateOrIncrement(NULL);
72}
73
e0e0d90e
A
74
75// We need this for a circle gencount test
76SOSGenCountRef SOSGenerationCreateWithValue(int64_t value) {
77 return CFNumberCreate(NULL, kCFNumberSInt64Type, &value);
78}
79
5c19dc3a
A
80SOSGenCountRef SOSGenerationIncrementAndCreate(SOSGenCountRef gen) {
81 return sosGenerationCreateOrIncrement(gen);
82}
83
84SOSGenCountRef SOSGenerationCopy(SOSGenCountRef gen) {
85 if(!gen) return NULL;
86 int64_t value = SOSGetGenerationSint(gen);
87 return CFNumberCreate(NULL, kCFNumberSInt64Type, &value);
88}
89
fa7225c8
A
90// Is current older than proposed?
91bool SOSGenerationIsOlder(SOSGenCountRef older, SOSGenCountRef newer) {
92 switch(CFNumberCompare(older, newer, NULL)) {
93 case kCFCompareLessThan: return true;
94 case kCFCompareEqualTo: return false;
95 case kCFCompareGreaterThan: return false;
96 }
97 return false;
5c19dc3a 98}
e0e0d90e 99
fa7225c8
A
100// Is current older than proposed?
101static bool SOSGenerationIsOlderOrEqual(SOSGenCountRef older, SOSGenCountRef newer) {
102 switch(CFNumberCompare(older, newer, NULL)) {
103 case kCFCompareLessThan: return true;
104 case kCFCompareEqualTo: return true;
105 case kCFCompareGreaterThan: return false;
106 }
107 return false;
108}
109
110
e0e0d90e
A
111SOSGenCountRef SOSGenerationCreateWithBaseline(SOSGenCountRef reference) {
112 SOSGenCountRef retval = SOSGenerationCreate();
fa7225c8 113 if(SOSGenerationIsOlderOrEqual(retval, reference)) {
e0e0d90e
A
114 CFReleaseNull(retval);
115 retval = SOSGenerationIncrementAndCreate(reference);
116 }
117 return retval;
118}