Separate encryption/decryption logic for different frameworks used

This commit is contained in:
Danny Moesch 2019-09-08 23:00:46 +02:00 committed by Mingshen Sun
parent e2201ffa52
commit 730542d5bb
24 changed files with 428 additions and 414 deletions

View file

@ -0,0 +1,105 @@
//
// PGPAgent.swift
// passKitTests
//
// Created by Yishi Lin on 2019/7/17.
// Copyright © 2019 Bob Sun. All rights reserved.
//
import XCTest
@testable import passKit
class PGPAgentTest: XCTestCase {
private var keychain: KeyStore!
private var pgpAgent: PGPAgent!
private let testData = "Hello World!".data(using: .utf8)!
override func setUp() {
super.setUp()
keychain = DictBasedKeychain()
pgpAgent = PGPAgent(keyStore: keychain)
}
override func tearDown() {
keychain.removeAllContent()
super.tearDown()
}
func basicEncryptDecrypt(using pgpAgent: PGPAgent) throws -> Data? {
let encryptedData = try pgpAgent.encrypt(plainData: testData)
return try pgpAgent.decrypt(encryptedData: encryptedData, requestPGPKeyPassphrase: requestPGPKeyPassphrase)
}
func testBasicEncryptDecrypt() throws {
try [
RSA2048,
RSA2048_SUB,
ED25519,
//ED25519_SUB,
].forEach { keyTriple in
let keychain = DictBasedKeychain()
let pgpAgent = PGPAgent(keyStore: keychain)
try KeyFileManager(keyType: PgpKey.PUBLIC, keyPath: "", keyHandler: keychain.add).importKey(from: keyTriple.publicKey)
try KeyFileManager(keyType: PgpKey.PRIVATE, keyPath: "", keyHandler: keychain.add).importKey(from: keyTriple.privateKey)
XCTAssert(pgpAgent.isPrepared)
try pgpAgent.initKeys()
XCTAssert(pgpAgent.keyId!.lowercased().hasSuffix(keyTriple.fingerprint))
XCTAssertEqual(try basicEncryptDecrypt(using: pgpAgent), testData)
}
}
func testNoPrivateKey() throws {
try KeyFileManager(keyType: PgpKey.PUBLIC, keyPath: "", keyHandler: keychain.add).importKey(from: RSA2048.publicKey)
XCTAssertFalse(pgpAgent.isPrepared)
XCTAssertThrowsError(try pgpAgent.initKeys()) {
XCTAssertEqual($0 as! AppError, AppError.KeyImport)
}
XCTAssertThrowsError(try basicEncryptDecrypt(using: pgpAgent)) {
XCTAssertEqual($0 as! AppError, AppError.KeyImport)
}
}
func testInterchangePublicAndPrivateKey() throws {
try importKeys(RSA2048.privateKey, RSA2048.publicKey)
XCTAssert(pgpAgent.isPrepared)
XCTAssertThrowsError(try basicEncryptDecrypt(using: pgpAgent)) {
XCTAssert($0.localizedDescription.contains("gopenpgp: cannot unlock key ring, no private key available"))
}
}
func testIncompatibleKeyTypes() throws {
try importKeys(ED25519.publicKey, RSA2048.privateKey)
XCTAssert(pgpAgent.isPrepared)
XCTAssertThrowsError(try basicEncryptDecrypt(using: pgpAgent)) {
XCTAssert($0.localizedDescription.contains("openpgp: incorrect key"))
}
}
func testCorruptedKey() throws {
try importKeys(RSA2048.publicKey.replacingOccurrences(of: "1", with: ""), RSA2048.privateKey)
XCTAssert(pgpAgent.isPrepared)
XCTAssertThrowsError(try basicEncryptDecrypt(using: pgpAgent)) {
XCTAssert($0.localizedDescription.contains("Can't read keys. Invalid input."))
}
}
func testUnsettKeys() throws {
try importKeys(ED25519.publicKey, ED25519.privateKey)
XCTAssert(pgpAgent.isPrepared)
XCTAssertEqual(try basicEncryptDecrypt(using: pgpAgent), testData)
keychain.removeContent(for: PgpKey.PUBLIC.getKeychainKey())
keychain.removeContent(for: PgpKey.PRIVATE.getKeychainKey())
XCTAssertThrowsError(try basicEncryptDecrypt(using: pgpAgent)) {
XCTAssertEqual($0 as! AppError, AppError.KeyImport)
}
}
private func importKeys(_ publicKey: String, _ privateKey: String) throws {
try KeyFileManager(keyType: PgpKey.PUBLIC, keyPath: "", keyHandler: keychain.add).importKey(from: publicKey)
try KeyFileManager(keyType: PgpKey.PRIVATE, keyPath: "", keyHandler: keychain.add).importKey(from: privateKey)
}
}

View file

