-
-
Notifications
You must be signed in to change notification settings - Fork 118
/
Copy pathAddNewSafeHelper.m
206 lines (174 loc) · 9.02 KB
/
AddNewSafeHelper.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
//
// AddNewSafeHelper.m
// Strongbox
//
// Created by Mark on 05/12/2018.
// Copyright © 2014-2021 Mark McGuill. All rights reserved.
//
#import "AddNewSafeHelper.h"
#import "Alerts.h"
#import "KeyFileManagement.h"
#import "LocalDeviceStorageProvider.h"
#import "YubiManager.h"
#import "BookmarksHelper.h"
#import "AppPreferences.h"
#import "SVProgressHUD.h"
#import "Serializator.h"
#import "SampleItemsGenerator.h"
#import "Strongbox-Swift.h"
const DatabaseFormat kDefaultFormat = kKeePass4;
@implementation AddNewSafeHelper
+ (void)createNewExpressDatabase:(UIViewController*)vc
name:(NSString *)name
password:(NSString *)password
completion:(void (^)(BOOL userCancelled, DatabasePreferences* metadata, NSData* initialSnapshot, NSError* error))completion {
[AddNewSafeHelper createNewExpressDatabase:vc name:name password:password forceLocal:NO completion:completion];
}
+ (void)createNewExpressDatabase:(UIViewController*)vc
name:(NSString *)name
password:(NSString *)password
forceLocal:(BOOL)forceLocal
completion:(void (^)(BOOL userCancelled, DatabasePreferences* metadata, NSData* initialSnapshot, NSError* error))completion {
NSError* error;
DatabaseModel *database = getNewDatabase(password, nil, nil, nil, nil, kDefaultFormat, &error);
if(!database) {
completion(NO, nil, nil, error);
return;
}
[AddNewSafeHelper createNewExpressDatabase:vc name:name model:database forceLocal:forceLocal completion:completion];
}
+ (void)createNewExpressDatabase:(UIViewController *)vc
name:(NSString *)name
model:(DatabaseModel *)model
completion:(void (^)(BOOL, DatabasePreferences * _Nonnull, NSData * _Nonnull, NSError * _Nonnull))completion {
[AddNewSafeHelper createNewExpressDatabase:vc name:name model:model forceLocal:NO completion:completion];
}
+ (void)createNewExpressDatabase:(UIViewController*)vc
name:(NSString *)name
model:(DatabaseModel *)model
forceLocal:(BOOL)forceLocal
completion:(void (^)(BOOL userCancelled, DatabasePreferences* metadata, NSData* initialSnapshot, NSError* error))completion {
#ifndef NO_NETWORKING
BOOL useCloudKitForStorage = !forceLocal && !AppPreferences.sharedInstance.disableNetworkBasedFeatures && CloudKitDatabasesInteractor.shared.fastIsAvailable;
id<SafeStorageProvider> provider = useCloudKitForStorage ? CloudKitStorageProvider.sharedInstance : LocalDeviceStorageProvider.sharedInstance;
#else
id<SafeStorageProvider> provider = LocalDeviceStorageProvider.sharedInstance;
#endif
[AddNewSafeHelper createDatabase:vc
name:name
keyFileBookmark:nil
keyFileFileName:nil
database:model
provider:provider
parentFolder:nil
yubiKeyConfig:nil
completion:completion];
}
+ (void)createNewDatabase:(UIViewController *)vc
name:(NSString *)name
password:(NSString *)password
keyFileBookmark:(NSString *)keyFileBookmark
keyFileFileName:(NSString *)keyFileFileName
onceOffKeyFileData:(NSData *)onceOffKeyFileData
yubiKeyConfig:(YubiKeyHardwareConfiguration *)yubiKeyConfig
storageParams:(SelectedStorageParameters *)storageParams
format:(DatabaseFormat)format
completion:(nonnull void (^)(BOOL, DatabasePreferences * _Nullable, NSData * _Nullable, NSError * _Nullable))completion {
NSError* error;
DatabaseModel *database = getNewDatabase(password, keyFileBookmark, keyFileFileName, onceOffKeyFileData, yubiKeyConfig, format, &error);
if(!database) {
completion(NO, nil, nil, error);
return;
}
[AddNewSafeHelper createDatabase:vc
name:name
keyFileBookmark:keyFileBookmark
keyFileFileName:keyFileFileName
database:database
provider:storageParams.provider
parentFolder:storageParams.parentFolder
yubiKeyConfig:yubiKeyConfig
completion:completion];
}
+ (void)createDatabase:(UIViewController*)vc
name:(NSString*)name
keyFileBookmark:(NSString *)keyFileBookmark
keyFileFileName:(NSString *)keyFileFileName
database:(DatabaseModel*)database
provider:(id<SafeStorageProvider>)provider
parentFolder:(NSObject*)parentFolder
yubiKeyConfig:(YubiKeyHardwareConfiguration *)yubiKeyConfig
completion:(void (^)(BOOL userCancelled, DatabasePreferences* metadata, NSData* initialSnapshot, NSError* error))completion {
dispatch_async(dispatch_get_main_queue(), ^(void) {
[SVProgressHUD showWithStatus:NSLocalizedString(@"generic_encrypting", @"Encrypting")];
});
DatabaseFormat format = database.originalFormat;
dispatch_async(dispatch_get_global_queue(0L, DISPATCH_QUEUE_PRIORITY_DEFAULT), ^{
NSOutputStream* outputStream = [NSOutputStream outputStreamToMemory];
[outputStream open];
[Serializator getAsData:database format:format outputStream:outputStream completion:^(BOOL userCancelled, NSString * _Nullable debugXml, NSError * _Nullable error) {
if (userCancelled || error) {
completion(userCancelled, nil, nil, error);
return;
}
[outputStream close];
NSData* data = [outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
dispatch_async(dispatch_get_main_queue(), ^(void) {
[SVProgressHUD dismiss];
[SVProgressHUD showWithStatus:NSLocalizedString(@"generic_saving_ellipsis", @"Saving...")];
NSString* filename = [NSString stringWithFormat:@"%@.%@", name, [Serializator getDefaultFileExtensionForFormat:format]];
[provider create:name
fileName:filename
data:data
parentFolder:parentFolder
viewController:vc
completion:^(DatabasePreferences *metadata, NSError *error) {
[metadata setKeyFile:keyFileBookmark keyFileFileName:keyFileFileName];
metadata.likelyFormat = format;
metadata.nextGenPrimaryYubiKeyConfig = yubiKeyConfig;
dispatch_async(dispatch_get_main_queue(), ^(void) {
[SVProgressHUD dismiss];
completion(NO, metadata, data, error);
});
}];
});
}];
});
}
static DatabaseModel* getNewDatabase(NSString* password,
NSString* keyFileBookmark,
NSString* keyFileFileName,
NSData* onceOffKeyFileData,
YubiKeyHardwareConfiguration *yubiConfig,
DatabaseFormat format,
NSError** error) {
NSData* keyFileDigest = nil;
if ( keyFileBookmark || keyFileFileName || onceOffKeyFileData ) {
keyFileDigest = [KeyFileManagement getDigestFromSources:keyFileBookmark
fallbackUrl:nil
keyFileFileName:keyFileFileName
onceOffKeyFileData:onceOffKeyFileData
format:format
resolvedKeyFileUrl:nil
updatedBookmark:nil
error:error];
if ( *error ) {
return nil;
}
}
CompositeKeyFactors* ckf;
if ( yubiConfig && yubiConfig.mode != kNoYubiKey ) {
ckf = [CompositeKeyFactors password:password
keyFileDigest:keyFileDigest
yubiKeyCR:^(NSData * _Nonnull challenge, YubiKeyCRResponseBlock _Nonnull completion) {
[YubiManager.sharedInstance getResponse:yubiConfig challenge:challenge completion:completion];
}];
}
else {
ckf = [CompositeKeyFactors password:password keyFileDigest:keyFileDigest];
}
DatabaseModel* database = [[DatabaseModel alloc] initWithFormat:format compositeKeyFactors:ckf];
[SampleItemsGenerator addSampleGroupAndRecordToRoot:database passwordConfig:AppPreferences.sharedInstance.passwordGenerationConfig];
return database;
}
@end