From cd0299d9f053805bc501e63518dbfccd03643d83 Mon Sep 17 00:00:00 2001 From: lazarog98 <lazarog98@ninlil.local> Date: Thu, 19 Mar 2020 12:42:32 +0100 Subject: [PATCH] #232 WIP certificate info retrieval, has a memory leak currently --- enzevalos_iphone.xcodeproj/project.pbxproj | 32 +++- enzevalos_iphone/Certificate.swift | 142 +++++++++++++++ enzevalos_iphone/SMIME.swift | 114 +++--------- enzevalos_iphone/SMIMEHelpers.swift | 84 +++++++++ enzevalos_iphone/c/certificate-helpers.c | 164 ++++++++++++++++++ enzevalos_iphone/c/certificate-helpers.h | 49 ++++++ enzevalos_iphone/c/general-helpers.c | 72 ++++++++ enzevalos_iphone/c/generic-helpers.h | 59 +++++++ .../c/{openssl-helpers.c => smime-helpers.c} | 101 ++--------- .../c/{openssl-helpers.h => smime-helpers.h} | 32 +--- .../enzevalos_iphone-Bridging-Header.h | 2 +- 11 files changed, 631 insertions(+), 220 deletions(-) create mode 100644 enzevalos_iphone/Certificate.swift create mode 100644 enzevalos_iphone/SMIMEHelpers.swift create mode 100644 enzevalos_iphone/c/certificate-helpers.c create mode 100644 enzevalos_iphone/c/certificate-helpers.h create mode 100644 enzevalos_iphone/c/general-helpers.c create mode 100644 enzevalos_iphone/c/generic-helpers.h rename enzevalos_iphone/c/{openssl-helpers.c => smime-helpers.c} (85%) rename enzevalos_iphone/c/{openssl-helpers.h => smime-helpers.h} (61%) diff --git a/enzevalos_iphone.xcodeproj/project.pbxproj b/enzevalos_iphone.xcodeproj/project.pbxproj index 15656bc4..5bfacc2b 100644 --- a/enzevalos_iphone.xcodeproj/project.pbxproj +++ b/enzevalos_iphone.xcodeproj/project.pbxproj @@ -27,6 +27,10 @@ 0ECEA0FE240E7DB1007DC71E /* mykey.p12 in Resources */ = {isa = PBXBuildFile; fileRef = 0ECEA0F4240E7DB0007DC71E /* mykey.p12 */; }; 0ECEA0FF240E7DB1007DC71E /* evilCA.pem in Resources */ = {isa = PBXBuildFile; fileRef = 0ECEA0F5240E7DB0007DC71E /* evilCA.pem */; }; 0ECEA100240E7DB1007DC71E /* evilkey1.pem in Resources */ = {isa = PBXBuildFile; fileRef = 0ECEA0F6240E7DB1007DC71E /* evilkey1.pem */; }; + 0EF148052422543E00B3C198 /* Certificate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EF148042422543E00B3C198 /* Certificate.swift */; }; + 0EF148082422572500B3C198 /* general-helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EF148072422572500B3C198 /* general-helpers.c */; }; + 0EF1480B2422584F00B3C198 /* certificate-helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EF1480A2422584F00B3C198 /* certificate-helpers.c */; }; + 0EF73F4324237E6500932FA0 /* SMIMEHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EF73F4224237E6500932FA0 /* SMIMEHelpers.swift */; }; 0EFEF0952417C0B400BB2FF7 /* CHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEF0942417C0B400BB2FF7 /* CHelpers.swift */; }; 3E6B07DE2011246500E49609 /* invitationText.html in Resources */ = {isa = PBXBuildFile; fileRef = 3E6B07DD2011246500E49609 /* invitationText.html */; }; 3EB4FA9F2012007C001D0625 /* DialogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EB4FA9D2012007C001D0625 /* DialogViewController.swift */; }; @@ -245,7 +249,7 @@ A1F992291DA7C9100073BF1B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A1F9922B1DA7C9100073BF1B /* Main.storyboard */; }; A1F992391DA7DD2E0073BF1B /* InboxTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A1F9923B1DA7DD2E0073BF1B /* InboxTableViewCell.xib */; }; A1FA44A721E10E1400DB02AC /* TravelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1FA44A621E10E1400DB02AC /* TravelHandler.swift */; }; - A5E303D824110F6400310264 /* openssl-helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = A5E303D724110F6400310264 /* openssl-helpers.c */; }; + A5E303D824110F6400310264 /* smime-helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = A5E303D724110F6400310264 /* smime-helpers.c */; }; AC4001CA169DC07A7A1E3AD3 /* Pods_enzevalos_iphone.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94EE54279AB591E0CAB8EFD8 /* Pods_enzevalos_iphone.framework */; }; F113C3851F30D06800E7F1D6 /* QRScannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F113C3841F30D06800E7F1D6 /* QRScannerView.swift */; }; F113C38B1F3344C200E7F1D6 /* ViewControllerPannable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F113C38A1F3344C200E7F1D6 /* ViewControllerPannable.swift */; }; @@ -321,6 +325,12 @@ 0ECEA0F4240E7DB0007DC71E /* mykey.p12 */ = {isa = PBXFileReference; lastKnownFileType = file; path = mykey.p12; sourceTree = "<group>"; }; 0ECEA0F5240E7DB0007DC71E /* evilCA.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = evilCA.pem; sourceTree = "<group>"; }; 0ECEA0F6240E7DB1007DC71E /* evilkey1.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = evilkey1.pem; sourceTree = "<group>"; }; + 0EF148042422543E00B3C198 /* Certificate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Certificate.swift; sourceTree = "<group>"; }; + 0EF148062422570F00B3C198 /* generic-helpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "generic-helpers.h"; sourceTree = "<group>"; }; + 0EF148072422572500B3C198 /* general-helpers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "general-helpers.c"; sourceTree = "<group>"; }; + 0EF148092422584F00B3C198 /* certificate-helpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "certificate-helpers.h"; sourceTree = "<group>"; }; + 0EF1480A2422584F00B3C198 /* certificate-helpers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "certificate-helpers.c"; sourceTree = "<group>"; }; + 0EF73F4224237E6500932FA0 /* SMIMEHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SMIMEHelpers.swift; sourceTree = "<group>"; }; 0EFEF0942417C0B400BB2FF7 /* CHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CHelpers.swift; sourceTree = "<group>"; }; 1D4A9E60565DECF52C011BC0 /* Pods-enzevalos_iphone-AdHoc.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphone-AdHoc.release.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphone-AdHoc/Pods-enzevalos_iphone-AdHoc.release.xcconfig"; sourceTree = "<group>"; }; 3E6B07DD2011246500E49609 /* invitationText.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = invitationText.html; path = Invitation/invitationText.html; sourceTree = "<group>"; }; @@ -683,8 +693,8 @@ A1F9923D1DA7DD350073BF1B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InboxTableViewCell.strings; sourceTree = "<group>"; }; A1F9923F1DA7DD370073BF1B /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InboxTableViewCell.strings; sourceTree = "<group>"; }; A1FA44A621E10E1400DB02AC /* TravelHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TravelHandler.swift; sourceTree = "<group>"; }; - A5E303D624110F6400310264 /* openssl-helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "openssl-helpers.h"; sourceTree = "<group>"; }; - A5E303D724110F6400310264 /* openssl-helpers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "openssl-helpers.c"; sourceTree = "<group>"; }; + A5E303D624110F6400310264 /* smime-helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "smime-helpers.h"; sourceTree = "<group>"; }; + A5E303D724110F6400310264 /* smime-helpers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "smime-helpers.c"; sourceTree = "<group>"; }; AA686D4FC9B86445A0C87F0F /* Pods-enzevalos_iphone.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphone.release.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphone/Pods-enzevalos_iphone.release.xcconfig"; sourceTree = "<group>"; }; AF67EF30BB065CC9C0D17940 /* Pods_enzevalos_iphoneUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_enzevalos_iphoneUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BC7D006B3B40A23E53B4F317 /* Pods-enzevalos_iphoneTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphoneTests.release.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphoneTests/Pods-enzevalos_iphoneTests.release.xcconfig"; sourceTree = "<group>"; }; @@ -761,6 +771,8 @@ children = ( 0ECA5797240D496800B0F231 /* SMIME.swift */, A5E303D524110F6400310264 /* c */, + 0EF148042422543E00B3C198 /* Certificate.swift */, + 0EF73F4224237E6500932FA0 /* SMIMEHelpers.swift */, ); name = SMIME; sourceTree = "<group>"; @@ -1579,8 +1591,12 @@ A5E303D524110F6400310264 /* c */ = { isa = PBXGroup; children = ( - A5E303D624110F6400310264 /* openssl-helpers.h */, - A5E303D724110F6400310264 /* openssl-helpers.c */, + A5E303D624110F6400310264 /* smime-helpers.h */, + A5E303D724110F6400310264 /* smime-helpers.c */, + 0EF148062422570F00B3C198 /* generic-helpers.h */, + 0EF148072422572500B3C198 /* general-helpers.c */, + 0EF148092422584F00B3C198 /* certificate-helpers.h */, + 0EF1480A2422584F00B3C198 /* certificate-helpers.c */, ); path = c; sourceTree = "<group>"; @@ -2047,7 +2063,7 @@ A1EB05801D956851008659C1 /* SendViewController.swift in Sources */, 479C649B21F45DAF00A01071 /* PasswordToggleVisibilityView.swift in Sources */, 47691A8C1ECC3EC7004BCFC5 /* EphemeralMail.swift in Sources */, - A5E303D824110F6400310264 /* openssl-helpers.c in Sources */, + A5E303D824110F6400310264 /* smime-helpers.c in Sources */, A142E70921E7919F000395E3 /* IntroContactViewController.swift in Sources */, 8428A8671F436A11007649A5 /* SubBadgeHeaderTableViewCell.swift in Sources */, A1EB05981D956947008659C1 /* InboxViewController.swift in Sources */, @@ -2059,6 +2075,7 @@ 472F398C1E2519C8009260FB /* CNContactExtension.swift in Sources */, 476406A12416B5C800C7D426 /* OnboardingIntro.swift in Sources */, 476406972416B54D00C7D426 /* InboxCoordinator.swift in Sources */, + 0EF148082422572500B3C198 /* general-helpers.c in Sources */, F113C3851F30D06800E7F1D6 /* QRScannerView.swift in Sources */, 477670C6228454F700043604 /* ButtonCell.swift in Sources */, F18B44601E704C550080C041 /* ReplaceSegue.swift in Sources */, @@ -2131,6 +2148,7 @@ A111F6AD1FA77B170060AFDE /* LoggerDetail.swift in Sources */, A13526791D955BDF00D3BFE1 /* AppDelegate.swift in Sources */, 476916A2216B86CF00491527 /* EnzevalosContact+CoreDataClass.swift in Sources */, + 0EF148052422543E00B3C198 /* Certificate.swift in Sources */, A1ECE54B1EFBE7ED0009349F /* FolderCell.swift in Sources */, 8428A85F1F436A05007649A5 /* GamificationData.swift in Sources */, 475DF4791F0D54C9009D807F /* Folder+CoreDataClass.swift in Sources */, @@ -2165,6 +2183,7 @@ 47E7376E22845EC400972401 /* SecretKeyTableViewController.swift in Sources */, 478154A721FF3F0900A931EC /* Warning.swift in Sources */, 4764069F2416B5A600C7D426 /* NewOnboardingView.swift in Sources */, + 0EF73F4324237E6500932FA0 /* SMIMEHelpers.swift in Sources */, 47EABF0B241A9C8700774A93 /* AuthenticationScreen.swift in Sources */, 8428A8681F436A11007649A5 /* SubBadgeTableViewCell.swift in Sources */, A1EB05861D956872008659C1 /* FrequentCell.swift in Sources */, @@ -2175,6 +2194,7 @@ 478154AC21FF6A9600A931EC /* Mailbot.swift in Sources */, 8428A86E1F436A1E007649A5 /* BadgeCase.swift in Sources */, A1B49E5D21E54CBF00ED86FC /* IntroContactTableViewController.swift in Sources */, + 0EF1480B2422584F00B3C198 /* certificate-helpers.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/enzevalos_iphone/Certificate.swift b/enzevalos_iphone/Certificate.swift new file mode 100644 index 00000000..832c7a33 --- /dev/null +++ b/enzevalos_iphone/Certificate.swift @@ -0,0 +1,142 @@ +// +// Certificate.swift +// enzevalos_iphone +// +// Created by lazarog98 on 18.03.20. +// Copyright © 2020 fu-berlin. All rights reserved. +// + +import Foundation + + +class Certificate { + // TODO: make all attributes private with getters + let pem: String // raw PEM string + let fingerPrint: String + let eMails: [String]? + let issuer: String? + let hasPrivateKey: Bool + let subject: String? + let startDate: String? + let endDate: String? + + init(pem: String) { + let cCertInfo = get_cert_data(pem) + + let certInfo = cCertInfo?.pointee + + // TODO: look for private key + self.hasPrivateKey = pem.contains("PRIVATE KEY") + + let (fingerPrint, _, _) = getFingerprintFromPem(pem: pem) + self.fingerPrint = fingerPrint! //TODO: REPLACE WITH EXCEPTION + self.pem = pem + + self.eMails = certInfo?.extractField(field: CertInfoString.emails) + self.endDate = certInfo?.extractField(field: CertInfoString.endDate) + self.startDate = certInfo?.extractField(field: CertInfoString.startDate) + self.subject = certInfo?.extractField(field: CertInfoString.subject) + self.issuer = certInfo?.extractField(field: CertInfoString.issuer) + + cCertInfo?.deallocate() + } + + //deinit() { + + //} + + func getMails() { + + } +} + +/** + An enum used in the extractString() method of cert_info + */ +enum CertInfoString { + case issuer; + case subject; + case startDate; + case endDate; + case emails; +} + +/** + extensions to the C struct so that memory deallocation is automatic + */ +extension cert_info { + /** + Extracts an array of certs in PEM of the respective function from the result object + Deallocates the "errors" part of the result object + Only use in combination with_extractOutput and _extractErrors + */ + func extractEmails() -> [String]? { + let arr = self.emails + var strArr: [String]? = nil + + if arr != nil { + strArr = [] + let size = self.num_emails + print("Size:",size) + for i in 0..<size { + let str = String(cString: arr![Int(i)]!) + strArr?.append(str) + //(arr![Int(i)])!.deallocate() + } + //arr?.deallocate() + } + + return strArr + } + + /** + Extracts the output of the respective function from the result object + Deallocates the "res" part of the result object + Only use in combination with_extractErrors + + - parameters: + - field: the result object + */ + func extractString(field: CertInfoString) -> String? { + let cStr: UnsafeMutablePointer<Int8>? + switch field { + case .endDate: + cStr = self.date_end + case .startDate: + cStr = self.date_start + case .issuer: + cStr = self.issuer + case .subject: + cStr = self.subject + default: + return nil + } + + var swiftStr: String? = nil + + if cStr != nil { + swiftStr = String(cString: cStr!) + // same here + cStr?.deallocate() + } + + return swiftStr + } + + func extractField<T>(field: CertInfoString) -> T? { + switch field { + case .emails: + let emails = self.extractEmails() + if emails is T? { + return emails as! T? + } + default: + let res = self.extractString(field: field) + if res is T? { + return res as! T? + } + } + + return nil + } +} diff --git a/enzevalos_iphone/SMIME.swift b/enzevalos_iphone/SMIME.swift index cde785df..ff7cfe9d 100644 --- a/enzevalos_iphone/SMIME.swift +++ b/enzevalos_iphone/SMIME.swift @@ -356,10 +356,11 @@ AYIHvW6qRLTsSR6BZZS3pqGXYue7fE0vj4HJ2IEpj05qQ5RXrD57Wg== let cert = certsKeychain[privateKeyKeychain["ownkey"]!]! let key = privateKeyKeychain[privateKeyKeychain["ownkey"]!]! - let (enc, enc_errs) = encryptWithPem(message: test_string, certAsPem: cert) + /*let (enc, enc_errs) = encryptWithPem(message: test_string, certAsPem: cert) if enc != nil { // the pointers point to memory allocatedi in c that needs to be manually dealocated print("SWIFT ENC DONE: ", enc ?? "") + let (dec, dec_errs) = decryptWithPem(message: enc ?? "", certAsPem: cert, keyAsPem: key) if dec != nil { print("SWIFT DEC DONE: ", dec ?? "") @@ -369,14 +370,27 @@ AYIHvW6qRLTsSR6BZZS3pqGXYue7fE0vj4HJ2IEpj05qQ5RXrD57Wg== print("Dec failed!") } } - else + if enc_errs != nil { print("Enc failed!") for x in enc_errs ?? [] { print("errorstring: ",getErrorString(errCode: x)) } - } + }*/ + for i in 0...1000 { + let _ = Certificate(pem: cert) + if (i % 100 == 0) + { + print(i) + } + /*print("CERTIFICATE OBJECT", certObj) + print("issuer", certObj.issuer ?? "") + print("emails", certObj.eMails ?? "") + print("subject", certObj.subject ?? "") + print("startDate", certObj.startDate ?? "") + print("endDate", certObj.endDate ?? "")*/ + } /*let (sig, sigErr) = signWithPem(message: test_string, certAsPem: cert, keyAsPem: key, detached: false) if sig != nil{ // the pointers point to memory allocatedi in c that needs to be manually dealocated @@ -422,81 +436,6 @@ AYIHvW6qRLTsSR6BZZS3pqGXYue7fE0vj4HJ2IEpj05qQ5RXrD57Wg== print("TEST CA FINGERPRINT", fpTestCA ?? "") }*/ } - - func encryptWithPem(message: String,certAsPem: String) -> (String?, [UInt]?) { - let enc = OpenSSL_encrypt(message, certAsPem) - let result = enc?.pointee; - - let encStr = result?._extractOutput() - let errArr = result?._extractErrors() - - enc?.deallocate() - return (encStr, errArr) - } - - func decryptWithPem(message:String, certAsPem: String, keyAsPem:String) -> (String?, [UInt]?) { - let dec = OpenSSL_decrypt(message, certAsPem, keyAsPem) - let result = dec?.pointee; - - let decStr = result?._extractOutput() - let errArr = result?._extractErrors() - - dec?.deallocate() - return (decStr, errArr) - } - - func signWithPem(message:String, certAsPem: String, keyAsPem:String, detached:Bool) -> (String?, [UInt]?) { - var detFlag : Int32 = 0 - if detached { - detFlag = 1 - } - - let sig = OpenSSL_sign(message, certAsPem, keyAsPem, detFlag) - let result = sig?.pointee - - let sigStr = result?._extractOutput() - let errArr = result?._extractErrors() - - sig?.deallocate() - return (sigStr, errArr) - } - - func verifyWithCApem (message:String, pemCAArr: [String]) -> (String?, [String]?, [UInt]?) { - let pemCAArrC = createCStrArr(sarr: pemCAArr) - let ver = OpenSSL_verify(message, pemCAArrC, Int32(pemCAArr.count)) - deallocateCStrArr(arr: pemCAArrC, len:pemCAArr.count) - - let result = ver?.pointee; - - let verStr = result?._extractOutput() - let errArr = result?._extractErrors() - let certArr = result?._extractCerts() - - ver?.deallocate() - return (verStr, certArr, errArr) - } - - func getFingerprintFromPem (pem: String) -> (String?, [String]?, [UInt]?) { - let res = get_fingerprint_from_pem(pem, 0); - - let result = res?.pointee; - - let fpStr = result?._extractOutput() - let errArr = result?._extractErrors() - - res?.deallocate() - return (fpStr, nil, errArr) - } - - func getErrorString(errCode: UInt) -> String { - let cStr = get_err_string(errCode); - if (cStr != nil) { - let str = String( cString: cStr!) - cStr?.deallocate() - return str; - } - return "Invalid error code!" - } } /** @@ -507,18 +446,14 @@ extension result { Extracts an array of certs in PEM of the respective function from the result object Deallocates the "errors" part of the result object Only use in combination with_extractOutput and _extractErrors - - - parameters: - - res: the result object */ - func _extractCerts() -> [String]? { + func extractCerts() -> [String]? { let arr = self.certs var strArr: [String]? = nil if arr != nil { strArr = [] let size = self.num_certs - print("Size:",size) for i in 0..<size { let str = String(cString: arr![Int(i)]!) strArr?.append(str) @@ -534,18 +469,14 @@ extension result { Extracts an array of errors of the respective function from the result object Deallocates the "errors" part of the result object Only use in combination with_extractOutput - - - parameters: - - res: the result object */ - func _extractErrors() -> [UInt]? { + func extractErrors() -> [UInt]? { let arr = self.errors var strArr: [UInt]? = nil if arr != nil { strArr = [] let size = self.num_errors - print("Size:",size) for i in 0..<size { print("Swift Error Extract:", arr![Int(i)]) strArr?.append(arr![Int(i)]) @@ -560,17 +491,14 @@ extension result { Extracts the output of the respective function from the result object Deallocates the "res" part of the result object Only use in combination with_extractErrors - - - parameters: - - res: the result object */ - func _extractOutput() -> String? { + func extractOutput() -> String? { let cStr = self.res var swiftStr: String? = nil if cStr != nil { - swiftStr = String(cString: self.res!) + swiftStr = String(cString: cStr!) // same here cStr?.deallocate() } diff --git a/enzevalos_iphone/SMIMEHelpers.swift b/enzevalos_iphone/SMIMEHelpers.swift new file mode 100644 index 00000000..15293dd5 --- /dev/null +++ b/enzevalos_iphone/SMIMEHelpers.swift @@ -0,0 +1,84 @@ +// +// SMIMEHelpers.swift +// enzevalos_iphone +// +// Created by lazarog98 on 19.03.20. +// Copyright © 2020 fu-berlin. All rights reserved. +// + +import Foundation + +func encryptWithPem(message: String,certAsPem: String) -> (String?, [UInt]?) { + let enc = OpenSSL_encrypt(message, certAsPem) + let result = enc?.pointee; + + let encStr = result?.extractOutput() + let errArr = result?.extractErrors() + + enc?.deallocate() + return (encStr, errArr) +} + +func decryptWithPem(message:String, certAsPem: String, keyAsPem:String) -> (String?, [UInt]?) { + let dec = OpenSSL_decrypt(message, certAsPem, keyAsPem) + let result = dec?.pointee; + + let decStr = result?.extractOutput() + let errArr = result?.extractErrors() + + dec?.deallocate() + return (decStr, errArr) +} + +func signWithPem(message:String, certAsPem: String, keyAsPem:String, detached:Bool) -> (String?, [UInt]?) { + var detFlag : Int32 = 0 + if detached { + detFlag = 1 + } + + let sig = OpenSSL_sign(message, certAsPem, keyAsPem, detFlag) + let result = sig?.pointee + + let sigStr = result?.extractOutput() + let errArr = result?.extractErrors() + + sig?.deallocate() + return (sigStr, errArr) +} + +func verifyWithCApem (message:String, pemCAArr: [String]) -> (String?, [String]?, [UInt]?) { + let pemCAArrC = createCStrArr(sarr: pemCAArr) + let ver = OpenSSL_verify(message, pemCAArrC, Int32(pemCAArr.count)) + deallocateCStrArr(arr: pemCAArrC, len:pemCAArr.count) + + let result = ver?.pointee; + + let verStr = result?.extractOutput() + let errArr = result?.extractErrors() + let certArr = result?.extractCerts() + + ver?.deallocate() + return (verStr, certArr, errArr) +} + +func getFingerprintFromPem (pem: String) -> (String?, [String]?, [UInt]?) { + let res = get_fingerprint_from_pem(pem, 0); + + let result = res?.pointee; + + let fpStr = result?.extractOutput() + let errArr = result?.extractErrors() + + res?.deallocate() + return (fpStr, nil, errArr) +} + +func getErrorString(errCode: UInt) -> String { + let cStr = get_err_string(errCode); + if (cStr != nil) { + let str = String( cString: cStr!) + cStr?.deallocate() + return str; + } + return "Invalid error code!" +} diff --git a/enzevalos_iphone/c/certificate-helpers.c b/enzevalos_iphone/c/certificate-helpers.c new file mode 100644 index 00000000..236d08a8 --- /dev/null +++ b/enzevalos_iphone/c/certificate-helpers.c @@ -0,0 +1,164 @@ +// +// certificate-helpers.c +// enzevalos_iphone +// +// Created by lazarog98 on 18.03.20. +// Copyright © 2020 fu-berlin. All rights reserved. +// + +#include "certificate-helpers.h" + +cert_info * get_cert_data(const char *pem) +{ + BIO *cert_bio = NULL; + // recipient certificate + X509 *cert = NULL; + cert_info *info = malloc(sizeof(cert_info)); + array_with_length *emails = NULL; + + cert_bio = BIO_new_mem_buf(pem, (int) strlen(pem)); + + if (!cert_bio) { + printf("Failed reading mykey.pem!\n"); + goto deinit; + } + + cert = PEM_read_bio_X509(cert_bio, NULL, 0, NULL); + if (!cert) { + printf("Failed reading pem\n"); + goto deinit; + } + + emails = get_emails(cert); + int size = info->num_emails; + info->num_emails = size; + info->emails = malloc(size*sizeof(char*)); + char ** arr = (char**) emails->arr; + for (int i = 0; i<size; i++) { + unsigned long len = strlen(arr[i]); + info->emails[i] = malloc(len + 1); + info->emails[i][len] = 0; + memcpy(info->emails[i], arr[i], len); + free(arr[i]); + } + free(emails); + + info->date_end = get_end_date(cert); + info->date_start = get_start_date(cert); + info->subject = get_subject(cert); + info->issuer = get_issuer(cert); + + // info->num_emails = emails->size; + // info->emails = (char **) (emails->arr); +deinit: + BIO_free(cert_bio); + X509_free(cert); + return info; +} + +char * get_issuer(X509 *cert) { + + char *res = NULL; + BIO *out = NULL; + out = BIO_new(BIO_s_mem()); + X509_NAME *name = NULL; + name = X509_get_issuer_name(cert); + X509_NAME_print_ex(out, name, 0, XN_FLAG_MULTILINE); + bio_to_str(out, &res); +deinit: + BIO_free(out); + //X509_NAME_free(name); + return res; +} + +char * get_subject(X509 *cert) { + char *res = NULL; + BIO *out = NULL; + out = BIO_new(BIO_s_mem()); + X509_NAME *name = NULL; + name = X509_get_subject_name(cert); + X509_NAME_print_ex(out, name, 0, XN_FLAG_MULTILINE); + bio_to_str(out, &res); +deinit: + BIO_free(out); +// X509_NAME_free(name); + return res; +} + +char * get_start_date(X509 *cert) { + char *res = NULL; + BIO *out = NULL; + out = BIO_new(BIO_s_mem()); + ASN1_TIME_print(out, X509_get0_notBefore(cert)); + bio_to_str(out, &res); +deinit: + BIO_free(out); + return res; +} + +char * get_end_date(X509 *cert) { + char *res = NULL; + BIO *out = NULL; + out = BIO_new(BIO_s_mem()); + ASN1_TIME_print(out, X509_get0_notAfter(cert)); + bio_to_str(out, &res); +deinit: + BIO_free(out); + return res; +} + +array_with_length *get_emails(X509 *cert) { + array_with_length *res = malloc(sizeof(array_with_length)); + int i = 0; + STACK_OF(OPENSSL_STRING) *list = NULL; + + if (cert == NULL) { + printf("Failed to get emails cause null cert!\n"); + goto deinit; + } + + list = X509_get1_email(cert); + + const int emails_num = sk_OPENSSL_STRING_num(list); + res->size = emails_num; + + if (emails_num == 0) + goto deinit; + + char ** arr = init_str_arr(emails_num); + + for (i = 0; i < emails_num; i++) { + char *temp = sk_OPENSSL_STRING_value(list, i); + unsigned long size = strlen(temp); + arr[i] = malloc(size+1); + arr[i][size] = 0; + memcpy(arr[i], temp, size); + } + res->arr = arr; +deinit: + //X509_email_free(list); + return res; +} + +X509 *get_cert_from_pem(const char *pem) { + BIO *rec_cert_bio = NULL; + // recipient certificate + X509 *rec_cert = NULL; + + rec_cert_bio = BIO_new_mem_buf(pem, (int) strlen(pem)); + + if (!rec_cert_bio) { + printf("Failed reading mykey.pem!\n"); + goto deinit; + } + + rec_cert = PEM_read_bio_X509(rec_cert_bio, NULL, 0, NULL); + + if (!rec_cert) { + printf("Failed reading pem\n"); + goto deinit; + } +deinit: + BIO_free(rec_cert_bio); + return rec_cert; +} diff --git a/enzevalos_iphone/c/certificate-helpers.h b/enzevalos_iphone/c/certificate-helpers.h new file mode 100644 index 00000000..73c84d3f --- /dev/null +++ b/enzevalos_iphone/c/certificate-helpers.h @@ -0,0 +1,49 @@ +// +// certificate-helpers.h +// enzevalos_iphone +// +// Created by lazarog98 on 18.03.20. +// Copyright © 2020 fu-berlin. All rights reserved. +// + +#ifndef certificate_helpers_h +#define certificate_helpers_h +#undef OPENSSL_NO_SSL_INTERN +#undef OPENSSL_NO_CRYPTO_INTERN + +#include "generic-helpers.h" +#include <string.h> +#include <stdlib.h> +#include <openssl/opensslv.h> +#include <openssl/evp.h> // this header may not be needed +#include <openssl/err.h> // this header may not be needed +#include <openssl/bio.h> +#include <openssl/pem.h> +#include <openssl/pkcs7.h> +#include <openssl/cms.h> +#include <openssl/safestack.h> +#include <openssl/x509.h> +#include <openssl/opensslconf.h> + +// subject +// issuer + +struct cert_info { + char *issuer; + char *subject; + char *date_start; + char *date_end; + char ** emails; + int num_emails; +} typedef cert_info; + + +char * get_issuer(X509 *cert); +char * get_subject(X509 *cert); +char * get_start_date(X509 *cert); +char * get_end_date(X509 *cert); +array_with_length *get_emails(X509 *cert); +// X509 *get_cert_from_pem(const char *pem); +cert_info * get_cert_data(const char *pem); + +#endif /* certificate_helpers_h */ diff --git a/enzevalos_iphone/c/general-helpers.c b/enzevalos_iphone/c/general-helpers.c new file mode 100644 index 00000000..3cde0771 --- /dev/null +++ b/enzevalos_iphone/c/general-helpers.c @@ -0,0 +1,72 @@ +// +// general-helpers.c +// enzevalos_iphone +// +// Created by lazarog98 on 18.03.20. +// Copyright © 2020 fu-berlin. All rights reserved. +// + + +#include "generic-helpers.h" + +void bio_to_str(BIO *bio_in, char **out) { + char * tmp = NULL, *tmp2 = NULL; + long size = BIO_get_mem_data(bio_in, &tmp); + tmp2 = malloc(size+1); + tmp2[size]=0; // To Nullterminate the string + memcpy(tmp2, tmp, size); + *out = tmp2; +} + +int get_array_size(array_with_length *arr) { + return arr->size; +} + +char *get_err_string(unsigned long err) { + const char *error = ERR_func_error_string(err); + //printf("\nError: %s", error); + char * error_permanent = (char *) malloc(strlen(error)+1); + error_permanent[strlen(error)]=0; // To Nullterminate the string + memcpy(error_permanent,error,strlen(error)); + + return error_permanent; +} + +char ** init_str_arr(int num) +{ + char ** arr = malloc(num*sizeof(char*)); + return arr; +} + +char ** add_str_to_arr(const char *str, char **arr, int i) +{ + unsigned long len = strlen(str); + char *newstr = malloc(len+1); + memcpy(newstr, str, len); + newstr[len]=0; + arr[i]=newstr; + return arr; +} + +void deallocate_str_arr(char **arr, int len) +{ + for (int i=0; i < len; i++){ + free(arr[i]); + } + free(arr); +} + +char *bin_to_hex(unsigned char *bin, int len) +{ + unsigned char buf[3]; + char *res = malloc(2*len+1); + for (int i =0;i<len;i++) + { + sprintf(buf, "%02x", bin[i]); + res[i*2]=buf[0]; + res[i*2+1]=buf[1]; + } + res[len*2]=0; + return res; +} + diff --git a/enzevalos_iphone/c/generic-helpers.h b/enzevalos_iphone/c/generic-helpers.h new file mode 100644 index 00000000..7d643746 --- /dev/null +++ b/enzevalos_iphone/c/generic-helpers.h @@ -0,0 +1,59 @@ +// +// generic-helpers.h +// enzevalos_iphone +// +// Created by lazarog98 on 18.03.20. +// Copyright © 2020 fu-berlin. All rights reserved. +// + +#ifndef generic_helpers_h +#undef OPENSSL_NO_SSL_INTERN +#undef OPENSSL_NO_CRYPTO_INTERN + +#include <string.h> +#include <stdlib.h> +#include <openssl/opensslv.h> +#include <openssl/evp.h> // this header may not be needed +#include <openssl/err.h> // this header may not be needed +#include <openssl/bio.h> +#include <openssl/pem.h> +#include <openssl/pkcs7.h> +#include <openssl/cms.h> +#include <openssl/safestack.h> +#include <openssl/x509.h> +#include <openssl/opensslconf.h> + +struct linked_list { + void *content; + struct linked_list *next; +} typedef linked_list; + +struct result { + char *res; + unsigned long *errors; + int num_errors; + char **certs; + int num_certs; +} typedef result; + + +struct array_with_length { + int size; + void *arr; +} typedef array_with_length; + +char * pop_error (result *res); +char *get_err_string(unsigned long err); + +void bio_to_str(BIO *bio_in, char **out); +int get_array_size(array_with_length *arr); + +char ** init_str_arr(int num); +char ** add_str_to_arr(const char *str, char **arr, int i); +void deallocate_str_arr(char **arr, int len); +char *bin_to_hex ( unsigned char *bin, int len); + +#define generic_helpers_h + + +#endif /* generic_helpers_h */ diff --git a/enzevalos_iphone/c/openssl-helpers.c b/enzevalos_iphone/c/smime-helpers.c similarity index 85% rename from enzevalos_iphone/c/openssl-helpers.c rename to enzevalos_iphone/c/smime-helpers.c index 481ec539..3c3ff16c 100644 --- a/enzevalos_iphone/c/openssl-helpers.c +++ b/enzevalos_iphone/c/smime-helpers.c @@ -5,21 +5,12 @@ // Created by lazarog98 on 02.03.20. // -#include "openssl-helpers.h" +#include "smime-helpers.h" #include <glob.h> // This is a wrapper around the OpenSSL functions, where everz function is primarily inspired by the SMIME demos in the OpenSSL github // https://github.com/openssl/openssl/tree/master/demos/smime -void bio_to_str(BIO *bio_in, char **out) { - char * tmp = NULL, *tmp2 = NULL; - long size = BIO_get_mem_data(bio_in, &tmp); - tmp2 = malloc(size+1); - tmp2[size]=0; // To Nullterminate the string - memcpy(tmp2, tmp, size); - *out = tmp2; -} - char ** stack_to_array(STACK_OF(X509) *stack) { char **str_arr = malloc(sizeof(char*)*sk_X509_num(stack)); @@ -93,16 +84,6 @@ array_with_length *create_list_of_errors() { return res; } -char *get_err_string(unsigned long err) { - const char *error = ERR_func_error_string(err); - //printf("\nError: %s", error); - char * error_permanent = (char *) malloc(strlen(error)+1); - error_permanent[strlen(error)]=0; // To Nullterminate the string - memcpy(error_permanent,error,strlen(error)); - - return error_permanent; -} - result * OpenSSL_encrypt(const char *text, const char *pem) { // https://github.com/openssl/openssl/blob/master/demos/cms/cms_enc.c BIO *in = NULL, *out = NULL, *rec_cert_bio = NULL; @@ -113,11 +94,8 @@ result * OpenSSL_encrypt(const char *text, const char *pem) { array_with_length *temp = NULL; result *res = malloc(sizeof(result)); - // this trick allows to hardcode a certificate as a string rec_cert_bio = BIO_new_mem_buf(pem, (int) strlen(pem)); - in = BIO_new_mem_buf(text, (int) strlen(text)); // simpletest - if (!rec_cert_bio) { printf("Failed reading mykey.pem!\n"); goto deinit; @@ -129,7 +107,7 @@ result * OpenSSL_encrypt(const char *text, const char *pem) { printf("Failed reading pem\n"); goto deinit; } - + cert_stack = sk_X509_new_null(); // note that if the stack is initialized correctly, the recipient certificate is pushed as a test @@ -156,8 +134,14 @@ result * OpenSSL_encrypt(const char *text, const char *pem) { // For testing - printf("\nSTART DATE %s\n", get_start_date(rec_cert)); - + // printf("\nSTART DATE %s\n", get_start_date(rec_cert)); + // printf("\nEND DATE %s\n", get_end_date(rec_cert)); + printf("\nemails\n"); + array_with_length *emails = get_emails(rec_cert); + for (int i = 0; i<emails->size; i++) { + printf("%s\n", ((char **) emails->arr)[0]); + } + bio_to_str(out, &(res->res)); deinit: // TODO: Collect all errors in a list and return them with the result @@ -457,33 +441,6 @@ deinit: X509_free(rec_cert); return res; } - -// startdate ASN1_TIME_print(out, X509_get0_notBefore(x)); - -char * get_start_date(X509 *cert) { - char *res = NULL; - BIO *out = NULL; - out = BIO_new(BIO_s_mem()); - ASN1_TIME_print(out, X509_get0_notBefore(cert)); - bio_to_str(out, &res); -deinit: - BIO_free(out); - return res; -} - -char * get_end_date(X509 *cert) { - char *res = NULL; - BIO *out = NULL; - out = BIO_new(BIO_s_mem()); - ASN1_TIME_print(out, X509_get0_notAfter(cert)); - bio_to_str(out, &res); -deinit: - BIO_free(out); - return res; -} - -// emndate ASN1_TIME_print(out, X509_get0_notAfter(x)); - /* email int j; STACK_OF(OPENSSL_STRING) *emlst; @@ -502,41 +459,3 @@ deinit: // subject print_name(out, "subject=", X509_get_subject_name(x), get_nameopt()); // kcacsac - -char ** init_str_arr(int num) -{ - char ** arr = malloc(num*sizeof(char*)); - return arr; -} - -char ** add_str_to_arr(const char *str, char **arr, int i) -{ - unsigned long len = strlen(str); - char *newstr = malloc(len+1); - memcpy(newstr, str, len); - newstr[len]=0; - arr[i]=newstr; - return arr; -} - -void deallocate_str_arr(char **arr, int len) -{ - for (int i=0; i < len; i++){ - free(arr[i]); - } - free(arr); -} - -char *bin_to_hex(unsigned char *bin, int len) -{ - unsigned char buf[3]; - char *res = malloc(2*len+1); - for (int i =0;i<len;i++) - { - sprintf(buf, "%02x", bin[i]); - res[i*2]=buf[0]; - res[i*2+1]=buf[1]; - } - res[len*2]=0; - return res; -} diff --git a/enzevalos_iphone/c/openssl-helpers.h b/enzevalos_iphone/c/smime-helpers.h similarity index 61% rename from enzevalos_iphone/c/openssl-helpers.h rename to enzevalos_iphone/c/smime-helpers.h index b97a2656..5b803dbd 100644 --- a/enzevalos_iphone/c/openssl-helpers.h +++ b/enzevalos_iphone/c/smime-helpers.h @@ -19,48 +19,22 @@ #include <openssl/bio.h> #include <openssl/pem.h> #include <openssl/pkcs7.h> -#include <openssl/pkcs12.h> #include <openssl/cms.h> #include <openssl/safestack.h> #include <openssl/x509.h> #include <openssl/opensslconf.h> - -struct linked_list { - void *content; - struct linked_list *next; -} typedef linked_list; - -struct result { - char *res; - unsigned long *errors; - int num_errors; - char **certs; - int num_certs; -} typedef result; - -struct array_with_length { - int size; - void *arr; -} typedef array_with_length; +#include "generic-helpers.h" +#include "certificate-helpers.h" STACK_OF(X509)* create_stack_x509(X509 *arr, int len); char ** stack_to_array(STACK_OF(X509) *stack); -char * pop_error (result *res); + void OpenSSL_print_ver(void); -// (de)init function makes initialization less cryptic -char *get_err_string(unsigned long err); -char * get_start_date(X509 *cert); -char * get_end_date(X509 *cert); result * OpenSSL_encrypt(const char *text, const char *pem); result * OpenSSL_decrypt(const char *str, const char *pem_cert, const char *pem_key); result * OpenSSL_sign(const char *text, const char *pem_cert, const char *pem_key, const int detached); result * OpenSSL_verify(const char *text, char **pem_cert, const int num_certs); result * get_fingerprint_from_pem(const char *pem, int md_alg); // 0 for SHA-256, 1 for SHA-1 -char ** init_str_arr(int num); -char ** add_str_to_arr(const char *str, char **arr, int i); -void deallocate_str_arr(char **arr, int len); -char *bin_to_hex ( unsigned char *bin, int len); - #endif /* openssl_helpers_h */ diff --git a/enzevalos_iphone/enzevalos_iphone-Bridging-Header.h b/enzevalos_iphone/enzevalos_iphone-Bridging-Header.h index fc62b8f0..725eede1 100644 --- a/enzevalos_iphone/enzevalos_iphone-Bridging-Header.h +++ b/enzevalos_iphone/enzevalos_iphone-Bridging-Header.h @@ -26,7 +26,7 @@ #import <GTMAppAuth/GTMAppAuth.h> #import <GTMSessionFetcher/GTMSessionFetcher.h> #import "OAuth/EmailHelper.h" -#import "c/openssl-helpers.h" +#import "c/smime-helpers.h" #import <openssl/pem.h> #import <openssl/cms.h> #import <openssl/err.h> -- GitLab