@ -12,28 +12,54 @@ import XCTest
class KeyFileManagerTest: XCTestCase {
private static let filePath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("test.txt").path
private static let keyFileManager = KeyFileManager(keyType: PgpKey.PUBLIC, keyPath: filePath)
private static let keyFileManager = KeyFileManager(keyType: PgpKey.PUBLIC, keyPath: filePath) { _, _ in }
override func tearDown() {
try? FileManager.default.removeItem(atPath: KeyFileManagerTest.filePath)
super.tearDown()
}
func testImportKeyAndDeleteFile() throws {
func testImportKeyFromFileSharing() throws {
let fileContent = "content".data(using: .ascii)
var storage: [String: Data] = [:]
let keyFileManager = KeyFileManager(keyType: PgpKey.PRIVATE, keyPath: KeyFileManagerTest.filePath)
var storage: [String: String] = [:]
let keyFileManager = KeyFileManager(keyType: PgpKey.PRIVATE, keyPath: KeyFileManagerTest.filePath) { storage[$1] = $0 }
FileManager.default.createFile(atPath: KeyFileManagerTest.filePath, contents: fileContent, attributes: nil)
try keyFileManager.importKeyAndDeleteFile { storage[$1] = $0 }
try keyFileManager.importKeyFromFileSharing()
XCTAssertFalse(FileManager.default.fileExists(atPath: KeyFileManagerTest.filePath))
XCTAssertTrue(storage[PgpKey.PRIVATE.getKeychainKey()] == fileContent)
XCTAssertEqual(storage[PgpKey.PRIVATE.getKeychainKey()], "content")
}
func testErrorReadingFile() throws {
XCTAssertThrowsError(try KeyFileManagerTest.keyFileManager.importKeyAndDeleteFile { _, _ in }) {
XCTAssertEqual($0 as! AppError, AppError.ReadingFile("test.txt"))
XCTAssertThrowsError(try KeyFileManagerTest.keyFileManager.importKeyFromFileSharing())
}
func testImportKeyFromUrl() throws {
let fileContent = "content".data(using: .ascii)
let url = URL(fileURLWithPath: KeyFileManagerTest.filePath)
var storage: [String: String] = [:]
let keyFileManager = KeyFileManager(keyType: PgpKey.PRIVATE, keyPath: KeyFileManagerTest.filePath) { storage[$1] = $0 }
FileManager.default.createFile(atPath: KeyFileManagerTest.filePath, contents: fileContent, attributes: nil)
try keyFileManager.importKey(from: url)
XCTAssertEqual(storage[PgpKey.PRIVATE.getKeychainKey()], "content")
}
func testImportKeyFromString() throws {
let string = "content"
var storage: [String: String] = [:]
let keyFileManager = KeyFileManager(keyType: PgpKey.PRIVATE, keyPath: KeyFileManagerTest.filePath) { storage[$1] = $0 }
try keyFileManager.importKey(from: string)
XCTAssertEqual(storage[PgpKey.PRIVATE.getKeychainKey()], string)
}
func testImportKeyFromNonAsciiString() throws {
XCTAssertThrowsError(try KeyFileManagerTest.keyFileManager.importKey(from: "")) {
XCTAssertEqual($0 as! AppError, AppError.Encoding)
}
}

View file

@ -1,108 +0,0 @@
//
// PGPAgent.swift
// passKitTests
//
// Created by Yishi Lin on 2019/7/17.
// Copyright © 2019 Bob Sun. All rights reserved.
//
import XCTest
@testable import passKit
class PGPAgentTest: XCTestCase {
private let keychain = DictBasedKeychain()
func basicEncryptDecrypt(pgpAgent: PGPAgent) -> Bool {
// Encrypt and decrypt.
let plainData = "Hello World!".data(using: .utf8)!
guard let encryptedData = try? pgpAgent.encrypt(plainData: plainData) else {
return false
}
guard let decryptedData = try? pgpAgent.decrypt(encryptedData: encryptedData, requestPGPKeyPassphrase: requestPGPKeyPassphrase) else {
return false
}
return plainData == decryptedData
}
func testInitPGPKey() {
let pgpAgent = PGPAgent(keyStore: keychain)
// [RSA2048] Setup keys.
try? pgpAgent.initPGPKey(with: PGP_RSA2048_PUBLIC_KEY, keyType: .PUBLIC)
try? pgpAgent.initPGPKey(with: PGP_RSA2048_PRIVATE_KEY, keyType: .PRIVATE)
XCTAssertTrue(pgpAgent.isImported)
XCTAssertEqual(pgpAgent.pgpKeyID, "A1024DAE")
XCTAssertTrue(self.basicEncryptDecrypt(pgpAgent: pgpAgent))
let pgpAgent2 = PGPAgent(keyStore: keychain)
try? pgpAgent2.initPGPKeys() // load from the keychain
XCTAssertTrue(self.basicEncryptDecrypt(pgpAgent: pgpAgent2))
pgpAgent.removePGPKeys()
// [RSA2048] Setup keys. The private key is a subkey.
try? pgpAgent.initPGPKey(with: PGP_RSA2048_PUBLIC_KEY, keyType: .PUBLIC)
try? pgpAgent.initPGPKey(with: PGP_RSA2048_PRIVATE_SUBKEY, keyType: .PRIVATE)
XCTAssertTrue(pgpAgent.isImported)
XCTAssertEqual(pgpAgent.pgpKeyID, "A1024DAE")
XCTAssertTrue(self.basicEncryptDecrypt(pgpAgent: pgpAgent))
pgpAgent.removePGPKeys()
// [ED25519] Setup keys.
try? pgpAgent.initPGPKey(with: PGP_ED25519_PUBLIC_KEY, keyType: .PUBLIC)
try? pgpAgent.initPGPKey(with: PGP_ED25519_PRIVATE_KEY, keyType: .PRIVATE)
XCTAssertTrue(pgpAgent.isImported)
XCTAssertEqual(pgpAgent.pgpKeyID, "E9444483")
XCTAssertTrue(self.basicEncryptDecrypt(pgpAgent: pgpAgent))
pgpAgent.removePGPKeys()
// [RSA2048] Setup keys from URL.
let publicKeyURL = URL(fileURLWithPath: PgpKey.PUBLIC.getFileSharingPath())
let privateKeyURL = URL(fileURLWithPath: PgpKey.PRIVATE.getFileSharingPath())
try? PGP_RSA2048_PUBLIC_KEY.write(to: publicKeyURL, atomically: false, encoding: .utf8)
try? PGP_RSA2048_PRIVATE_KEY.write(to: privateKeyURL, atomically: false, encoding: .utf8)
try? pgpAgent.initPGPKey(from: publicKeyURL, keyType: .PUBLIC)
try? pgpAgent.initPGPKey(from: privateKeyURL, keyType: .PRIVATE)
XCTAssertTrue(pgpAgent.isImported)
XCTAssertEqual(pgpAgent.pgpKeyID, "A1024DAE")
XCTAssertTrue(self.basicEncryptDecrypt(pgpAgent: pgpAgent))
pgpAgent.removePGPKeys()
// [RSA2048] Setup keys from iTunes file sharing.
try? PGP_RSA2048_PUBLIC_KEY.write(to: publicKeyURL, atomically: false, encoding: .utf8)
try? PGP_RSA2048_PRIVATE_KEY.write(to: privateKeyURL, atomically: false, encoding: .utf8)
XCTAssertTrue(pgpAgent.isFileSharingReady)
try? pgpAgent.initPGPKeyFromFileSharing()
XCTAssertTrue(pgpAgent.isImported)
XCTAssertEqual(pgpAgent.pgpKeyID, "A1024DAE")
XCTAssertTrue(self.basicEncryptDecrypt(pgpAgent: pgpAgent))
XCTAssertFalse(FileManager.default.fileExists(atPath: publicKeyURL.absoluteString))
XCTAssertFalse(FileManager.default.fileExists(atPath: privateKeyURL.absoluteString))
pgpAgent.removePGPKeys()
}
func testInitPGPKeyBadPrivateKeys() {
let pgpAgent = PGPAgent(keyStore: keychain)
let plainData = "Hello World!".data(using: .utf8)!
// [RSA2048] Setup the public key.
try? pgpAgent.initPGPKey(with: PGP_RSA2048_PUBLIC_KEY, keyType: .PUBLIC)
let encryptedData = try? pgpAgent.encrypt(plainData: plainData)
XCTAssertNotNil(encryptedData)
XCTAssertThrowsError(try pgpAgent.decrypt(encryptedData: encryptedData!, requestPGPKeyPassphrase: requestPGPKeyPassphrase))
// Wrong private key: a public key.
try? pgpAgent.initPGPKey(with: PGP_RSA2048_PUBLIC_KEY, keyType: .PRIVATE)
XCTAssertThrowsError(try pgpAgent.decrypt(encryptedData: encryptedData!, requestPGPKeyPassphrase: requestPGPKeyPassphrase))
// Wrong private key: an unmatched private key.
try? pgpAgent.initPGPKey(with: PGP_ED25519_PRIVATE_KEY, keyType: .PRIVATE)
XCTAssertThrowsError(try pgpAgent.decrypt(encryptedData: encryptedData!, requestPGPKeyPassphrase: requestPGPKeyPassphrase))
/// Wrong private key: a corrupted private key.
try? pgpAgent.initPGPKey(with: PGP_RSA2048_PRIVATE_KEY.replacingOccurrences(of: "1", with: ""), keyType: .PRIVATE)
XCTAssertThrowsError(try pgpAgent.decrypt(encryptedData: encryptedData!, requestPGPKeyPassphrase: requestPGPKeyPassphrase))
}
}