Newer
Older
LaserMethane / Pods / SwiftyRSA / Source / SwiftyRSA+ObjC.swift
Pengxh on 28 Jul 2021 8 KB first commit
//
//  SwiftyRSA+ObjC.swift
//  SwiftyRSA
//
//  Created by Lois Di Qual on 3/6/17.
//  Copyright © 2017 Scoop. All rights reserved.
//

import Foundation

/// This files allows the ObjC runtime to access SwiftyRSA classes while keeping the swift code Swiftyish.
/// Things like protocol extensions or throwing and returning booleans are not well supported by ObjC, so instead
/// of giving access to the Swift classes directly, we're wrapping then their `_objc_*` counterpart.
/// They are exposed under the same name to the ObjC runtime, and all methods are present – they're just delegated
/// to the wrapped swift value.

private protocol ObjcBridgeable {
    associatedtype SwiftType
    var swiftValue: SwiftType { get }
    init(swiftValue: SwiftType)
}

// MARK: - PublicKey

@objc(PublicKey)
public class _objc_PublicKey: NSObject, Key, ObjcBridgeable { // swiftlint:disable:this type_name
    
    fileprivate let swiftValue: PublicKey
    
    @objc public var reference: SecKey {
        return swiftValue.reference
    }
    
    @objc public var originalData: Data? {
        return swiftValue.originalData
    }
    
    @objc public func pemString() throws -> String {
        return try swiftValue.pemString()
    }
    
    @objc public func data() throws -> Data {
        return try swiftValue.data()
    }
    
    @objc public func base64String() throws -> String {
        return try swiftValue.base64String()
    }
    
    required public init(swiftValue: PublicKey) {
        self.swiftValue = swiftValue
    }
    
    @objc required public init(data: Data) throws {
        self.swiftValue = try PublicKey(data: data)
    }
    
    @objc public required init(reference: SecKey) throws {
        self.swiftValue = try PublicKey(reference: reference)
    }
    
    @objc public required init(base64Encoded base64String: String) throws {
        self.swiftValue = try PublicKey(base64Encoded: base64String)
    }
    
    @objc public required init(pemEncoded pemString: String) throws {
        self.swiftValue = try PublicKey(pemEncoded: pemString)
    }
    
    @objc public required init(pemNamed pemName: String, in bundle: Bundle) throws {
        self.swiftValue = try PublicKey(pemNamed: pemName, in: bundle)
    }
    
    @objc public required init(derNamed derName: String, in bundle: Bundle) throws {
        self.swiftValue = try PublicKey(derNamed: derName, in: bundle)
    }
    
    @objc public static func publicKeys(pemEncoded pemString: String) -> [_objc_PublicKey] {
        return PublicKey.publicKeys(pemEncoded: pemString).map { _objc_PublicKey(swiftValue: $0) }
    }
}

// MARK: - PrivateKey

@objc(PrivateKey)
public class _objc_PrivateKey: NSObject, Key, ObjcBridgeable { // swiftlint:disable:this type_name
    
    fileprivate let swiftValue: PrivateKey
    
    @objc public var reference: SecKey {
        return swiftValue.reference
    }
    
    @objc public var originalData: Data? {
        return swiftValue.originalData
    }
    
    @objc public func pemString() throws -> String {
        return try swiftValue.pemString()
    }
    
    @objc public func data() throws -> Data {
        return try swiftValue.data()
    }
    
    @objc public func base64String() throws -> String {
        return try swiftValue.base64String()
    }
    
    public required init(swiftValue: PrivateKey) {
        self.swiftValue = swiftValue
    }
    
    @objc public required init(data: Data) throws {
        self.swiftValue = try PrivateKey(data: data)
    }
    
    @objc public required init(reference: SecKey) throws {
        self.swiftValue = try PrivateKey(reference: reference)
    }
    
    @objc public required init(base64Encoded base64String: String) throws {
        self.swiftValue = try PrivateKey(base64Encoded: base64String)
    }
    
    @objc public required init(pemEncoded pemString: String) throws {
        self.swiftValue = try PrivateKey(pemEncoded: pemString)
    }
    
    @objc public required init(pemNamed pemName: String, in bundle: Bundle) throws {
        self.swiftValue = try PrivateKey(pemNamed: pemName, in: bundle)
    }
    
    @objc public required init(derNamed derName: String, in bundle: Bundle) throws {
        self.swiftValue = try PrivateKey(derNamed: derName, in: bundle)
    }
}

// MARK: - VerificationResult

