2 // SOSAccountTrustClassicIdentity.m
7 #import <Foundation/Foundation.h>
8 #include <AssertMacros.h>
9 #import "Security/SecureObjectSync/SOSAccountTrustClassic.h"
10 #import "Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h"
11 #import "Security/SecureObjectSync/SOSAccountTrustClassic+Identity.h"
12 #import "Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h"
14 #import "Security/SecureObjectSync/SOSViews.h"
16 @implementation SOSAccountTrustClassic (Identity)
18 -(bool) updateFullPeerInfo:(SOSAccount*)account minimum:(CFSetRef)minimumViews excluded:(CFSetRef)excludedViews
20 if (self.trustedCircle && self.fullPeerInfo) {
21 if(SOSFullPeerInfoUpdateToCurrent(self.fullPeerInfo, minimumViews, excludedViews)) {
22 [self modifyCircle:account.circle_transport err:NULL action:^(SOSCircleRef circle_to_change) {
23 secnotice("circleChange", "Calling SOSCircleUpdatePeerInfo for gestalt change");
24 return SOSCircleUpdatePeerInfo(circle_to_change, self.peerInfo);
32 -(SOSFullPeerInfoRef) getMyFullPeerInfo
34 return self.trustedCircle ? self.fullPeerInfo : NULL;
37 -(bool) fullPeerInfoVerify:(SecKeyRef) privKey err:(CFErrorRef *)error
39 if(!self.fullPeerInfo) return false;
40 SecKeyRef pubKey = SecKeyCreatePublicFromPrivate(privKey);
41 bool retval = SOSPeerInfoApplicationVerify(self.peerInfo, pubKey, error);
42 CFReleaseNull(pubKey);
46 -(bool) hasFullPeerInfo:(CFErrorRef*) error
49 if(![self hasCircle:error]){
52 hasPeer = self.fullPeerInfo != NULL;
55 SOSCreateErrorWithFormat(kSOSErrorPeerNotFound, NULL, error, NULL, CFSTR("No peer for circle"));
60 -(SOSFullPeerInfoRef) CopyAccountIdentityPeerInfo
62 return SOSFullPeerInfoCopyFullPeerInfo(self.fullPeerInfo);
65 - (SecKeyRef)randomPermanentFullECKey:(int)keysize name:(NSString *)name error:(CFErrorRef*)cferror
67 return GeneratePermanentFullECKey(keysize, (__bridge CFStringRef)name, cferror);
70 - (void)ensureOctagonPeerKeys:(SOSKVSCircleStorageTransport*)circleTransport
72 NSString* octagonKeyName;
75 bool changedSelf = false;
77 CFErrorRef copyError = NULL;
78 publicKey = SOSFullPeerInfoCopyOctagonSigningKey(self.fullPeerInfo, ©Error);
80 secerror("circleChange: Error fetching Octagon signing key: %@", copyError);
81 CFReleaseNull(copyError);
84 if (publicKey == NULL) {
85 octagonKeyName = [NSString stringWithFormat:@"Octagon Peer Signing ID for %@", SOSCircleGetName(self.trustedCircle)];
86 CFErrorRef cferror = NULL;
87 SecKeyRef octagonSigningFullKey = [self randomPermanentFullECKey:384 name:octagonKeyName error:&cferror];
88 if(cferror || !octagonSigningFullKey) {
89 secerror("circleChange: Error upgrading Octagon signing key: %@", cferror);
91 SOSFullPeerInfoUpdateOctagonSigningKey(self.fullPeerInfo, octagonSigningFullKey, &cferror);
93 secerror("circleChange: Error upgrading Octagon signing key: %@", cferror);
98 CFReleaseNull(cferror);
99 CFReleaseNull(octagonSigningFullKey);
101 CFReleaseNull(publicKey);
103 CFReleaseNull(copyError);
104 publicKey = SOSFullPeerInfoCopyOctagonEncryptionKey(self.fullPeerInfo, ©Error);
106 secerror("circleChange: Error fetching Octagon encryption key: %@", copyError);
107 CFReleaseNull(copyError);
110 if (publicKey == NULL) {
111 octagonKeyName = [NSString stringWithFormat:@"Octagon Peer Encryption ID for %@", SOSCircleGetName(self.trustedCircle)];
112 CFErrorRef cferror = NULL;
113 SecKeyRef octagonEncryptionFullKey = [self randomPermanentFullECKey:384 name:octagonKeyName error:&cferror];
114 if(cferror || !octagonEncryptionFullKey) {
115 secerror("circleChange: Error upgrading Octagon encryption key: %@", cferror);
118 SOSFullPeerInfoUpdateOctagonEncryptionKey(self.fullPeerInfo, octagonEncryptionFullKey, &cferror);
120 secerror("circleChange: Error upgrading Octagon encryption key: %@", cferror);
125 CFReleaseNull(cferror);
126 CFReleaseNull(octagonEncryptionFullKey);
128 CFReleaseNull(publicKey);
131 [self modifyCircle:circleTransport err:NULL action:^bool (SOSCircleRef circle_to_change) {
132 return SOSCircleUpdatePeerInfo(circle_to_change, SOSFullPeerInfoGetPeerInfo(self.fullPeerInfo));
137 -(bool) ensureFullPeerAvailable:(CFDictionaryRef)gestalt deviceID:(CFStringRef)deviceID backupKey:(CFDataRef)backup err:(CFErrorRef *) error
139 require_action_quiet(self.trustedCircle, fail, SOSCreateErrorWithFormat(kSOSErrorNoCircle, NULL, error, NULL, CFSTR("Don't have circle")));
141 if (self.fullPeerInfo == NULL) {
142 NSString* octagonKeyName;
143 CFStringRef keyName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("ID for %@-%@"), SOSPeerGestaltGetName(gestalt), SOSCircleGetName(self.trustedCircle));
144 SecKeyRef full_key = [self randomPermanentFullECKey:256 name:(__bridge NSString *)keyName error:NULL];
146 octagonKeyName = [@"Octagon Peer Signing " stringByAppendingString:(__bridge NSString*)keyName];
147 SecKeyRef octagonSigningFullKey = [self randomPermanentFullECKey:384 name:octagonKeyName error:NULL];
149 octagonKeyName = [@"Octagon Peer Encryption " stringByAppendingString:(__bridge NSString*)keyName];
150 SecKeyRef octagonEncryptionFullKey = [self randomPermanentFullECKey:384 name:octagonKeyName error:NULL];
152 if (full_key && octagonSigningFullKey && octagonEncryptionFullKey) {
153 CFSetRef initialViews = SOSViewCopyViewSet(kViewSetInitial);
155 self.fullPeerInfo = nil;
156 self.fullPeerInfo = SOSFullPeerInfoCreateWithViews(kCFAllocatorDefault, gestalt, backup, initialViews, full_key, octagonSigningFullKey, octagonEncryptionFullKey, error);
158 CFDictionaryRef v2dictionaryTestUpdates = [self getValueFromExpansion:kSOSTestV2Settings err:NULL];
159 if(v2dictionaryTestUpdates) SOSFullPeerInfoUpdateV2Dictionary(self.fullPeerInfo, v2dictionaryTestUpdates, NULL);
160 CFReleaseNull(initialViews);
161 CFReleaseNull(full_key);
163 CFSetRef pendingDefaultViews = SOSViewCopyViewSet(kViewSetDefault);
164 [self pendEnableViewSet:pendingDefaultViews];
165 CFReleaseNull(pendingDefaultViews);
167 [self setValueInExpansion:kSOSUnsyncedViewsKey value:kCFBooleanTrue err:NULL];
169 if (!self.fullPeerInfo) {
170 secerror("Can't make FullPeerInfo for %@-%@ (%@) - is AKS ok?", SOSPeerGestaltGetName(gestalt), SOSCircleGetName(self.trustedCircle), error ? (void*)*error : (void*)CFSTR("-"));
173 secnotice("fpi", "alert KeychainSyncingOverIDSProxy the fpi is available");
174 notify_post(kSecServerPeerInfoAvailable);
176 SOSFullPeerInfoUpdateDeviceID(self.fullPeerInfo, deviceID, error);
180 secerror("No full_key: %@:", error ? *error : NULL);
184 CFReleaseNull(full_key);
185 CFReleaseNull(octagonSigningFullKey);
186 CFReleaseNull(octagonEncryptionFullKey);
187 CFReleaseNull(keyName);
191 return self.fullPeerInfo != NULL;
193 -(bool) isMyPeerActive:(CFErrorRef*) error
195 return (self.peerInfo ? SOSCircleHasActivePeer(self.trustedCircle, self.peerInfo, error) : false);
198 -(void) purgeIdentity
200 if (self.fullPeerInfo) {
201 // Purge private key but don't return error if we can't.
202 CFErrorRef purgeError = NULL;
203 if (!SOSFullPeerInfoPurgePersistentKey(self.fullPeerInfo, &purgeError)) {
204 secwarning("Couldn't purge persistent key for %@ [%@]", self.fullPeerInfo, purgeError);
206 CFReleaseNull(purgeError);
208 self.fullPeerInfo=nil;