-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSecurityQuestionModule.swift
218 lines (206 loc) · 10 KB
/
SecurityQuestionModule.swift
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
207
208
209
210
211
212
213
214
215
216
217
218
import Foundation
#if canImport(lib)
import lib
#endif
public final class SecurityQuestionModule {
private static func generate_new_share(threshold_key: ThresholdKey, questions: String, answer: String, completion: @escaping (Result<GenerateShareStoreResult, Error>) -> Void) {
threshold_key.tkeyQueue.async {
do {
var errorCode: Int32 = -1
let curvePointer = UnsafeMutablePointer<Int8>(mutating: (threshold_key.curveN as NSString).utf8String)
let questionsPointer = UnsafeMutablePointer<Int8>(mutating: (questions as NSString).utf8String)
let answerPointer = UnsafeMutablePointer<Int8>(mutating: (answer as NSString).utf8String)
let ptr = withUnsafeMutablePointer(to: &errorCode, { error in
security_question_generate_new_share(threshold_key.pointer, questionsPointer, answerPointer, curvePointer, error)
})
guard errorCode == 0 else {
throw RuntimeError("Error in SecurityQuestionModule, generate_new_share")
}
let result = try! GenerateShareStoreResult.init(pointer: ptr!)
completion(.success(result))
} catch {
completion(.failure(error))
}
}
}
/// Generates a new security share on an existing `ThresholdKey` object.
/// - Parameters:
/// - threshold_key: The threshold key to act on.
/// - question: The security question.
/// - answer: The answer for the security question.
///
/// - Returns: `GenerateShareStoreResult` object.
///
/// - Throws: `RuntimeError`, indicates invalid parameters was used or invalid threshold key.
public static func generate_new_share(threshold_key: ThresholdKey, questions: String, answer: String ) async throws -> GenerateShareStoreResult {
return try await withCheckedThrowingContinuation {
continuation in
generate_new_share(threshold_key: threshold_key, questions: questions, answer: answer) {
result in
switch result {
case .success(let result):
continuation.resume(returning: result)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
private static func input_share(threshold_key: ThresholdKey, answer: String, completion: @escaping (Result<Bool, Error>) -> Void) {
threshold_key.tkeyQueue.async {
do {
var errorCode: Int32 = -1
let curvePointer = UnsafeMutablePointer<Int8>(mutating: (threshold_key.curveN as NSString).utf8String)
let answerPointer = UnsafeMutablePointer<Int8>(mutating: (answer as NSString).utf8String)
let result = withUnsafeMutablePointer(to: &errorCode, { error in
security_question_input_share(threshold_key.pointer, answerPointer, curvePointer, error)
})
guard errorCode == 0 else {
if errorCode == 2103 || errorCode == 2101 {
return completion(.success(result))
}
throw RuntimeError("Error in SecurityQuestionModule, input_share")
}
completion(.success(result))
} catch {
completion(.failure(error))
}
}
}
/// Inputs a stored security share into an existing `ThresholdKey` object.
/// - Parameters:
/// - threshold_key: The threshold key to act on.
/// - answer: The answer for the security question of the stored share.
///
/// - Returns: `true` on success, `false` otherwise.
///
/// - Throws: `RuntimeError`, indicates invalid parameters was used or invalid threshold key.
public static func input_share(threshold_key: ThresholdKey, answer: String ) async throws -> Bool {
return try await withCheckedThrowingContinuation {
continuation in
input_share(threshold_key: threshold_key, answer: answer) {
result in
switch result {
case .success(let result):
continuation.resume(returning: result)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
private static func change_question_and_answer(threshold_key: ThresholdKey, questions: String, answer: String, completion: @escaping (Result<Bool, Error>) -> Void) {
threshold_key.tkeyQueue.async {
do {
var errorCode: Int32 = -1
let curvePointer = UnsafeMutablePointer<Int8>(mutating: (threshold_key.curveN as NSString).utf8String)
let questionsPointer = UnsafeMutablePointer<Int8>(mutating: (questions as NSString).utf8String)
let answerPointer = UnsafeMutablePointer<Int8>(mutating: (answer as NSString).utf8String)
let result = withUnsafeMutablePointer(to: &errorCode, { error in
security_question_change_question_and_answer(threshold_key.pointer, questionsPointer, answerPointer, curvePointer, error)
})
guard errorCode == 0 else {
throw RuntimeError("Error in SecurityQuestionModule, change_question_and_answer")
}
completion(.success(result))
} catch {
completion(.failure(error))
}
}
}
/// Changes the question and answer for an existing security share on a `ThresholdKey` object.
/// - Parameters:
/// - threshold_key: The threshold key to act on.
/// - question: The security question.
/// - answer: The answer for the security question.
///
/// - Returns: `true` on success, `false` otherwise.
///
/// - Throws: `RuntimeError`, indicates invalid parameters was used or invalid threshold key.
public static func change_question_and_answer(threshold_key: ThresholdKey, questions: String, answer: String ) async throws -> Bool {
return try await withCheckedThrowingContinuation {
continuation in
change_question_and_answer(threshold_key: threshold_key, questions: questions, answer: answer) {
result in
switch result {
case .success(let result):
continuation.resume(returning: result)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
private static func store_answer(threshold_key: ThresholdKey, answer: String, completion: @escaping (Result<Bool, Error>) -> Void) {
threshold_key.tkeyQueue.async {
do {
var errorCode: Int32 = -1
let curvePointer = UnsafeMutablePointer<Int8>(mutating: (threshold_key.curveN as NSString).utf8String)
let answerPointer = UnsafeMutablePointer<Int8>(mutating: (answer as NSString).utf8String)
let result = withUnsafeMutablePointer(to: &errorCode, { error in
security_question_store_answer(threshold_key.pointer, answerPointer, curvePointer, error)
})
guard errorCode == 0 else {
throw RuntimeError("Error in SecurityQuestionModule, store_answer")
}
completion(.success(result))
} catch {
completion(.failure(error))
}
}
}
/// Saves the answer for an existing security share on a `ThresholdKey` object to the tkey store.
/// - Parameters:
/// - threshold_key: The threshold key to act on.
/// - answer: The answer for the security question.
///
/// - Returns: `true` on success, `false` otherwise.
///
/// - Throws: `RuntimeError`, indicates invalid parameters was used or invalid threshold key.
public static func store_answer(threshold_key: ThresholdKey, answer: String ) async throws -> Bool {
return try await withCheckedThrowingContinuation {
continuation in
store_answer(threshold_key: threshold_key, answer: answer) {
result in
switch result {
case .success(let result):
continuation.resume(returning: result)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Retrieves the answer for an existing security share on a `ThresholdKey`.
/// - Returns: `String`.
///
/// - Throws: `RuntimeError`, indicates invalid parameters was used or invalid threshold key.
public static func get_answer(threshold_key: ThresholdKey) throws -> String {
var errorCode: Int32 = -1
let result = withUnsafeMutablePointer(to: &errorCode, { error in
security_question_get_answer(threshold_key.pointer, error)
})
guard errorCode == 0 else {
throw RuntimeError("Error in SecurityQuestionModule, get_answer")
}
let string = String.init(cString: result!)
string_free(result)
return string
}
/// Retrieves the question for an existing security share on a `ThresholdKey`.
/// - Returns: `String`.
///
/// - Throws: `RuntimeError`, indicates invalid parameters was used or invalid threshold key.
public static func get_questions(threshold_key: ThresholdKey) throws -> String {
var errorCode: Int32 = -1
let result = withUnsafeMutablePointer(to: &errorCode, { error in
security_question_get_questions(threshold_key.pointer, error)
})
guard errorCode == 0 else {
throw RuntimeError("Error in SecurityQuestionModule, get_questions")
}
let string = String.init(cString: result!)
string_free(result)
return string
}
}