Skip to content
Snippets Groups Projects
Commit 2bb6293c authored by lazarog98's avatar lazarog98
Browse files

#232 add wip verify, sign and encrypt methods with cryptoobjects

parent 380f9127
Branches
Tags
2 merge requests!58Onboarding screens swift ui merge dev,!35Resolve "SMIME Support"
......@@ -26,8 +26,17 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
codeCoverageEnabled = "YES"
shouldUseLaunchSchemeArgsEnv = "YES">
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A13526741D955BDF00D3BFE1"
BuildableName = "enzevalos_iphone.app"
BlueprintName = "enzevalos_iphone"
ReferencedContainer = "container:enzevalos_iphone.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
......@@ -55,17 +64,6 @@
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A13526741D955BDF00D3BFE1"
BuildableName = "enzevalos_iphone.app"
BlueprintName = "enzevalos_iphone"
ReferencedContainer = "container:enzevalos_iphone.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
......@@ -88,8 +86,6 @@
ReferencedContainer = "container:enzevalos_iphone.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
......
......@@ -8,19 +8,6 @@
import Foundation
struct SMIMEError : Error {
enum ErrorType {
case fingerPrint
case encryption
case decryption
case signing
}
let message: String?
let errorArray: [UInt]?
let type: ErrorType
}
class Certificate {
// TODO: make all attributes private with getters
let pem: String // raw PEM string
......
......@@ -276,6 +276,7 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
for cert in certs {
let (fp, _, _) = getFingerprintFromPem(pem: cert)
// TODO Exception
if fp != nil {
keychain[fp!] = cert
fingerprints.append(fp!)
......@@ -383,6 +384,10 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
}
}
func getOwnKeyFP() -> String? {
return privateKeyKeychain["ownkey"]
}
func testSMIMEencrypt(){
// OpenSSL_print_ver()
......@@ -495,10 +500,122 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
}
}
func encrypt() -> CryptoObject? {
// TODO: do we need a keychain that sotres userID -> user key/cert fp.
// MY IDEA WAS SAVING THE FP under the email in the cert kezchain
// Note: we ignore the Encryption interface because some things are built with PGP in mind and make no sense in the context of SMIME (signatureIDs for example)
func decrypt(data: Data, attatchedSig: Data? = nil, fromAddr: String) -> CryptoObject {
// NOTE TO SELF: Implement verify with CryptoObject BEFORE decrypt
}
func sign(plainData: Data, myEmail: String, detached: Bool = true) throws -> CryptoObject {
let fp = getOwnKeyFP()
let cert = certsKeychain[fp!]!
let key = privateKeyKeychain[fp!]!
let text = String(data: plainData, encoding: .utf8)
let (sigText, errArr) = signWithPem(message: text!, certAsPem: cert, keyAsPem: key, detached: detached)
// TODO: Exception
return CryptoObject(chiphertext: sigText!.data(using: .utf8), plaintext: text, decryptedData: plainData, sigState: SignatureState.ValidSignature, encState: EncryptionState.NoEncryption, signKey: fp, encType: CryptoScheme.SMIME, signedAdrs: [myEmail])
}
// If multiple signatures are present, ALL need to be valid AND have a matching mail address, else the signature is invalid.
func verify(data: Data, attacthedSig: Data?, email: String, isMailNew: Bool) -> SignatureState? {
var CAs : [String] = []
CAKeychain.allKeys().forEach({ (key) in
CAs.append(CAKeychain[key]!)
})
let text = String(data: data, encoding: .utf8)!
let (verStr, certsFPArr, errArr) = verifyWithCApem(message: text, pemCAArr: CAs)
if certsFPArr != nil {
var newCerts: [String] = [] // all certs that came from the email and weren't available before
var mailMatch = true
if certsFPArr?.count == 0 {mailMatch = false}
for item in certsFPArr! {
var mailFound = false
let (fp, cert) = item
let certObj = Certificate(pem: cert)
// check if the email from the parameters matches with one of the emails in each of the certs used to sign the message
for addr in certObj.eMails ?? [] {
if addr == email {
mailFound = true
break
}
}
mailMatch = mailFound && mailMatch
// check if cert is already in the keychain
if let _ = try? certsKeychain.get(fp) {
continue
}
newCerts.append(cert)
}
let fps = importCerts(certs: newCerts)
// check if the email has no certificate or the certificate is newer than the present one and update accordingly
for fp in fps{
let cert = Certificate(pem: certsKeychain[fp]!)
for email in cert.eMails ?? []
{
if isMailNew || certsKeychain[email] == nil
{
certsKeychain[email] = fp
}
}
}
return mailMatch ? SignatureState.ValidSignature : SignatureState.InvalidSignature
}
return nil
// TODO: Exception no valid signatures
}
func encrypt(plainData: Data, ids: [String], ownId: String, encryptForMyId: Bool = true) -> CryptoObject? {
let text = String(data: plainData, encoding: .utf8)
var pems: [String] = []
var ownFp: String? = nil
for id in ids {
if let fp = certsKeychain[id] {
// TODO: Exception try catch
pems.append(certsKeychain[fp]!)
}
else{
// TODO: Exception
print("No cert for email ", id)
}
}
// TODO: Ask Oliver why signing is allowed only with encryptForMyID = true
if encryptForMyId {
if let fp = getOwnKeyFP() {
ownFp = fp
// TODO: Exception try catch
pems.append(certsKeychain[fp]!)
}
else {
// TODO: Exception
print("No cert for own key!")
}
}
// TODO: try-catch text
let (encStr, errArr) = encryptWithPem(message: text!, certPems: pems)
let encData = encStr?.data(using: .utf8)
// TODO: check if errArr empty, exception
if ownFp != nil {
let ownCert = certsKeychain[ownFp!]!
let ownPk = privateKeyKeychain[ownFp!]!
let (sigText, sigErrArr) = signWithPem(message: encStr!, certAsPem: ownCert, keyAsPem: ownPk, detached: false)
// TODO: check if errArr empty, exception
return CryptoObject(chiphertext: sigText!.data(using: .utf8), plaintext: text, decryptedData: plainData, sigState: SignatureState.ValidSignature, encState: EncryptionState.ValidedEncryptedWithCurrentKey, signKey: ownFp, encType: CryptoScheme.SMIME, signedAdrs: [ownId])
}
return nil
// TODO: Exception
// throw SMIMEError
}
}
......
......@@ -8,12 +8,24 @@
import Foundation
struct SMIMEError : Error {
enum ErrorType {
case fingerPrint
case encryption
case decryption
case signing
}
let message: String?
let errorArray: [UInt]?
let type: ErrorType
}
func encryptWithPem(message: String,certPems: [String]) -> (String?, [UInt]?) {
let cCertsArray = createCStrArr(sarr: certPems)
let enc = OpenSSL_encrypt(message, cCertsArray, Int32(certPems.count))
defer {
deallocateResult(res: enc)
// enc?.deallocate()
}
let result = enc?.pointee;
......@@ -28,7 +40,6 @@ func decryptWithPem(message:String, certAsPem: String, keyAsPem:String) -> (Stri
let dec = OpenSSL_decrypt(message, certAsPem, keyAsPem)
defer {
deallocateResult(res: dec)
// dec?.deallocate()
}
let result = dec?.pointee;
......@@ -47,7 +58,6 @@ func signWithPem(message:String, certAsPem: String, keyAsPem:String, detached:Bo
let sig = OpenSSL_sign(message, certAsPem, keyAsPem, detFlag)
defer {
deallocateResult(res: sig)
// sig?.deallocate()
}
let result = sig?.pointee
......@@ -98,7 +108,6 @@ func getFingerprintFromPem (pem: String) -> (String?, [String]?, [UInt]?) {
let res = get_fingerprint_from_pem(pem, 0);
defer {
deallocateResult(res: res)
// res?.deallocate()
}
let result = res?.pointee;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment