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