]> git.saurik.com Git - apple/security.git/blob - keychain/SecureObjectSync/Regressions/sc-130-resignationticket.c
Security-59754.41.1.tar.gz
[apple/security.git] / keychain / SecureObjectSync / Regressions / sc-130-resignationticket.c
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 #include "keychain/SecureObjectSync/SOSPeerInfoDER.h"
29 #include "keychain/SecureObjectSync/SOSCircle.h"
30 #include <Security/SecureObjectSync/SOSPeerInfo.h>
31 #include "keychain/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
44 #if SOS_ENABLED
45
46 typedef struct piStuff_t {
47 SecKeyRef signingKey;
48 SecKeyRef octagonSigningKey;
49 SecKeyRef octagonEncryptionKey;
50 SOSFullPeerInfoRef fpi;
51 SOSPeerInfoRef pi;
52 SOSPeerInfoRef resignation_ticket;
53 } piStuff;
54
55 static piStuff *makeSimplePeer(char *name) {
56 piStuff *pi = malloc(sizeof(piStuff));
57
58 if(!pi) return NULL;
59 pi->signingKey = NULL;
60 CFStringRef cfName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman);
61 pi->fpi = SOSCreateFullPeerInfoFromName(cfName, &pi->signingKey, &pi->octagonSigningKey, &pi->octagonEncryptionKey, NULL);
62 CFReleaseSafe(cfName);
63 pi->pi = SOSFullPeerInfoGetPeerInfo(pi->fpi);
64 pi->resignation_ticket = SOSPeerInfoCreateRetirementTicket(kCFAllocatorDefault, pi->signingKey, pi->pi, NULL);
65 return pi;
66 }
67
68 static void freeSimplePeer(piStuff *pi)
69 {
70 CFReleaseSafe(pi->fpi);
71 CFReleaseSafe(pi->signingKey);
72 CFReleaseSafe(pi->octagonSigningKey);
73 CFReleaseSafe(pi->octagonEncryptionKey);
74 CFReleaseSafe(pi->resignation_ticket);
75 free(pi);
76 }
77
78 static inline bool retire_me(piStuff *pi, size_t seconds) {
79 return SOSPeerInfoRetireRetirementTicket(seconds, pi->resignation_ticket);
80 }
81
82
83 static inline bool chkBasicTicket(piStuff *pi) {
84 return CFEqual(SOSPeerInfoInspectRetirementTicket(pi->resignation_ticket, NULL), SOSPeerInfoGetPeerID(pi->pi));
85 }
86
87 static bool in_between_time(CFDateRef before, piStuff *pi, CFDateRef after) {
88 CFDateRef during = SOSPeerInfoGetRetirementDate(pi->resignation_ticket);
89 CFTimeInterval time1 = CFDateGetTimeIntervalSinceDate(before, during);
90 CFTimeInterval time2 = CFDateGetTimeIntervalSinceDate(during, after);
91 CFReleaseNull(during);
92 if(time1 >= 0.0) return false;
93 if(time2 >= 0.0) return false;
94 return true;
95 }
96
97 static bool PeerInfoRoundTrip(SOSPeerInfoRef pi) {
98 bool retval = false;
99 size_t size = SOSPeerInfoGetDEREncodedSize(pi, NULL);
100 uint8_t buffer[size];
101 const uint8_t *buffer_p = SOSPeerInfoEncodeToDER(pi, NULL, buffer, buffer + sizeof(buffer));
102 ok(buffer_p != NULL, "encode");
103 if(buffer_p == NULL) return false;
104 SOSPeerInfoRef pi2 = SOSPeerInfoCreateFromDER(NULL, NULL, &buffer_p, buffer + sizeof(buffer));
105 ok(pi2 != NULL, "decode");
106 if(!pi2) return false;
107 ok(CFEqual(pi, pi2), "Decode matches");
108 if(CFEqual(pi, pi2)) retval = true;
109 CFReleaseNull(pi2);
110 return retval;
111 }
112
113 static void tests(void)
114 {
115 CFDateRef before_time = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
116 sleep(1);
117 piStuff *iPhone = makeSimplePeer("iPhone");
118 piStuff *iPad = makeSimplePeer("iPad");
119 piStuff *iMac = makeSimplePeer("iMac");
120 piStuff *iDrone = makeSimplePeer("iDrone");
121 sleep(1);
122 CFDateRef after_time = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
123
124 ok(in_between_time(before_time, iPhone, after_time), "retirement date recorded correctly");
125 CFReleaseSafe(before_time);
126 CFReleaseSafe(after_time);
127 ok(chkBasicTicket(iPhone), "peer ID's Match");
128 ok(chkBasicTicket(iPad), "peer ID's Match");
129 ok(chkBasicTicket(iMac), "peer ID's Match");
130 ok(chkBasicTicket(iDrone), "peer ID's Match");
131
132 // ok(miss_signature(iDrone, iPad), "signature failure detected");
133
134 ok(!retire_me(iPhone, 10000), "ticket still valid");
135 sleep(2);
136 ok(retire_me(iPhone, 1), "ticket not valid");
137
138 CFDateRef retdate = SOSPeerInfoGetRetirementDate(iPhone->resignation_ticket);
139 ok(retdate != NULL, "got retirement date %@", retdate);
140 CFReleaseSafe(retdate);
141
142 ok(PeerInfoRoundTrip(iPhone->resignation_ticket), "retirement ticket safely DERs");
143 #if 0
144 CFDateRef appdate = NULL;
145 ok((appdate = SOSPeerInfoGetApplicationDate(iPhone->resignation_ticket)) != NULL, "got application date %@", appdate);
146 CFReleaseSafe(appdate);
147 #endif
148
149 freeSimplePeer(iPhone);
150 freeSimplePeer(iPad);
151 freeSimplePeer(iMac);
152 freeSimplePeer(iDrone);
153 }
154
155 #endif
156
157 int sc_130_resignationticket(int argc, char *const *argv)
158 {
159 #if SOS_ENABLED
160 plan_tests(12);
161 tests();
162 #else
163 plan_tests(0);
164 #endif
165 return 0;
166 }