diff --git a/CryptoLoadExternalCertificate.xcodeproj/project.pbxproj b/CryptoLoadExternalCertificate.xcodeproj/project.pbxproj
index 98337f8..6dc6c93 100644
--- a/CryptoLoadExternalCertificate.xcodeproj/project.pbxproj
+++ b/CryptoLoadExternalCertificate.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 46;
+ objectVersion = 53;
objects = {
/* Begin PBXBuildFile section */
@@ -155,7 +155,8 @@
668B94CC1BC3D19F00913B83 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0800;
+ BuildIndependentTargetsInParallel = YES;
+ LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "Ignacio Nieto Carvajal";
TargetAttributes = {
668B94D31BC3D19F00913B83 = {
@@ -172,7 +173,7 @@
};
buildConfigurationList = 668B94CF1BC3D19F00913B83 /* Build configuration list for PBXProject "CryptoLoadExternalCertificate" */;
compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
+ developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -246,14 +247,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -276,7 +286,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -292,14 +302,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -316,10 +335,11 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
@@ -331,10 +351,13 @@
CODE_SIGN_ENTITLEMENTS = CryptoLoadExternalCertificate/CryptoLoadExternalCertificate.entitlements;
DEVELOPMENT_TEAM = 97P9DZHP78;
INFOPLIST_FILE = CryptoLoadExternalCertificate/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
PRODUCT_BUNDLE_IDENTIFIER = "com.Ignacio-Nieto-Carvajal.CryptoLoadExternalCertificate";
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -345,10 +368,13 @@
CODE_SIGN_ENTITLEMENTS = CryptoLoadExternalCertificate/CryptoLoadExternalCertificate.entitlements;
DEVELOPMENT_TEAM = 97P9DZHP78;
INFOPLIST_FILE = CryptoLoadExternalCertificate/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
PRODUCT_BUNDLE_IDENTIFIER = "com.Ignacio-Nieto-Carvajal.CryptoLoadExternalCertificate";
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
};
name = Release;
};
diff --git a/CryptoLoadExternalCertificate.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/CryptoLoadExternalCertificate.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/CryptoLoadExternalCertificate.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/CryptoLoadExternalCertificate/AppDelegate.swift b/CryptoLoadExternalCertificate/AppDelegate.swift
index 5909dea..5aa7604 100644
--- a/CryptoLoadExternalCertificate/AppDelegate.swift
+++ b/CryptoLoadExternalCertificate/AppDelegate.swift
@@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
- func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
diff --git a/CryptoLoadExternalCertificate/CryptoExportImportManager.swift b/CryptoLoadExternalCertificate/CryptoExportImportManager.swift
index febebb7..cbed136 100644
--- a/CryptoLoadExternalCertificate/CryptoExportImportManager.swift
+++ b/CryptoLoadExternalCertificate/CryptoExportImportManager.swift
@@ -3,88 +3,92 @@
// CryptoExportImportManager
//
// Created by Ignacio Nieto Carvajal on 6/10/15.
+// Adopted by Nikolay Kapsutin on 6/29/23
// Copyright © 2015 Ignacio Nieto Carvajal. All rights reserved.
//
-import UIKit
+import Foundation
+import Security
-/*
+/** This file originated from https://github.com/DigitalLeaves/CryptoExportImportManager/tree/master **/
-EC keys: http://www.opensource.apple.com/source/security_certtool/security_certtool-55103/src/dumpasn1.cfg
+/**
+ * This class exists due to the easy and intuitive way of using public keys generated outside iOS in
+ * the Security framework and CommonCrypto tools (yes, I'm being sarcastic here).
+ * CryptoCertificateImportManager is in charge of importing a certificate and obtaining a valid key
+ * reference to use in any of SecKey operations (SecKeyEncrypt, SecKeyRawVerify...).
+ * As far as I know, any other way of importing and using public keys from the outside is not
+ * advised: https://devforums.apple.com/message/301532#301532
+ */
+enum CryptoExportImportManager {
+ /*
-EC param 1
-OID = 06 07 2A 86 48 CE 3D 02 01
-Comment = ANSI X9.62 public key type
-Description = ecPublicKey (1 2 840 10045 2 1)
+ EC keys: http://www.opensource.apple.com/source/security_certtool/security_certtool-55103/src/dumpasn1.cfg
-EC param 2
-OID = 06 08 2A 86 48 CE 3D 03 01 07
-Comment = ANSI X9.62 named elliptic curve
-Description = ansiX9p256r1 (1 2 840 10045 3 1 7)
+ EC param 1
+ OID = 06 07 2A 86 48 CE 3D 02 01
+ Comment = ANSI X9.62 public key type
+ Description = ecPublicKey (1 2 840 10045 2 1)
-OID = 06 05 2B 81 04 00 22
-Comment = SECG (Certicom) named elliptic curve
-Description = secp384r1 (1 3 132 0 34)
+ EC param 2
+ OID = 06 08 2A 86 48 CE 3D 03 01 07
+ Comment = ANSI X9.62 named elliptic curve
+ Description = ansiX9p256r1 (1 2 840 10045 3 1 7)
-OID = 06 05 2B 81 04 00 23
-Comment = SECG (Certicom) named elliptic curve
-Description = secp521r1 (1 3 132 0 35)
+ OID = 06 05 2B 81 04 00 22
+ Comment = SECG (Certicom) named elliptic curve
+ Description = secp384r1 (1 3 132 0 34)
-EC params sequence: public key + curve 256r1
-30 13 06 07 2A 86 48 CE 3D 02 01 06 08 2A 86 48 CE 3D 03 01 07
-*/
+ OID = 06 05 2B 81 04 00 23
+ Comment = SECG (Certicom) named elliptic curve
+ Description = secp521r1 (1 3 132 0 35)
-// SECP256R1 EC public key header (length + EC params (sequence) + bitstring
-private let kCryptoExportImportManagerSecp256r1CurveLen = 256
-private let kCryptoExportImportManagerSecp256r1header: [UInt8] = [0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00]
-private let kCryptoExportImportManagerSecp256r1headerLen = 26
+ EC params sequence: public key + curve 256r1
+ 30 13 06 07 2A 86 48 CE 3D 02 01 06 08 2A 86 48 CE 3D 03 01 07
+ */
-private let kCryptoExportImportManagerSecp384r1CurveLen = 384
-private let kCryptoExportImportManagerSecp384r1header: [UInt8] = [0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00]
-private let kCryptoExportImportManagerSecp384r1headerLen = 23
+ // SECP256R1 EC public key header (length + EC params (sequence) + bitstring
+ private static let kCryptoExportImportManagerSecp256r1CurveLen = 256
+ private static let kCryptoExportImportManagerSecp256r1header: [UInt8] = [0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00]
+ private static let kCryptoExportImportManagerSecp256r1headerLen = 26
-private let kCryptoExportImportManagerSecp521r1CurveLen = 521
-private let kCryptoExportImportManagerSecp521r1header: [UInt8] = [0x30, 0x81, 0x9B, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23, 0x03, 0x81, 0x86, 0x00]
-private let kCryptoExportImportManagerSecp521r1headerLen = 25
+ private static let kCryptoExportImportManagerSecp384r1CurveLen = 384
+ private static let kCryptoExportImportManagerSecp384r1header: [UInt8] = [0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00]
+ private static let kCryptoExportImportManagerSecp384r1headerLen = 23
-/*
+ private static let kCryptoExportImportManagerSecp521r1CurveLen = 521
+ private static let kCryptoExportImportManagerSecp521r1header: [UInt8] = [0x30, 0x81, 0x9B, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23, 0x03, 0x81, 0x86, 0x00]
+ private static let kCryptoExportImportManagerSecp521r1headerLen = 25
-RSA keys: http://www.opensource.apple.com/source/security_certtool/security_certtool-55103/src/dumpasn1.cfg
+ /*
-OID = 06 09 2A 86 48 86 F7 0D 01 01 01
-Comment = PKCS #1
-Description = rsaEncryption (1 2 840 113549 1 1 1)
+ RSA keys: http://www.opensource.apple.com/source/security_certtool/security_certtool-55103/src/dumpasn1.cfg
-NULL byte: 05 00
-*/
+ OID = 06 09 2A 86 48 86 F7 0D 01 01 01
+ Comment = PKCS #1
+ Description = rsaEncryption (1 2 840 113549 1 1 1)
-// RSA OID header
-private let kCryptoExportImportManagerRSAOIDHeader: [UInt8] = [0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00]
-private let kCryptoExportImportManagerRSAOIDHeaderLength = 15
+ NULL byte: 05 00
+ */
-// ASN.1 encoding parameters.
-private let kCryptoExportImportManagerASNHeaderSequenceMark: UInt8 = 48 // 0x30
-private let kCryptoExportImportManagerASNHeaderIntegerMark: UInt8 = 02 // 0x32
-private let kCryptoExportImportManagerASNHeaderBitstringMark: UInt8 = 03 //0x03
-private let kCryptoExportImportManagerASNHeaderNullMark: UInt8 = 05 //0x05
-private let kCryptoExportImportManagerASNHeaderRSAEncryptionObjectMark: UInt8 = 06 //0x06
-private let kCryptoExportImportManagerExtendedLengthMark: UInt8 = 128 // 0x80
-private let kCryptoExportImportManagerASNHeaderLengthForRSA = 15
+ // RSA OID header
+ private static let kCryptoExportImportManagerRSAOIDHeader: [UInt8] = [0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00]
+ private static let kCryptoExportImportManagerRSAOIDHeaderLength = 15
-// PEM encoding constants
-private let kCryptoExportImportManagerPublicKeyInitialTag = "-----BEGIN PUBLIC KEY-----\n"
-private let kCryptoExportImportManagerPublicKeyFinalTag = "-----END PUBLIC KEY-----"
-private let kCryptoExportImportManagerPublicNumberOfCharactersInALine = 64
+ // ASN.1 encoding parameters.
+ private static let kCryptoExportImportManagerASNHeaderSequenceMark: UInt8 = 48 // 0x30
+ private static let kCryptoExportImportManagerASNHeaderIntegerMark: UInt8 = 02 // 0x32
+ private static let kCryptoExportImportManagerASNHeaderBitstringMark: UInt8 = 03 //0x03
+ private static let kCryptoExportImportManagerASNHeaderNullMark: UInt8 = 05 //0x05
+ private static let kCryptoExportImportManagerASNHeaderRSAEncryptionObjectMark: UInt8 = 06 //0x06
+ private static let kCryptoExportImportManagerExtendedLengthMark: UInt8 = 128 // 0x80
+ private static let kCryptoExportImportManagerASNHeaderLengthForRSA = 15
+
+ // PEM encoding constants
+ private static let kCryptoExportImportManagerPublicKeyInitialTag = "-----BEGIN PUBLIC KEY-----\n"
+ private static let kCryptoExportImportManagerPublicKeyFinalTag = "-----END PUBLIC KEY-----"
+ private static let kCryptoExportImportManagerPublicNumberOfCharactersInALine = 64
-/**
- * This class exists due to the easy and intuitive way of using public keys generated outside iOS in
- * the Security framework and CommonCrypto tools (yes, I'm being sarcastic here).
- * CryptoCertificateImportManager is in charge of importing a certificate and obtaining a valid key
- * reference to use in any of SecKey operations (SecKeyEncrypt, SecKeyRawVerify...).
- * As far as I know, any other way of importing and using public keys from the outside is not
- * advised: https://devforums.apple.com/message/301532#301532
- */
-class CryptoExportImportManager: NSObject {
// MARK: - Import methods.
/**
@@ -92,7 +96,7 @@ class CryptoExportImportManager: NSObject {
* used in any of SecKey operations (SecKeyEncrypt, SecKeyRawVerify...).
* Receives the certificate data in DER format.
*/
- func importPublicKeyReferenceFromDERCertificate(_ certData: Data) -> SecKey? {
+ static func importPublicKeyReferenceFromDERCertificate(_ certData: Data) -> SecKey? {
// first we create the certificate reference
guard let certRef = SecCertificateCreateWithData(nil, certData as CFData) else { return nil }
print("Successfully generated a valid certificate reference from the data.")
@@ -102,15 +106,31 @@ class CryptoExportImportManager: NSObject {
let secTrustStatus = SecTrustCreateWithCertificates(certRef, nil, &secTrust)
print("Generating a SecTrust reference from the certificate: \(secTrustStatus)")
if secTrustStatus != errSecSuccess { return nil }
+ guard let secTrust = secTrust else {return nil}
// now evaluate the certificate.
var resultType: SecTrustResultType = SecTrustResultType(rawValue: UInt32(0))! // result will be ignored.
- let evaluateStatus = SecTrustEvaluate(secTrust!, &resultType)
- print("Evaluating the obtained SecTrust reference: \(evaluateStatus)")
- if evaluateStatus != errSecSuccess { return nil }
+
+ if #available(iOS 14, *) {
+ if SecTrustEvaluateWithError(secTrust, nil) == false {
+ print("Evaluating the obtained SecTrust reference has been failed!")
+ return nil
+ }
+ }
+ else {
+ let evaluateStatus = SecTrustEvaluate(secTrust, &resultType)
+ print("Evaluating the obtained SecTrust reference: \(evaluateStatus)")
+ if evaluateStatus != errSecSuccess { return nil }
+ }
// lastly, once evaluated, we can export the public key from the certificate leaf.
- let publicKeyRef = SecTrustCopyPublicKey(secTrust!)
+ let publicKeyRef:SecKey?
+ if #available(iOS 14, *) {
+ publicKeyRef = SecTrustCopyKey(secTrust)
+ }
+ else {
+ publicKeyRef = SecTrustCopyPublicKey(secTrust)
+ }
print("Got public key reference: \(String(describing: publicKeyRef))")
return publicKeyRef
}
@@ -121,7 +141,7 @@ class CryptoExportImportManager: NSObject {
* Exports a key retrieved from the keychain so it can be used outside iOS (i.e: in OpenSSL).
* Returns a DER representation of the key.
*/
- func exportPublicKeyToDER(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> Data? {
+ static func exportPublicKeyToDER(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> Data? {
if keyType == kSecAttrKeyTypeEC as String {
return exportECPublicKeyToDER(rawPublicKeyBytes, keyType: keyType, keySize: keySize)
} else if keyType == kSecAttrKeyTypeRSA as String {
@@ -135,7 +155,7 @@ class CryptoExportImportManager: NSObject {
* Exports a key retrieved from the keychain so it can be used outside iOS (i.e: in OpenSSL).
* Returns a PEM representation of the key.
*/
- func exportPublicKeyToPEM(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> String? {
+ static func exportPublicKeyToPEM(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> String? {
if keyType == kSecAttrKeyTypeEC as String {
return exportECPublicKeyToPEM(rawPublicKeyBytes, keyType: keyType, keySize: keySize)
} else if keyType == kSecAttrKeyTypeRSA as String {
@@ -151,7 +171,7 @@ class CryptoExportImportManager: NSObject {
* keys in a very raw format. If we want to use it on OpenSSL, PHP or almost anywhere outside iOS, we
* need to remove add the full PKCS#1 ASN.1 wrapping. Returns a DER representation of the key.
*/
- func exportRSAPublicKeyToDER(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> Data {
+ static func exportRSAPublicKeyToDER(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> Data {
// first we create the space for the ASN.1 header and decide about its length
let bitstringEncodingLength = bytesNeededForRepresentingInteger(rawPublicKeyBytes.count)
@@ -186,7 +206,7 @@ class CryptoExportImportManager: NSObject {
* keys in a very raw format. If we want to use it on OpenSSL, PHP or almost anywhere outside iOS, we
* need to remove add the full PKCS#1 ASN.1 wrapping. Returns a DER representation of the key.
*/
- func exportRSAPublicKeyToPEM(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> String {
+ static func exportRSAPublicKeyToPEM(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> String {
return PEMKeyFromDERKey(exportRSAPublicKeyToDER(rawPublicKeyBytes, keyType: keyType, keySize: keySize))
}
@@ -194,7 +214,7 @@ class CryptoExportImportManager: NSObject {
/**
* Returns the number of bytes needed to represent an integer.
*/
- func bytesNeededForRepresentingInteger(_ number: Int) -> Int {
+ static func bytesNeededForRepresentingInteger(_ number: Int) -> Int {
if number <= 0 { return 0 }
var i = 1
while (i < 8 && number >= (1 << (i * 8))) { i += 1 }
@@ -206,7 +226,7 @@ class CryptoExportImportManager: NSObject {
* writing the ASN.1 sequence. The memory of buffer must be initialized (i.e: from an NSData).
* Returns the number of bytes used to write the sequence.
*/
- func encodeASN1LengthParameter(_ length: Int, buffer: UnsafeMutablePointer) -> Int {
+ static func encodeASN1LengthParameter(_ length: Int, buffer: UnsafeMutablePointer) -> Int {
if length < Int(kCryptoExportImportManagerExtendedLengthMark) {
buffer[0] = UInt8(length)
return 1 // just one byte was used, no need for length starting mark (0x80).
@@ -230,7 +250,7 @@ class CryptoExportImportManager: NSObject {
* header and codifies the result as valid base64 string, 64 characters split.
* Returns a DER representation of the key.
*/
- func exportECPublicKeyToDER(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> Data {
+ static func exportECPublicKeyToDER(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> Data {
print("Exporting EC raw key: \(rawPublicKeyBytes)")
// first retrieve the header with the OID for the proper key curve.
let curveOIDHeader: [UInt8]
@@ -262,7 +282,7 @@ class CryptoExportImportManager: NSObject {
* header and codifies the result as valid base64 string, 64 characters split.
* Returns a DER representation of the key.
*/
- func exportECPublicKeyToPEM(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> String {
+ static func exportECPublicKeyToPEM(_ rawPublicKeyBytes: Data, keyType: String, keySize: Int) -> String {
return PEMKeyFromDERKey(exportECPublicKeyToDER(rawPublicKeyBytes, keyType: keyType, keySize: keySize))
}
@@ -271,7 +291,7 @@ class CryptoExportImportManager: NSObject {
* the key and then splits this base64 string in 64 character chunks. Then it wraps it in
* BEGIN and END key tags.
*/
- func PEMKeyFromDERKey(_ data: Data) -> String {
+ static func PEMKeyFromDERKey(_ data: Data) -> String {
// base64 encode the result
let base64EncodedString = data.base64EncodedString(options: [])
diff --git a/CryptoLoadExternalCertificate/ExportViewController.swift b/CryptoLoadExternalCertificate/ExportViewController.swift
index 9a378d0..39b9f3c 100644
--- a/CryptoLoadExternalCertificate/ExportViewController.swift
+++ b/CryptoLoadExternalCertificate/ExportViewController.swift
@@ -66,11 +66,10 @@ class ExportViewController: UIViewController {
func exportKeyFromRawBytesAndShowInTextView(_ rawBytes: Data) {
let keyType = getKeyTypeFromSegmentedControl()
let keySize = getKeyLengthFromSegmentedControl()
- let exportImportManager = CryptoExportImportManager()
- if let exportableDERKey = exportImportManager.exportPublicKeyToDER(rawBytes, keyType: keyType, keySize: keySize) {
+ if let exportableDERKey = CryptoExportImportManager.exportPublicKeyToDER(rawBytes, keyType: keyType, keySize: keySize) {
self.textView.text = self.textView.text + "Exportable key in DER format:\n\(exportableDERKey.hexDescription)\n\n"
print("Exportable key in DER format:\n\(exportableDERKey.hexDescription)\n")
- let exportablePEMKey = exportImportManager.PEMKeyFromDERKey(exportableDERKey)
+ let exportablePEMKey = CryptoExportImportManager.PEMKeyFromDERKey(exportableDERKey)
self.textView.text = self.textView.text + "Exportable key in PEM format:\n\(exportablePEMKey)\n\n"
print("Exportable key in PEM format:\n\(exportablePEMKey)\n")
} else {
@@ -112,7 +111,7 @@ class ExportViewController: UIViewController {
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { () -> Void in
var pubKey, privKey: SecKey?
let status = SecKeyGeneratePair(parameters as CFDictionary, &pubKey, &privKey)
- if status == errSecSuccess {
+ if status == errSecSuccess, let privKey = privKey, let pubKey = pubKey {
DispatchQueue.main.async(execute: {
print("Successfully generated keypair!\nPrivate key: \(privKey)\nPublic key: \(pubKey)")
let publicKeyData = self.getPublicKeyData(kExportKeyTag + self.getKeyTypeFromSegmentedControl())
diff --git a/CryptoLoadExternalCertificate/ImportViewController.swift b/CryptoLoadExternalCertificate/ImportViewController.swift
index 3fe2ac3..55e17fa 100644
--- a/CryptoLoadExternalCertificate/ImportViewController.swift
+++ b/CryptoLoadExternalCertificate/ImportViewController.swift
@@ -38,8 +38,7 @@ class ImportViewController: UIViewController {
}
// if we got the certificate data, let's extract the public key reference.
- let importExportManager = CryptoExportImportManager()
- if let publicKeyRef = importExportManager.importPublicKeyReferenceFromDERCertificate(certData) {
+ if let publicKeyRef = CryptoExportImportManager.importPublicKeyReferenceFromDERCertificate(certData) {
textView.text = "Successfully extracted public key from certificate:\n\(publicKeyRef)\n"
} else {
textView.text = "Oups! I was unable to retrieve a public key from the certificate."