@objc(VerificationResult)
public class _objc_VerificationResult: NSObject { // swiftlint:disable:this type_name
    @objc public let isSuccessful: Bool
    init(isSuccessful: Bool) {
        self.isSuccessful = isSuccessful
    }
}

// MARK: - ClearMessage

@objc(ClearMessage)
public class _objc_ClearMessage: NSObject, Message, ObjcBridgeable { // swiftlint:disable:this type_name
    
    fileprivate let swiftValue: ClearMessage
    
    @objc public var base64String: String {
        return swiftValue.base64String
    }
    
    @objc public var data: Data {
        return swiftValue.data
    }
    
    public required init(swiftValue: ClearMessage) {
        self.swiftValue = swiftValue
    }
    
    @objc public required init(data: Data) {
        self.swiftValue = ClearMessage(data: data)
    }
    
    @objc public required init(string: String, using rawEncoding: UInt) throws {
        let encoding = String.Encoding(rawValue: rawEncoding)
        self.swiftValue = try ClearMessage(string: string, using: encoding)
    }
    
    @objc public required init(base64Encoded base64String: String) throws {
        self.swiftValue = try ClearMessage(base64Encoded: base64String)
    }
    
    @objc public func string(encoding rawEncoding: UInt) throws -> String {
        let encoding = String.Encoding(rawValue: rawEncoding)
        return try swiftValue.string(encoding: encoding)
    }
    
    @objc public func encrypted(with key: _objc_PublicKey, padding: Padding) throws -> _objc_EncryptedMessage {
        let encryptedMessage = try swiftValue.encrypted(with: key.swiftValue, padding: padding)
        return _objc_EncryptedMessage(swiftValue: encryptedMessage)
    }
    
    @objc public func signed(with key: _objc_PrivateKey, digestType: _objc_Signature.DigestType) throws -> _objc_Signature {
        let signature = try swiftValue.signed(with: key.swiftValue, digestType: digestType.swiftValue)
        return _objc_Signature(swiftValue: signature)
    }
    
    @objc public func verify(with key: _objc_PublicKey, signature: _objc_Signature, digestType: _objc_Signature.DigestType) throws -> _objc_VerificationResult {
        let isSuccessful = try swiftValue.verify(with: key.swiftValue, signature: signature.swiftValue, digestType: digestType.swiftValue)
        return _objc_VerificationResult(isSuccessful: isSuccessful)
    }
}

// MARK: - EncryptedMessage

@objc(EncryptedMessage)
public class _objc_EncryptedMessage: NSObject, Message, ObjcBridgeable { // swiftlint:disable:this type_name
    
    fileprivate let swiftValue: EncryptedMessage
    
    @objc public var base64String: String {
        return swiftValue.base64String
    }
    
    @objc public var data: Data {
        return swiftValue.data
    }
    
    public required init(swiftValue: EncryptedMessage) {
        self.swiftValue = swiftValue
    }
    
    @objc public required init(data: Data) {
        self.swiftValue = EncryptedMessage(data: data)
    }
    
    @objc public required init(base64Encoded base64String: String) throws {
        self.swiftValue = try EncryptedMessage(base64Encoded: base64String)
    }
    
    @objc public func decrypted(with key: _objc_PrivateKey, padding: Padding) throws -> _objc_ClearMessage {
        let clearMessage = try swiftValue.decrypted(with: key.swiftValue, padding: padding)
        return _objc_ClearMessage(swiftValue: clearMessage)
    }
}

// MARK: - Signature

@objc(Signature)
public class _objc_Signature: NSObject, ObjcBridgeable { // swiftlint:disable:this type_name
    
    @objc
    public enum DigestType: Int {
        case sha1
        case sha224
        case sha256
        case sha384
        case sha512
        
        fileprivate var swiftValue: Signature.DigestType {
            switch self {
            case .sha1: return .sha1
            case .sha224: return .sha224
            case .sha256: return .sha256
            case .sha384: return .sha384
            case .sha512: return .sha512
            }
        }
    }
    
    fileprivate let swiftValue: Signature
    
    @objc public var base64String: String {
        return swiftValue.base64String
    }
    
    @objc public var data: Data {
        return swiftValue.data
    }
    
    public required init(swiftValue: Signature) {
        self.swiftValue = swiftValue
    }
    
    @objc public init(data: Data) {
        self.swiftValue = Signature(data: data)
    }
    
    @objc public required init(base64Encoded base64String: String) throws {
        self.swiftValue = try Signature(base64Encoded: base64String)
    }
}