Skip to content
Snippets Groups Projects
Commit e7b132dd authored by jakobsbode's avatar jakobsbode
Browse files

update travellib

parent 326dfe4e
Branches
No related tags found
No related merge requests found
......@@ -55,7 +55,7 @@ CHECKOUT OPTIONS:
:commit: e6b4597d3bbff232e63f50942318f2b4d3523b1b
:git: https://github.com/MailCore/mailcore2.git
Travellib:
:commit: ec4ccef6bd2420b92e9f81a725ab3ee991671e83
:commit: 9ce858d03a21e139b7bfa069d219942875aec8f1
:git: https://git.imp.fu-berlin.de/jakobsbode/travellib.git
SPEC CHECKSUMS:
......
......@@ -55,7 +55,7 @@ CHECKOUT OPTIONS:
:commit: e6b4597d3bbff232e63f50942318f2b4d3523b1b
:git: https://github.com/MailCore/mailcore2.git
Travellib:
:commit: ec4ccef6bd2420b92e9f81a725ab3ee991671e83
:commit: 9ce858d03a21e139b7bfa069d219942875aec8f1
:git: https://git.imp.fu-berlin.de/jakobsbode/travellib.git
SPEC CHECKSUMS:
......
Source diff could not be displayed: it is too large. Options to address this: view the blob.
......@@ -10,7 +10,6 @@
#endif
#endif
#import "CommonCrypto.h"
#import "Pods-Travellib-umbrella.h"
#import "Pods-TravellibTests-umbrella.h"
#import "Travellib.h"
......
#import <Foundation/Foundation.h>
FOUNDATION_EXPORT double CommonCryptoVersionNumber;
FOUNDATION_EXPORT const unsigned char CommonCryptoVersionString[];
import Foundation
......@@ -9,5 +9,5 @@
import Foundation
public enum TravelError: Error {
case cannotCreateRandom, invalidAlphabet, tooManyBits, invalidData, corruptData
case cannotCreateRandom, invalidAlphabet, tooManyBits, invalidData, corruptData, invalidPassword
}
......@@ -13,43 +13,54 @@ public class Traveler: Codable {
var contacts: [String] = []
var keys: [String : String] = [:]
var salts: [String : String] = [:]
var travelerAddress: String = ""
var travelerKey: String = ""
var pw1 = ""
var pw2 = ""
var y = ""
let alphabet: [String] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/:;()$&@\".,?!'[]{}#%^*+=_\\|~<>€¥£•".map { String($0) }
fileprivate let attackerProbability = 3/pow(10, 4.25)
internal static func parsePassword(password: String, alphabetCount: Int) throws -> (String, String, String) {
internal static func parsePassword(password: String, alphabetCount: Int, errorDetectionBits: Int = 6) throws -> (String, String, String, String) {
let pw2Length = Int(ceil(log(pow(2, 18))/log(Double(alphabetCount))))
let errorDetectionLength = Int(ceil(log(pow(2, Double(errorDetectionBits)))/log(Double(alphabetCount))))
if alphabetCount == 0 || password.count <= 2*pw2Length {
throw TravelError.corruptData
}
let pw2 = password.prefix(pw2Length)
let y = password.dropFirst(pw2Length).prefix(pw2Length)
let pw1 = password.dropFirst(2*pw2Length)
let errorDetection = password.suffix(errorDetectionLength)
let encodedData = password.dropLast(errorDetectionLength)
return (String(pw2), String(y), String(pw1))
let pw2 = encodedData.prefix(pw2Length)
let y = encodedData.dropFirst(pw2Length).prefix(pw2Length)
let pw1 = encodedData.dropFirst(2*pw2Length)
return (String(pw2), String(y), String(pw1), String(errorDetection))
}
public static func load(from data: Data, password: String) throws -> Traveler {
public static func load(from data: Data, password: String, errorDetectionBits: Int = 6) throws -> Traveler {
//create Checksum, verify it with the one in the password and throw invalidData Error, if they don't match up
//otherwise set password in Traveler-object and succed
let traveler = try JSONDecoder().decode(Traveler.self, from: data)
let alphabetCount = traveler.alphabet.count
let passwordTuple = try parsePassword(password: password, alphabetCount: alphabetCount)
let passwordTuple = try parsePassword(password: password, alphabetCount: alphabetCount, errorDetectionBits: errorDetectionBits)
let pw2 = passwordTuple.0
let y = passwordTuple.1
let pw1 = passwordTuple.2
let errorDetection = passwordTuple.3
traveler.setPassword(pw1: pw1, pw2: pw2)
if traveler.calculateErrorDetection(of: pw2+y+pw1, bits: errorDetectionBits) != errorDetection {
throw TravelError.invalidPassword
}
if try traveler.createChecksum() != y {
throw TravelError.corruptData
}
return traveler
}
public init(contacts: [String], keys: [String : String]) {
public init(contacts: [String], keys: [String : String], travelerAddress: String, travelerKey: String) {
self.contacts = contacts
self.keys = keys
self.travelerAddress = travelerAddress
self.travelerKey = travelerKey
salts = [:]
do {
try createSalts()
......@@ -102,6 +113,7 @@ public class Traveler: Codable {
throw TravelError.invalidData
}
}
input.append("("+travelerAddress+","+travelerKey+")")
let checksum = Crypto.sha256raw(string: input)
let coefficients = Crypto.split(data: checksum, bitsPerBlock: 18)
let polynom = Crypto.Polynom.init(coeficients: coefficients, irreducible: (1 << 18)+(1 << 3)) //chosen irreducible from http://www.hpl.hp.com/techreports/98/HPL-98-135.pdf
......@@ -109,17 +121,31 @@ public class Traveler: Codable {
return try Crypto.convertToPassword(number: y, alphabet: alphabet, bits: 18)
}
//calculates and encodes an errordetection code over text. Is capable to use up to 256 bits.
internal func calculateErrorDetection(of text: String, bits: Int) -> String {
let hash = Crypto.sha256raw(string: text)
let errorDetection = Crypto.split(data: hash, bitsPerBlock: bits)
if let errorDetection = errorDetection.first, let result = try? Crypto.convertToPassword(number: errorDetection, alphabet: alphabet, bits: bits) {
return result
}
return ""
}
fileprivate func setPassword(pw1: String, pw2: String) {
self.pw1 = pw1
self.pw2 = pw2
}
public func getPassword() throws -> String {
//returns the password the user has to remember
public func getToRemember(errorDetectionBits: Int = 6) throws -> String {
let y = try createChecksum()
return pw2+y+pw1
let password = pw2+y+pw1
let errorDetection = calculateErrorDetection(of: password, bits: errorDetectionBits)
return password+errorDetection
}
public func getSharedSecrets() throws -> [String : String] {
//returns the shared secrets which should be send to the contacts ordered by contacts
public func getToSend() throws -> [String : String] {
var result: [String: String] = [:]
for c in contacts {
let secret = Crypto.sha256(string: pw1+salts[c]!)
......@@ -129,12 +155,22 @@ public class Traveler: Codable {
}
//call this function after getPassword and getSharedSecrets
public func getDataToStore() -> Data {
public func getToStore() -> Data {
deletePasswordReference()
let data = try? JSONEncoder().encode(self)
return data!
}
//returns the contacts
public func getContacts() -> [String] {
return contacts
}
//returns the keys
public func getKeys() -> [String: String] {
return keys
}
public func deletePasswordReference() {
pw1 = ""
pw2 = ""
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment