Skip to content
Snippets Groups Projects
Commit 59614372 authored by Oliver Wiese's avatar Oliver Wiese
Browse files

update ObjectivePGP

parent b3b1c93a
No related branches found
No related tags found
No related merge requests found
...@@ -113,6 +113,7 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -113,6 +113,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSData*) transformKey: (NSString *) string; + (NSData*) transformKey: (NSString *) string;
+ (nullable NSData *)symmetricEncrypt:(NSData *)dataToEncrypt signWithKey:(nullable PGPKey *)signKey encryptionKey: (nullable NSString *) key passphrase:(nullable NSString *)passphrase armored:(BOOL)armored error:(NSError *__autoreleasing _Nullable *)error; + (nullable NSData *)symmetricEncrypt:(NSData *)dataToEncrypt signWithKey:(nullable PGPKey *)signKey encryptionKey: (nullable NSString *) key passphrase:(nullable NSString *)passphrase armored:(BOOL)armored error:(NSError *__autoreleasing _Nullable *)error;
+ (nullable NSData *)symmetricDecrypt:(NSData *)messageDataToDecrypt key:(nullable NSString *)encKey verifyWithKey:(nullable PGPKey *)key signed:(nullable BOOL *)isSigned valid:(nullable BOOL *)isValid integrityProtected:(nullable BOOL *)isIntegrityProtected error:(NSError *__autoreleasing _Nullable *)error;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
...@@ -824,6 +824,104 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -824,6 +824,104 @@ NS_ASSUME_NONNULL_BEGIN
} }
return encryptedMessage; return encryptedMessage;
} }
+ (nullable NSData *)symmetricDecrypt:(NSData *)messageDataToDecrypt key:(nullable NSString *)encKey verifyWithKey:(nullable PGPKey *)key signed:(nullable BOOL *)isSigned valid:(nullable BOOL *)isValid integrityProtected:(nullable BOOL *)isIntegrityProtected error:(NSError *__autoreleasing _Nullable *)error {
PGPAssertClass(messageDataToDecrypt, NSData);
let binaryMessages = [PGPArmor convertArmoredMessage2BinaryBlocksWhenNecessary:messageDataToDecrypt error:error];
// decrypt first message only
let binaryMessageToDecrypt = binaryMessages.count > 0 ? binaryMessages.firstObject : nil;
if (!binaryMessageToDecrypt) {
if (error) {
*error = [NSError errorWithDomain:PGPErrorDomain code:0 userInfo:@{ NSLocalizedDescriptionKey: @"Invalid input data" }];
}
return nil;
}
// parse packets
var packets = [self readPacketsFromData:binaryMessageToDecrypt];
PGPSymetricKeyEncryptedSessionKeyPacket *sessionKey = nil;
for (PGPPacket *packet in packets) {
if (packet.tag == PGPSymetricKeyEncryptedSessionKeyPacketTag){
sessionKey = PGPCast(packet, PGPSymetricKeyEncryptedSessionKeyPacket);
break;
}
}
NSAssert(sessionKey, @"Missing session key data");
if (!sessionKey) {
if (error) {
*error = [NSError errorWithDomain:PGPErrorDomain code:0 userInfo:@{ NSLocalizedDescriptionKey: @"Missing session key data" }];
}
return nil;
}
// 2
NSAssert(sessionKey.s2k, @"Missing s2k data\n");
if (sessionKey.s2k == nil){
if (error){
*error = [NSError errorWithDomain:PGPErrorDomain code:0 userInfo:@{ NSLocalizedDescriptionKey: @"Missing s2k data" }];
}
return nil;
}
let sessionKeyData = [sessionKey.s2k produceSessionKeyWithPassphrase: encKey symmetricAlgorithm:sessionKey.symmetricAlgorithm];
for (PGPPacket *packet in packets) {
switch (packet.tag) {
case PGPSymmetricallyEncryptedIntegrityProtectedDataPacketTag: {
// decrypt PGPSymmetricallyEncryptedIntegrityProtectedDataPacket
let symEncryptedDataPacket = PGPCast(packet, PGPSymmetricallyEncryptedIntegrityProtectedDataPacket);
packets = [symEncryptedDataPacket decryptWithSessionKeyAlgorithm:sessionKey.symmetricAlgorithm sessionKeyData:sessionKeyData error:error];
} break;
default:
break;
}
}
if (packets.count == 0) {
return nil;
}
PGPLiteralPacket * _Nullable literalPacket = nil;
PGPSignaturePacket * _Nullable signaturePacket = nil;
for (PGPPacket *packet in packets) {
switch (packet.tag) {
case PGPCompressedDataPacketTag:
case PGPOnePassSignaturePacketTag:
// ignore here
break;
case PGPLiteralDataPacketTag:
literalPacket = PGPCast(packet, PGPLiteralPacket);
break;
case PGPSignaturePacketTag:
signaturePacket = PGPCast(packet, PGPSignaturePacket);
break;
default:
if (error) {
*error = [NSError errorWithDomain:PGPErrorDomain code:0 userInfo:@{ NSLocalizedDescriptionKey: @"Unknown packet (expected literal or compressed)" }];
}
return nil;
}
}
BOOL dataIsSigned = signaturePacket != nil;
if (isSigned) { *isSigned = dataIsSigned; }
// available if literalPacket is available
let _Nullable plaintextData = literalPacket.literalRawData;
if (!plaintextData) {
return nil;
}
BOOL dataIsValid = NO;
if (signaturePacket && key.publicKey) {
// TODO
}
if (isValid) { *isValid = dataIsValid; }
return plaintextData;
}
@end @end
......
...@@ -112,9 +112,11 @@ class SwiftPGP: Encryption{ ...@@ -112,9 +112,11 @@ class SwiftPGP: Encryption{
func generateKey(adr: String) -> String{ func generateKey(adr: String) -> String{
let gen = KeyGenerator() let gen = KeyGenerator()
let pw = generatePW(size: PasscodeSize) let pw: String? = nil //generatePW(size: PasscodeSize)
let key = gen.generate(for: "\(adr) <\(adr)>", passphrase: pw) let key = gen.generate(for: "\(adr) <\(adr)>", passphrase: pw)
if pw != nil{
pwKeyChain[key.keyID.longIdentifier] = pw pwKeyChain[key.keyID.longIdentifier] = pw
}
return storeKey(key: key) return storeKey(key: key)
} }
...@@ -136,7 +138,7 @@ class SwiftPGP: Encryption{ ...@@ -136,7 +138,7 @@ class SwiftPGP: Encryption{
for key in keys{ for key in keys{
if key.isSecret{ if key.isSecret{
//test key{ //test key{
let m = try ObjectivePGP.sign("1234".data(using: .utf8)!, detached: false, using: [key], passphraseForKey: {(key) -> String? in return pw}) try ObjectivePGP.sign("1234".data(using: .utf8)!, detached: false, using: [key], passphraseForKey: {(key) -> String? in return pw})
} }
} }
return storeMultipleKeys(keys: keys, pw: pw, secret: isSecretKey) return storeMultipleKeys(keys: keys, pw: pw, secret: isSecretKey)
...@@ -191,14 +193,14 @@ class SwiftPGP: Encryption{ ...@@ -191,14 +193,14 @@ class SwiftPGP: Encryption{
if autocrypt{ if autocrypt{
// Create Autocrypt Setup-message // Create Autocrypt Setup-message
// See: https://autocrypt.readthedocs.io/en/latest/level1.html#autocrypt-setup-message // See: https://autocrypt.readthedocs.io/en/latest/level1.html#autocrypt-setup-message
// var passcode = loadPassword(id: id) var passcode = loadPassword(id: id)
// if passcode == nil{ if passcode == nil{
// passcode = generatePW(size: PasscodeSize) passcode = generatePW(size: PasscodeSize)
// } }
// exportPwKeyChain[key.keyID.longKeyString] = passcode exportPwKeyChain[key.keyID.longIdentifier] = passcode
// let cipher = try! pgp.symmetricEncrypt(keyData, signWith: nil, encryptionKey: passcode, passphrase: passcode, armored: true) let cipher = try! ObjectivePGP.symmetricEncrypt(keyData, signWith: nil, encryptionKey: passcode, passphrase: passcode, armored: true)
//return cipher return cipher
} }
return keyData return keyData
} }
...@@ -228,22 +230,28 @@ class SwiftPGP: Encryption{ ...@@ -228,22 +230,28 @@ class SwiftPGP: Encryption{
func encrypt(plaintext: String, ids: [String], myId: String) -> CryptoObject{ func encrypt(plaintext: String, ids: [String], myId: String) -> CryptoObject{
var keys = [Key]() var keys = [Key]()
let signKey = loadKey(id: myId)
for id in ids{ for id in ids{
if let key = loadKey(id: id){ if let key = loadKey(id: id){
keys.append(key) keys.append(key)
print("ID to encrypt: \(id)")
} }
} }
let signKey = loadKey(id: myId)
if signKey != nil{ if signKey != nil{
print("signing id: \(myId)")
keys.append(signKey!) keys.append(signKey!)
} }
let signedAdr = vaildAddress(key: signKey) let signedAdr = vaildAddress(key: signKey)
if let data = plaintext.data(using: String.Encoding.utf8){ if let data = plaintext.data(using: String.Encoding.utf8){
do{ do{
let chipher = try ObjectivePGP.encrypt(data, addSignature: true, using: keys, passphraseForKey: loadPassword) let chipher = try ObjectivePGP.encrypt(data, addSignature: true, using: keys, passphraseForKey: loadPassword)
return CryptoObject(chiphertext: chipher, plaintext: plaintext, decryptedData: data, sigState: SignatureState.ValidSignature, encState: EncryptionState.ValidedEncryptedWithCurrentKey, signKey: myId, encType: CryptoScheme.PGP, signedAdrs: signedAdr) let armorChipherString = Armor.armored(chipher, as: .message)
print("Encrypted: \n \(armorChipherString)")
let armorChipherData = armorChipherString.data(using: .utf8)
return CryptoObject(chiphertext: armorChipherData, plaintext: plaintext, decryptedData: data, sigState: SignatureState.ValidSignature, encState: EncryptionState.ValidedEncryptedWithCurrentKey, signKey: myId, encType: CryptoScheme.PGP, signedAdrs: signedAdr)
} catch { } catch {
print("Encryption error!") //TODO: Error handling! print("Encryption error!")
print(error)
} }
} }
return CryptoObject(chiphertext: nil, plaintext: nil,decryptedData: nil, sigState: SignatureState.InvalidSignature, encState: EncryptionState.UnableToDecrypt, signKey: nil, encType: cryptoScheme, signedAdrs: signedAdr) return CryptoObject(chiphertext: nil, plaintext: nil,decryptedData: nil, sigState: SignatureState.InvalidSignature, encState: EncryptionState.UnableToDecrypt, signKey: nil, encType: cryptoScheme, signedAdrs: signedAdr)
...@@ -251,64 +259,39 @@ class SwiftPGP: Encryption{ ...@@ -251,64 +259,39 @@ class SwiftPGP: Encryption{
} }
func decrypt(data: Data,decryptionIDs: [String], verifyIds: [String], fromAdr: String?) -> CryptoObject{ func decrypt(data: Data,decryptionIDs: [String], verifyIds: [String], fromAdr: String?) -> CryptoObject{
var cryptoObject: CryptoObject? = nil
for decId in decryptionIDs{
let temp = decrypt(data: data, decryptionId: decId, verifyIds: verifyIds, fromAdr: fromAdr)
if temp.encryptionState != EncryptionState.UnableToDecrypt{
cryptoObject = temp
if decId != DataHandler.handler.prefSecretKey().keyID{
temp.encryptionState = EncryptionState.ValidEncryptedWithOldKey
}
else{
break
}
}
}
if let c = cryptoObject {
return c
}
return decrypt(data: data, decryptionId: nil, verifyIds: verifyIds, fromAdr: fromAdr)
}
func decrypt(data: Data,decryptionId: String?, verifyIds: [String], fromAdr: String?) -> CryptoObject{
var plaindata: Data? = nil var plaindata: Data? = nil
var plaintext: String? = nil
var sigState = SignatureState.NoSignature var sigState = SignatureState.NoSignature
var encState = EncryptionState.UnableToDecrypt var encState = EncryptionState.UnableToDecrypt
var sigKeyID: String? = nil var sigKeyID: String? = nil
var signedAdr = [String]() var signedAdr = [String]()
var decKey: Key let prefID = DataHandler.handler.prefSecretKey().keyID
var encForCurrentSK = false
var keys = [Key]() var keys = [Key]()
/*
if let decIDs = try? ObjectivePGP.recipientsKeyID(forMessage: data){ DECRYPTION
let currentSkID = DataHandler.handler.prefSecretKey().keyID */
for id in decIDs{ // TODO: Maybe consider: try ObjectivePGP.recipientsKeyID(forMessage: ...) but currently not working...
if let key = loadKey(id: id.longIdentifier){ for decID in decryptionIDs{
decKey = key if let decKey = loadKey(id: decID){
keys.append(decKey) if decID == prefID{
} let (currentPlain, currentEncState) = decryptMessage(data: data, keys: [decKey], encForCurrentSK: true)
if id.longIdentifier == currentSkID{ if encState != EncryptionState.ValidEncryptedWithOldKey || currentEncState == EncryptionState.ValidedEncryptedWithCurrentKey{
encForCurrentSK = true plaindata = currentPlain
break encState = currentEncState
}
} }
} }
keys.append(decKey)
if let plain = try? ObjectivePGP.decrypt(data, andVerifySignature: false, using: keys, passphraseForKey: loadPassword){
plaindata = plain
if encForCurrentSK{
encState = EncryptionState.ValidedEncryptedWithCurrentKey
}
else{
encState = EncryptionState.ValidEncryptedWithOldKey
} }
} }
else{ if encState != EncryptionState.ValidedEncryptedWithCurrentKey{
encState = EncryptionState.UnableToDecrypt (plaindata, encState) = decryptMessage(data: data, keys: keys, encForCurrentSK: false)
} }
/*
VERIFICATION
*/
// test if message ist signed // test if message ist signed
sigState = verifyMessage(data: data, keys: keys) sigState = verifyMessage(data: data, keys: keys)
for id in verifyIds{ for id in verifyIds{
if let key = loadKey(id: id){ if let key = loadKey(id: id){
keys.append(key) keys.append(key)
...@@ -324,25 +307,54 @@ class SwiftPGP: Encryption{ ...@@ -324,25 +307,54 @@ class SwiftPGP: Encryption{
} }
} }
} }
if encState == EncryptionState.UnableToDecrypt{ if encState == EncryptionState.UnableToDecrypt{
sigState = SignatureState.NoSignature sigState = SignatureState.NoSignature
} }
var plaintext: String? = nil
if plaindata != nil{ if plaindata != nil{
plaintext = plaindata?.base64EncodedString() plaintext = plaindata?.base64EncodedString()
} }
return CryptoObject(chiphertext: data, plaintext: plaintext, decryptedData: plaindata, sigState: sigState, encState: encState, signKey: sigKeyID, encType: CryptoScheme.PGP, signedAdrs: signedAdr) return CryptoObject(chiphertext: data, plaintext: plaintext, decryptedData: plaindata, sigState: sigState, encState: encState, signKey: sigKeyID, encType: CryptoScheme.PGP, signedAdrs: signedAdr)
} }
func decrypt(data: Data,decryptionId: String?, verifyIds: [String], fromAdr: String?) -> CryptoObject{
if let decId = decryptionId{
return decrypt(data: data, decryptionIDs: [decId], verifyIds: verifyIds, fromAdr: fromAdr)
}
return decrypt(data: data, decryptionIDs: [String](), verifyIds: verifyIds, fromAdr: fromAdr)
}
private func decryptMessage(data: Data, keys: [Key], encForCurrentSK: Bool) -> (Data?, EncryptionState){
if let dataString = String(data: data, encoding: .utf8), let unarmored = try? Armor.readArmored(dataString){
if let plain = try? ObjectivePGP.decrypt(unarmored, andVerifySignature: true, using: keys, passphraseForKey: loadPassword){
if encForCurrentSK{
return (plain, EncryptionState.ValidedEncryptedWithCurrentKey)
}
else{
return(plain, EncryptionState.ValidEncryptedWithOldKey)
}
}
else{
return (nil, EncryptionState.UnableToDecrypt)
}
}
return (nil, EncryptionState.NoEncryption)
}
private func verifyMessage(data: Data, keys: [Key]) -> SignatureState{ private func verifyMessage(data: Data, keys: [Key]) -> SignatureState{
if let dataString = String(data: data, encoding: .utf8), let unarmored = try? Armor.readArmored(dataString){
do{ do{
try ObjectivePGP.verify(data, withSignature: nil, using: keys, passphraseForKey: loadPassword) try ObjectivePGP.verify(unarmored, withSignature: nil, using: keys, passphraseForKey: loadPassword)
return SignatureState.ValidSignature
} catch { } catch {
let nsError = error as NSError let nsError = error as NSError
print(error)
switch nsError.code { switch nsError.code {
case 7: case 7: // no public key
return SignatureState.NoPublicKey return SignatureState.NoPublicKey
case 8: case 8: // no signature
return SignatureState.NoSignature return SignatureState.NoSignature
case 9: // unable to decrypt case 9: // unable to decrypt
return SignatureState.InvalidSignature return SignatureState.InvalidSignature
...@@ -350,6 +362,7 @@ class SwiftPGP: Encryption{ ...@@ -350,6 +362,7 @@ class SwiftPGP: Encryption{
return SignatureState.InvalidSignature return SignatureState.InvalidSignature
} }
} }
}
return SignatureState.NoSignature return SignatureState.NoSignature
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment