]> git.saurik.com Git - apple/security.git/blob - keychain/ckks/CKKSRecordHolder.m
Security-58286.1.32.tar.gz
[apple/security.git] / keychain / ckks / CKKSRecordHolder.m
1 /*
2 * Copyright (c) 2017 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 #include <AssertMacros.h>
25
26 #import <Foundation/Foundation.h>
27 #import "CKKSItem.h"
28 #import "CKKSSIV.h"
29
30 #include <utilities/SecDb.h>
31 #include <securityd/SecDbItem.h>
32 #include <securityd/SecItemSchema.h>
33
34 #if OCTAGON
35
36 #import <CloudKit/CloudKit.h>
37
38
39 @implementation CKKSCKRecordHolder
40
41 - (instancetype) initWithCKRecord: (CKRecord*) record {
42 if(self = [super init]) {
43 self.zoneID = record.recordID.zoneID;
44 [self setFromCKRecord:record];
45 }
46 return self;
47 }
48
49 - (instancetype)initWithCKRecordType: (NSString*) recordType encodedCKRecord: (NSData*) encodedCKRecord zoneID:(CKRecordZoneID*)zoneID {
50 if(self = [super init]) {
51 _zoneID = zoneID;
52 _ckRecordType = recordType;
53 _encodedCKRecord = encodedCKRecord;
54
55 if(self.encodedCKRecord && ![self.storedCKRecord.recordID.zoneID isEqual: self.zoneID]) {
56 secerror("ckks: mismatching zone ids in a single record: %@ and %@", self.zoneID, self.storedCKRecord.recordID.zoneID);
57 }
58 }
59 return self;
60 }
61
62 - (CKRecord*) storedCKRecord {
63 if(!_encodedCKRecord) {
64 return nil;
65 }
66 NSKeyedUnarchiver *coder = [[NSKeyedUnarchiver alloc] initForReadingWithData:_encodedCKRecord];
67 coder.requiresSecureCoding = YES;
68 CKRecord* ckRecord = [[CKRecord alloc] initWithCoder:coder];
69 [coder finishDecoding];
70
71 return ckRecord;
72 }
73
74 - (void) setStoredCKRecord: (CKRecord*) ckRecord {
75 if(!ckRecord) {
76 _encodedCKRecord = nil;
77 return;
78 }
79 self.zoneID = ckRecord.recordID.zoneID;
80 self.ckRecordType = ckRecord.recordType;
81
82 NSMutableData* data = [NSMutableData data];
83 NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
84 [ckRecord encodeWithCoder:archiver];
85 [archiver finishEncoding];
86 _encodedCKRecord = data;
87 }
88
89 - (CKRecord*) CKRecordWithZoneID: (CKRecordZoneID*) zoneID {
90 CKRecordID* recordID = [[CKRecordID alloc] initWithRecordName: [self CKRecordName] zoneID: zoneID];
91 CKRecord* record = nil;
92
93 if(self.encodedCKRecord == nil) {
94 record = [[CKRecord alloc] initWithRecordType:self.ckRecordType recordID:recordID];
95 } else {
96 record = self.storedCKRecord;
97 }
98
99 [self updateCKRecord:record zoneID:zoneID];
100
101 self.storedCKRecord = record;
102 return record;
103 }
104
105 - (NSString*) CKRecordName {
106 @throw [NSException exceptionWithName:NSInternalInconsistencyException
107 reason:[NSString stringWithFormat:@"%@ must override %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]
108 userInfo:nil];
109 }
110 - (CKRecord*) updateCKRecord: (CKRecord*) record zoneID: (CKRecordZoneID*) zoneID {
111 @throw [NSException exceptionWithName:NSInternalInconsistencyException
112 reason:[NSString stringWithFormat:@"%@ must override %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]
113 userInfo:nil];
114 }
115 - (void) setFromCKRecord: (CKRecord*) record {
116 @throw [NSException exceptionWithName:NSInternalInconsistencyException
117 reason:[NSString stringWithFormat:@"%@ must override %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]
118 userInfo:nil];
119 }
120 - (bool) matchesCKRecord: (CKRecord*) record {
121 @throw [NSException exceptionWithName:NSInternalInconsistencyException
122 reason:[NSString stringWithFormat:@"%@ must override %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]
123 userInfo:nil];
124 }
125
126 - (instancetype)copyWithZone:(NSZone *)zone {
127 CKKSCKRecordHolder *rhCopy = [super copyWithZone:zone];
128 rhCopy->_zoneID = _zoneID;
129 rhCopy->_ckRecordType = _ckRecordType;
130 rhCopy->_encodedCKRecord = _encodedCKRecord;
131 return rhCopy;
132 }
133 @end
134
135 #endif