Skip to content

Commit 5b8bc83

Browse files
author
Alex Vlasov
committed
allow to choose AES cypher mode for BIP32 keystore
1 parent 70e95d0 commit 5b8bc83

File tree

3 files changed

+38
-28
lines changed

3 files changed

+38
-28
lines changed

web3swift/Contract/Classes/EventFiltering.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ internal func parseReceiptForLogs(receipt: TransactionReceipt, contract: Contrac
140140
let decodedLogs = allLogs.compactMap({ (log) -> EventParserResultProtocol? in
141141
let (n, d) = contract.parseEvent(log)
142142
guard let evName = n, let evData = d else {return nil}
143-
return EventParserResult(eventName: evName, transactionReceipt: receipt, contractAddress: log.address, decodedResult: evData)
143+
var result = EventParserResult(eventName: evName, transactionReceipt: receipt, contractAddress: log.address, decodedResult: evData)
144+
result.eventLog = log
145+
return result
144146
}).filter { (res:EventParserResultProtocol?) -> Bool in
145147
return res != nil && res?.eventName == eventName
146148
}

web3swift/KeystoreManager/Classes/BIP32Keystore.swift

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public class BIP32Keystore: AbstractKeystore {
9090
try createNewAccount(parentNode: rootNode, password: password)
9191
}
9292

93-
public func createNewAccount(parentNode: HDNode, password: String = "BANKEXFOUNDATION") throws {
93+
public func createNewAccount(parentNode: HDNode, password: String = "BANKEXFOUNDATION", aesMode: String = "aes-128-cbc") throws {
9494
var newIndex = UInt32(0)
9595
for (p, _) in paths {
9696
guard let idx = UInt32(p.components(separatedBy: "/").last!) else {continue}
@@ -109,7 +109,7 @@ public class BIP32Keystore: AbstractKeystore {
109109
}
110110
paths[newPath] = newAddress
111111
guard let serializedRootNode = parentNode.serialize(serializePublic: false) else {throw AbstractKeystoreError.keyDerivationError}
112-
try encryptDataToStorage(password, data: serializedRootNode)
112+
try encryptDataToStorage(password, data: serializedRootNode, aesMode: aesMode)
113113
}
114114

115115
public func createNewCustomChildAccount(password: String = "BANKEXFOUNDATION", path: String) throws {
@@ -146,10 +146,10 @@ public class BIP32Keystore: AbstractKeystore {
146146
}
147147
paths[newPath] = newAddress
148148
guard let serializedRootNode = rootNode.serialize(serializePublic: false) else {throw AbstractKeystoreError.keyDerivationError}
149-
try encryptDataToStorage(password, data: serializedRootNode)
149+
try encryptDataToStorage(password, data: serializedRootNode, aesMode: self.keystoreParams!.crypto.cipher)
150150
}
151151

152-
fileprivate func encryptDataToStorage(_ password: String, data: Data?, dkLen: Int=32, N: Int = 4096, R: Int = 6, P: Int = 1) throws {
152+
fileprivate func encryptDataToStorage(_ password: String, data: Data?, dkLen: Int=32, N: Int = 4096, R: Int = 6, P: Int = 1, aesMode: String = "aes-128-cbc") throws {
153153
if (data == nil) {
154154
throw AbstractKeystoreError.encryptionError("Encryption without key data")
155155
}
@@ -162,16 +162,27 @@ public class BIP32Keystore: AbstractKeystore {
162162
let last16bytes = derivedKey[(derivedKey.count - 16)...(derivedKey.count-1)]
163163
let encryptionKey = derivedKey[0...15]
164164
guard let IV = Data.randomBytes(length: 16) else {throw AbstractKeystoreError.noEntropyError}
165-
let aecCipher = try? AES(key: encryptionKey.bytes, blockMode: CBC(iv: IV.bytes), padding: .pkcs7)
166-
guard let encryptedKey = try aecCipher?.encrypt(data!.bytes) else {throw AbstractKeystoreError.aesError}
165+
var aesCipher : AES?
166+
switch aesMode {
167+
case "aes-128-cbc":
168+
aesCipher = try? AES(key: encryptionKey.bytes, blockMode: CBC(iv: IV.bytes), padding: .pkcs7)
169+
case "aes-128-ctr":
170+
aesCipher = try? AES(key: encryptionKey.bytes, blockMode: CTR(iv: IV.bytes), padding: .pkcs7)
171+
default:
172+
aesCipher = nil
173+
}
174+
if aesCipher == nil {
175+
throw AbstractKeystoreError.aesError
176+
}
177+
guard let encryptedKey = try aesCipher?.encrypt(data!.bytes) else {throw AbstractKeystoreError.aesError}
167178
let encryptedKeyData = Data(bytes:encryptedKey)
168179
var dataForMAC = Data()
169180
dataForMAC.append(last16bytes)
170181
dataForMAC.append(encryptedKeyData)
171182
let mac = dataForMAC.sha3(.keccak256)
172183
let kdfparams = KdfParamsV3(salt: saltData.toHexString(), dklen: dkLen, n: N, p: P, r: R, c: nil, prf: nil)
173184
let cipherparams = CipherParamsV3(iv: IV.toHexString())
174-
let crypto = CryptoParamsV3(ciphertext: encryptedKeyData.toHexString(), cipher: "aes-128-cbc", cipherparams: cipherparams, kdf: "scrypt", kdfparams: kdfparams, mac: mac.toHexString(), version: nil)
185+
let crypto = CryptoParamsV3(ciphertext: encryptedKeyData.toHexString(), cipher: aesMode, cipherparams: cipherparams, kdf: "scrypt", kdfparams: kdfparams, mac: mac.toHexString(), version: nil)
175186
var pathToAddress = [String:String]()
176187
for (path, address) in paths {
177188
pathToAddress[path] = address.address
@@ -188,7 +199,7 @@ public class BIP32Keystore: AbstractKeystore {
188199
throw AbstractKeystoreError.encryptionError("Failed to decrypt a keystore")
189200
}
190201
defer {Data.zero(&keyData!)}
191-
try self.encryptDataToStorage(newPassword, data: keyData!)
202+
try self.encryptDataToStorage(newPassword, data: keyData!, aesMode: self.keystoreParams!.crypto.cipher)
192203
}
193204

194205
fileprivate func getPrefixNodeData(_ password: String) throws -> Data? {
@@ -206,14 +217,14 @@ public class BIP32Keystore: AbstractKeystore {
206217
guard let algo = keystorePars.crypto.kdfparams.prf else {return nil}
207218
var hashVariant:HMAC.Variant?;
208219
switch algo {
209-
case "hmac-sha256" :
210-
hashVariant = HMAC.Variant.sha256
211-
case "hmac-sha384" :
212-
hashVariant = HMAC.Variant.sha384
213-
case "hmac-sha512" :
214-
hashVariant = HMAC.Variant.sha512
215-
default:
216-
hashVariant = nil
220+
case "hmac-sha256" :
221+
hashVariant = HMAC.Variant.sha256
222+
case "hmac-sha384" :
223+
hashVariant = HMAC.Variant.sha384
224+
case "hmac-sha512" :
225+
hashVariant = HMAC.Variant.sha512
226+
default:
227+
hashVariant = nil
217228
}
218229
guard (hashVariant != nil) else {return nil}
219230
guard let c = keystorePars.crypto.kdfparams.c else {return nil}
@@ -237,14 +248,14 @@ public class BIP32Keystore: AbstractKeystore {
237248
guard let IV = Data.fromHex(keystorePars.crypto.cipherparams.iv) else {return nil}
238249
var decryptedPK:Array<UInt8>?
239250
switch cipher {
240-
case "aes-128-ctr":
241-
guard let aesCipher = try? AES(key: decryptionKey.bytes, blockMode: CTR(iv: IV.bytes), padding: .pkcs7) else {return nil}
242-
decryptedPK = try aesCipher.decrypt(cipherText.bytes)
243-
case "aes-128-cbc":
244-
guard let aesCipher = try? AES(key: decryptionKey.bytes, blockMode: CBC(iv: IV.bytes), padding: .pkcs7) else {return nil}
245-
decryptedPK = try? aesCipher.decrypt(cipherText.bytes)
246-
default:
247-
return nil
251+
case "aes-128-ctr":
252+
guard let aesCipher = try? AES(key: decryptionKey.bytes, blockMode: CTR(iv: IV.bytes), padding: .pkcs7) else {return nil}
253+
decryptedPK = try aesCipher.decrypt(cipherText.bytes)
254+
case "aes-128-cbc":
255+
guard let aesCipher = try? AES(key: decryptionKey.bytes, blockMode: CBC(iv: IV.bytes), padding: .pkcs7) else {return nil}
256+
decryptedPK = try? aesCipher.decrypt(cipherText.bytes)
257+
default:
258+
return nil
248259
}
249260
guard decryptedPK != nil else {return nil}
250261
guard decryptedPK?.count == 82 else {return nil}

web3swift/Web3/Classes/Web3+EventParser.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,6 @@ extension web3.web3contract.EventParser {
219219

220220
}
221221

222-
223-
224-
225222
extension web3.web3contract {
226223
public func getIndexedEvents(eventName: String?, filter: EventFilter) -> Result<[EventParserResultProtocol], Web3Error> {
227224
guard let rawContract = self.contract as? ContractV2 else {return Result.failure(Web3Error.nodeError("ABIv1 is not supported for this method"))}

0 commit comments

Comments
 (0)