|
@@ -15,19 +15,24 @@
|
|
|
|
|
|
// MARK: SecKey <-> RSA Interoperability
|
|
|
|
|
|
- // From CryptoSwift RSA -> External Representation -> SecKey
|
|
|
- func testRSAExternalRepresentationPrivate() throws {
|
|
|
+ /// From CryptoSwift RSA -> External Representation -> SecKey
|
|
|
+ ///
|
|
|
+ /// This test enforces that
|
|
|
+ /// 1) We can export the raw external representation of a CryptoSwift RSA Public Key
|
|
|
+ /// 2) And that we can import / create an RSA SecKey from that raw external representation
|
|
|
+ /// 3) Proves interoperability between Apple's `Security` Framework and `CryptoSwift`
|
|
|
+ func testRSAExternalRepresentationPublic() throws {
|
|
|
|
|
|
// Generate a CryptoSwift RSA Key
|
|
|
let rsaCryptoSwift = try RSA(keySize: 1024)
|
|
|
|
|
|
// Get the key's rawExternalRepresentation
|
|
|
- let rsaCryptoSwiftRawRep = try rsaCryptoSwift.privateKeyDER()
|
|
|
+ let rsaCryptoSwiftRawRep = try rsaCryptoSwift.publicKeyDER()
|
|
|
|
|
|
// We should be able to instantiate an RSA SecKey from this data
|
|
|
let attributes: [String: Any] = [
|
|
|
kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
|
|
|
- kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
|
|
|
+ kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
|
|
|
kSecAttrKeySizeInBits as String: 1024,
|
|
|
kSecAttrIsPermanent as String: false
|
|
|
]
|
|
@@ -46,22 +51,27 @@
|
|
|
|
|
|
// Ensure both the CryptoSwift Ext Rep and the SecKey Ext Rep match
|
|
|
XCTAssertEqual(rsaSecKeyRawRep, Data(rsaCryptoSwiftRawRep))
|
|
|
- XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.externalRepresentation())
|
|
|
+ XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.publicKeyExternalRepresentation())
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/// From CryptoSwift RSA -> External Representation -> SecKey
|
|
|
- func testRSAExternalRepresentationPublic() throws {
|
|
|
+ ///
|
|
|
+ /// This test enforces that
|
|
|
+ /// 1) We can export the raw external representation of a CryptoSwift RSA Private Key
|
|
|
+ /// 2) And that we can import / create an RSA SecKey from that raw external representation
|
|
|
+ /// 3) Proves interoperability between Apple's `Security` Framework and `CryptoSwift`
|
|
|
+ func testRSAExternalRepresentationPrivate() throws {
|
|
|
|
|
|
// Generate a CryptoSwift RSA Key
|
|
|
let rsaCryptoSwift = try RSA(keySize: 1024)
|
|
|
|
|
|
// Get the key's rawExternalRepresentation
|
|
|
- let rsaCryptoSwiftRawRep = try rsaCryptoSwift.publicKeyDER()
|
|
|
+ let rsaCryptoSwiftRawRep = try rsaCryptoSwift.privateKeyDER()
|
|
|
|
|
|
// We should be able to instantiate an RSA SecKey from this data
|
|
|
let attributes: [String: Any] = [
|
|
|
kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
|
|
|
- kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
|
|
|
+ kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
|
|
|
kSecAttrKeySizeInBits as String: 1024,
|
|
|
kSecAttrIsPermanent as String: false
|
|
|
]
|
|
@@ -80,11 +90,16 @@
|
|
|
|
|
|
// Ensure both the CryptoSwift Ext Rep and the SecKey Ext Rep match
|
|
|
XCTAssertEqual(rsaSecKeyRawRep, Data(rsaCryptoSwiftRawRep))
|
|
|
- XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.publicKeyExternalRepresentation())
|
|
|
+ XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.externalRepresentation())
|
|
|
}
|
|
|
|
|
|
/// From SecKey -> External Representation -> CryptoSwift RSA
|
|
|
- func testSecKeyExternalRepresentationPrivate() throws {
|
|
|
+ ///
|
|
|
+ /// This test enforces that
|
|
|
+ /// 1) Given the raw external representation of a Public RSA SecKey, we can import that same key into CryptoSwift
|
|
|
+ /// 2) When we export the raw external representation of the RSA Key we get the exact same data
|
|
|
+ /// 3) Proves interoperability between Apple's `Security` Framework and `CryptoSwift`
|
|
|
+ func testSecKeyExternalRepresentationPublic() throws {
|
|
|
// Generate a SecKey RSA Key
|
|
|
let parameters: [CFString: Any] = [
|
|
|
kSecAttrKeyType: kSecAttrKeyTypeRSA,
|
|
@@ -99,9 +114,15 @@
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // Lets grab the external representation
|
|
|
+ // Extract the public key from the private RSA SecKey
|
|
|
+ guard let rsaSecKeyPublic = SecKeyCopyPublicKey(rsaSecKey) else {
|
|
|
+ XCTFail("Public Key Extraction Error")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // Lets grab the external representation of the public key
|
|
|
var externalRepError: Unmanaged<CFError>?
|
|
|
- guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
|
|
|
+ guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKeyPublic, &externalRepError) as? Data else {
|
|
|
XCTFail("Failed to copy external representation for RSA SecKey")
|
|
|
return
|
|
|
}
|
|
@@ -109,12 +130,17 @@
|
|
|
// Ensure we can import the private RSA key into CryptoSwift
|
|
|
let rsaCryptoSwift = try RSA(rawRepresentation: rsaSecKeyRawRep)
|
|
|
|
|
|
- XCTAssertNotNil(rsaCryptoSwift.d)
|
|
|
+ XCTAssertNil(rsaCryptoSwift.d)
|
|
|
XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.externalRepresentation())
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/// From SecKey -> External Representation -> CryptoSwift RSA
|
|
|
- func testSecKeyExternalRepresentationPublic() throws {
|
|
|
+ ///
|
|
|
+ /// This test enforces that
|
|
|
+ /// 1) Given the raw external representation of a Private RSA SecKey, we can import that same key into CryptoSwift
|
|
|
+ /// 2) When we export the raw external representation of the RSA Key we get the exact same data
|
|
|
+ /// 3) Proves interoperability between Apple's `Security` Framework and `CryptoSwift`
|
|
|
+ func testSecKeyExternalRepresentationPrivate() throws {
|
|
|
// Generate a SecKey RSA Key
|
|
|
let parameters: [CFString: Any] = [
|
|
|
kSecAttrKeyType: kSecAttrKeyTypeRSA,
|
|
@@ -129,15 +155,9 @@
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // Extract the public key from the private RSA SecKey
|
|
|
- guard let rsaSecKeyPublic = SecKeyCopyPublicKey(rsaSecKey) else {
|
|
|
- XCTFail("Public Key Extraction Error")
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // Lets grab the external representation of the public key
|
|
|
+ // Lets grab the external representation
|
|
|
var externalRepError: Unmanaged<CFError>?
|
|
|
- guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKeyPublic, &externalRepError) as? Data else {
|
|
|
+ guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
|
|
|
XCTFail("Failed to copy external representation for RSA SecKey")
|
|
|
return
|
|
|
}
|
|
@@ -145,13 +165,20 @@
|
|
|
// Ensure we can import the private RSA key into CryptoSwift
|
|
|
let rsaCryptoSwift = try RSA(rawRepresentation: rsaSecKeyRawRep)
|
|
|
|
|
|
- XCTAssertNil(rsaCryptoSwift.d)
|
|
|
+ XCTAssertNotNil(rsaCryptoSwift.d)
|
|
|
XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.externalRepresentation())
|
|
|
}
|
|
|
|
|
|
- func testRSASecKey() throws {
|
|
|
+ /// This test generates X RSA keys and tests them between `Security` and `CryptoSwift` for interoperability
|
|
|
+ ///
|
|
|
+ /// For each key generated, this test enforces that
|
|
|
+ /// 1) We can import the raw external representation (generated by the `Security` framework) of the RSA Key into `CryptoSwift`
|
|
|
+ /// 2) When signing messages using a deterministic variant, we get the same output from both `Security` and `CryptoSwift`
|
|
|
+ /// 3) We can verify a signature generated from `CryptoSwift` with `Security` and vice versa
|
|
|
+ /// 4) We can encrypt and decrypt a message generated from `CryptoSwift` with `Security` and vice versa
|
|
|
+ func testRSASecKeys() throws {
|
|
|
|
|
|
- let tests = 1
|
|
|
+ let tests = 3
|
|
|
let messageToSign: String = "RSA Keys!"
|
|
|
|
|
|
for _ in 0..<tests {
|
|
@@ -200,8 +227,6 @@
|
|
|
// Decrypt with SecKey
|
|
|
XCTAssertEqual(try self.secKeyDecrypt(csEncryption, usingVariant: .rsaEncryptionRaw, withKey: rsaSecKey).bytes, messageToSign.bytes, "SecKey Decryption of CryptoSwift Encryption Failed")
|
|
|
|
|
|
- //print(csEncryption)
|
|
|
- //print(skEncryption.bytes)
|
|
|
XCTAssertEqual(csEncryption, skEncryption.bytes, "Encrypted Data Does Not Match")
|
|
|
|
|
|
// Encrypt with SecKey
|
|
@@ -213,9 +238,6 @@
|
|
|
let csEncryption2 = try rsaCryptoSwift.encrypt(messageToSign.bytes, variant: .pksc1v15)
|
|
|
// Decrypt with SecKey
|
|
|
XCTAssertEqual(try self.secKeyDecrypt(csEncryption2, usingVariant: .rsaEncryptionPKCS1, withKey: rsaSecKey).bytes, messageToSign.bytes, "SecKey Decryption of CryptoSwift Encryption Failed")
|
|
|
-
|
|
|
- print(csEncryption2.count)
|
|
|
- print(skEncryption2.bytes.count)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -278,10 +300,31 @@
|
|
|
}
|
|
|
return (decryptedData as Data).drop { $0 == 0x00 }
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
+ extension RSASecKeyTests {
|
|
|
+ static func allTests() -> [(String, (RSASecKeyTests) -> () throws -> Void)] {
|
|
|
+ let tests = [
|
|
|
+ ("testRSAExternalRepresentationPublic", testRSAExternalRepresentationPublic),
|
|
|
+ ("testRSAExternalRepresentationPrivate", testRSAExternalRepresentationPrivate),
|
|
|
+ ("testSecKeyExternalRepresentationPublic", testSecKeyExternalRepresentationPublic),
|
|
|
+ ("testSecKeyExternalRepresentationPrivate", testSecKeyExternalRepresentationPrivate),
|
|
|
+ ("testRSASecKeys", testRSASecKeys)
|
|
|
+ ]
|
|
|
+
|
|
|
+ return tests
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // - MARK: Test Fixture Generation Code
|
|
|
+ extension RSASecKeyTests {
|
|
|
+
|
|
|
+ /// This 'Test' generates an RSA Key and uses that key to sign and encrypt a series of messages that we can test against.
|
|
|
+ ///
|
|
|
+ /// It prints a `Fixture` object that can be copy and pasted / used in other tests.
|
|
|
func testCreateTestFixture() throws {
|
|
|
|
|
|
- let keySize = 1056
|
|
|
+ let keySize = 1024
|
|
|
let messages = [
|
|
|
"",
|
|
|
"👋",
|
|
@@ -325,14 +368,14 @@
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- var template = FixtureTemplate2
|
|
|
+ var template = RSASecKeyTests.FixtureTemplate
|
|
|
template = template.replacingOccurrences(of: "{{KEY_SIZE}}", with: "\(keySize)")
|
|
|
template = template.replacingOccurrences(of: "{{PUBLIC_DER}}", with: "\(publicRSASecKeyRawRep.base64EncodedString())")
|
|
|
template = template.replacingOccurrences(of: "{{PRIVATE_DER}}", with: "\(privateRSASecKeyRawRep.base64EncodedString())")
|
|
|
|
|
|
var messageEntries: [String] = []
|
|
|
for message in messages {
|
|
|
- var messageTemplate = MessageTemplate
|
|
|
+ var messageTemplate = RSASecKeyTests.MessageTemplate
|
|
|
messageTemplate = messageTemplate.replacingOccurrences(of: "{{PLAINTEXT_MESSAGE}}", with: message)
|
|
|
|
|
|
let encryptedMessages = try encrypt(data: message.data(using: .utf8)!, with: rsaSecKeyPublic)
|
|
@@ -346,182 +389,130 @@
|
|
|
|
|
|
template = template.replacingOccurrences(of: "{{MESSAGE_TEMPLATES}}", with: "\(messageEntries.joined(separator: ",\n\t"))")
|
|
|
|
|
|
+ print("\n**************************")
|
|
|
+ print(" Test Fixture Output")
|
|
|
+ print("**************************\n")
|
|
|
print(template)
|
|
|
+ print("\n**************************")
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- extension RSASecKeyTests {
|
|
|
- static func allTests() -> [(String, (RSASecKeyTests) -> () throws -> Void)] {
|
|
|
- let tests = [
|
|
|
- ("testRSAExternalRepresentationPrivate", testRSAExternalRepresentationPrivate),
|
|
|
- ("testRSAExternalRepresentationPublic", testRSAExternalRepresentationPublic),
|
|
|
- ("testSecKeyExternalRepresentationPrivate", testSecKeyExternalRepresentationPrivate),
|
|
|
- ("testSecKeyExternalRepresentationPublic", testSecKeyExternalRepresentationPublic)
|
|
|
- ]
|
|
|
|
|
|
- return tests
|
|
|
- }
|
|
|
- }
|
|
|
+ private static let FixtureTemplate = """
|
|
|
+ static let RSA_{{KEY_SIZE}} = Fixture(
|
|
|
+ keySize: {{KEY_SIZE}},
|
|
|
+ publicDER: \"\"\"
|
|
|
+ {{PUBLIC_DER}}
|
|
|
+ \"\"\",
|
|
|
+ privateDER: \"\"\"
|
|
|
+ {{PRIVATE_DER}}
|
|
|
+ \"\"\",
|
|
|
+ messages: [
|
|
|
+ {{MESSAGE_TEMPLATES}}
|
|
|
+ ]
|
|
|
+ )
|
|
|
+ """
|
|
|
|
|
|
- private let FixtureTemplate = """
|
|
|
- static let RSA_{{KEY_SIZE}} = Fixture(
|
|
|
- keySize: {{KEY_SIZE}},
|
|
|
- publicDER: \"\"\"
|
|
|
- {{PUBLIC_DER}}
|
|
|
- \"\"\",
|
|
|
- privateDER: \"\"\"
|
|
|
- {{PRIVATE_DER}}
|
|
|
- \"\"\",
|
|
|
- rawMessage: [
|
|
|
- {{PLAINTEXT_MESSAGE}}
|
|
|
- ],
|
|
|
+ private static let MessageTemplate = """
|
|
|
+ "{{PLAINTEXT_MESSAGE}}": (
|
|
|
encryptedMessage: [
|
|
|
{{ENCRYPTED_MESSAGES}}
|
|
|
],
|
|
|
- signedMessages: [
|
|
|
+ signedMessage: [
|
|
|
{{SIGNED_MESSAGES}}
|
|
|
]
|
|
|
)
|
|
|
- """
|
|
|
-
|
|
|
- private let FixtureTemplate2 = """
|
|
|
- static let RSA_{{KEY_SIZE}} = Fixture(
|
|
|
- keySize: {{KEY_SIZE}},
|
|
|
- publicDER: \"\"\"
|
|
|
- {{PUBLIC_DER}}
|
|
|
- \"\"\",
|
|
|
- privateDER: \"\"\"
|
|
|
- {{PRIVATE_DER}}
|
|
|
- \"\"\",
|
|
|
- messages: [
|
|
|
- {{MESSAGE_TEMPLATES}}
|
|
|
- ]
|
|
|
- )
|
|
|
- """
|
|
|
-
|
|
|
- private let MessageTemplate = """
|
|
|
- "{{PLAINTEXT_MESSAGE}}": (
|
|
|
- encryptedMessage: [
|
|
|
- {{ENCRYPTED_MESSAGES}}
|
|
|
- ],
|
|
|
- signedMessage: [
|
|
|
- {{SIGNED_MESSAGES}}
|
|
|
- ]
|
|
|
- )
|
|
|
- """
|
|
|
-
|
|
|
- //encryptedMessage: [
|
|
|
-// "algid:encrypt:RSA:raw": "{{ENCRYPTED_RAW}}",
|
|
|
-// "algid:encrypt:RSA:PKCS1": "{{ENCRYPTED_PKCS1}}"
|
|
|
- //],
|
|
|
- //signedMessages: [
|
|
|
-// "algid:sign:RSA:raw" : "{{SIGNATURE_RAW}}",
|
|
|
-// "algid:sign:RSA:digest-PKCS1v15" : "{{SIGNATURE_DIGEST_PKCS1v15}}",
|
|
|
-// "algid:sign:RSA:digest-PKCS1v15:SHA1" : "{{SIGNATURE_DIGEST_PKCS1v15_SHA1}}",
|
|
|
-// "algid:sign:RSA:digest-PKCS1v15:SHA224" : "{{SIGNATURE_DIGEST_PKCS1v15_SHA224}}",
|
|
|
-// "algid:sign:RSA:digest-PKCS1v15:SHA256" : "{{SIGNATURE_DIGEST_PKCS1v15_SHA256}}",
|
|
|
-// "algid:sign:RSA:digest-PKCS1v15:SHA384" : "{{SIGNATURE_DIGEST_PKCS1v15_SHA384}}",
|
|
|
-// "algid:sign:RSA:digest-PKCS1v15:SHA512" : "{{SIGNATURE_DIGEST_PKCS1v15_SHA512}}",
|
|
|
-// "algid:sign:RSA:message-PKCS1v15:SHA1" : "{{SIGNATURE_MESSAGE_PKCS1v15_SHA1}}",
|
|
|
-// "algid:sign:RSA:message-PKCS1v15:SHA224": "{{SIGNATURE_MESSAGE_PKCS1v15_SHA224}}",
|
|
|
-// "algid:sign:RSA:message-PKCS1v15:SHA256": "{{SIGNATURE_MESSAGE_PKCS1v15_SHA256}}",
|
|
|
-// "algid:sign:RSA:message-PKCS1v15:SHA384": "{{SIGNATURE_MESSAGE_PKCS1v15_SHA384}}",
|
|
|
-// "algid:sign:RSA:message-PKCS1v15:SHA512": "{{SIGNATURE_MESSAGE_PKCS1v15_SHA512}}"
|
|
|
- //]
|
|
|
-
|
|
|
- //private func printHexData16BytesWide(_ bytes:[UInt8]) {
|
|
|
-// print(bytes.toHexString().split(intoChunksOfLength: 32).map { $0.split(intoChunksOfLength: 2).map { "0x\($0.uppercased())" }.joined(separator: ", ") }.joined(separator: ",\n"))
|
|
|
- //}
|
|
|
-
|
|
|
- private func initSecKey(rawRepresentation unsafe: Data) throws -> SecKey {
|
|
|
- let attributes: [String: Any] = [
|
|
|
- kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
|
|
|
- kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
|
|
|
- kSecAttrKeySizeInBits as String: 1024,
|
|
|
- kSecAttrIsPermanent as String: false
|
|
|
- ]
|
|
|
-
|
|
|
- var error: Unmanaged<CFError>?
|
|
|
- guard let secKey = SecKeyCreateWithData(unsafe as CFData, attributes as CFDictionary, &error) else {
|
|
|
- throw NSError(domain: "Error constructing SecKey from raw key data: \(error.debugDescription)", code: 0, userInfo: nil)
|
|
|
- }
|
|
|
+ """
|
|
|
|
|
|
- return secKey
|
|
|
- }
|
|
|
+ private func initSecKey(rawRepresentation unsafe: Data) throws -> SecKey {
|
|
|
+ let attributes: [String: Any] = [
|
|
|
+ kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
|
|
|
+ kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
|
|
|
+ kSecAttrKeySizeInBits as String: 1024,
|
|
|
+ kSecAttrIsPermanent as String: false
|
|
|
+ ]
|
|
|
|
|
|
- private func sign(message: Data, using key: SecKey) throws -> [String] {
|
|
|
- let algorithms: [SecKeyAlgorithm] = [
|
|
|
- .rsaSignatureRaw,
|
|
|
- //.rsaSignatureDigestPSSSHA1,
|
|
|
- //.rsaSignatureDigestPSSSHA224,
|
|
|
- //.rsaSignatureDigestPSSSHA256,
|
|
|
- //.rsaSignatureDigestPSSSHA384,
|
|
|
- //.rsaSignatureDigestPSSSHA512,
|
|
|
- .rsaSignatureDigestPKCS1v15Raw,
|
|
|
- .rsaSignatureDigestPKCS1v15SHA1,
|
|
|
- .rsaSignatureDigestPKCS1v15SHA224,
|
|
|
- .rsaSignatureDigestPKCS1v15SHA256,
|
|
|
- .rsaSignatureDigestPKCS1v15SHA384,
|
|
|
- .rsaSignatureDigestPKCS1v15SHA512,
|
|
|
- //.rsaSignatureMessagePSSSHA1,
|
|
|
- //.rsaSignatureMessagePSSSHA224,
|
|
|
- //.rsaSignatureMessagePSSSHA256,
|
|
|
- //.rsaSignatureMessagePSSSHA384,
|
|
|
- //.rsaSignatureMessagePSSSHA512,
|
|
|
- .rsaSignatureMessagePKCS1v15SHA1,
|
|
|
- .rsaSignatureMessagePKCS1v15SHA224,
|
|
|
- .rsaSignatureMessagePKCS1v15SHA256,
|
|
|
- .rsaSignatureMessagePKCS1v15SHA384,
|
|
|
- .rsaSignatureMessagePKCS1v15SHA512,
|
|
|
- ]
|
|
|
-
|
|
|
- var sigs: [String] = []
|
|
|
-
|
|
|
- for algo in algorithms {
|
|
|
var error: Unmanaged<CFError>?
|
|
|
-
|
|
|
- // Sign the data
|
|
|
- guard let signature = SecKeyCreateSignature(
|
|
|
- key,
|
|
|
- algo,
|
|
|
- message as CFData,
|
|
|
- &error
|
|
|
- ) as Data?
|
|
|
- else {
|
|
|
- print("\"\(algo.rawValue)\": \"nil\",")
|
|
|
- sigs.append("\"\(algo.rawValue)\": \"\"")
|
|
|
- continue
|
|
|
+ guard let secKey = SecKeyCreateWithData(unsafe as CFData, attributes as CFDictionary, &error) else {
|
|
|
+ throw NSError(domain: "Error constructing SecKey from raw key data: \(error.debugDescription)", code: 0, userInfo: nil)
|
|
|
}
|
|
|
|
|
|
- // Throw the error if we encountered one
|
|
|
- if let error = error { print("\"\(algo.rawValue)\": \"\(error.takeRetainedValue())\","); continue }
|
|
|
-
|
|
|
- // Append the signature
|
|
|
- sigs.append("\"\(algo.rawValue)\": \"\(signature.base64EncodedString())\"")
|
|
|
+ return secKey
|
|
|
}
|
|
|
|
|
|
- return sigs
|
|
|
- }
|
|
|
+ // We don't support PSS yet so we skip these variants
|
|
|
+ private func sign(message: Data, using key: SecKey) throws -> [String] {
|
|
|
+ let algorithms: [SecKeyAlgorithm] = [
|
|
|
+ .rsaSignatureRaw,
|
|
|
+ //.rsaSignatureDigestPSSSHA1,
|
|
|
+ //.rsaSignatureDigestPSSSHA224,
|
|
|
+ //.rsaSignatureDigestPSSSHA256,
|
|
|
+ //.rsaSignatureDigestPSSSHA384,
|
|
|
+ //.rsaSignatureDigestPSSSHA512,
|
|
|
+ .rsaSignatureDigestPKCS1v15Raw,
|
|
|
+ .rsaSignatureDigestPKCS1v15SHA1,
|
|
|
+ .rsaSignatureDigestPKCS1v15SHA224,
|
|
|
+ .rsaSignatureDigestPKCS1v15SHA256,
|
|
|
+ .rsaSignatureDigestPKCS1v15SHA384,
|
|
|
+ .rsaSignatureDigestPKCS1v15SHA512,
|
|
|
+ //.rsaSignatureMessagePSSSHA1,
|
|
|
+ //.rsaSignatureMessagePSSSHA224,
|
|
|
+ //.rsaSignatureMessagePSSSHA256,
|
|
|
+ //.rsaSignatureMessagePSSSHA384,
|
|
|
+ //.rsaSignatureMessagePSSSHA512,
|
|
|
+ .rsaSignatureMessagePKCS1v15SHA1,
|
|
|
+ .rsaSignatureMessagePKCS1v15SHA224,
|
|
|
+ .rsaSignatureMessagePKCS1v15SHA256,
|
|
|
+ .rsaSignatureMessagePKCS1v15SHA384,
|
|
|
+ .rsaSignatureMessagePKCS1v15SHA512,
|
|
|
+ ]
|
|
|
|
|
|
- private func encrypt(data: Data, with key: SecKey) throws -> [String] {
|
|
|
- let algorithms: [SecKeyAlgorithm] = [
|
|
|
- .rsaEncryptionRaw,
|
|
|
- .rsaEncryptionPKCS1
|
|
|
- ]
|
|
|
+ var sigs: [String] = []
|
|
|
|
|
|
- var encryptions: [String] = []
|
|
|
+ for algo in algorithms {
|
|
|
+ var error: Unmanaged<CFError>?
|
|
|
|
|
|
- for algo in algorithms {
|
|
|
- var error: Unmanaged<CFError>?
|
|
|
- guard let encryptedData = SecKeyCreateEncryptedData(key, algo, data as CFData, &error) as? Data else {
|
|
|
- print("\"\(algo.rawValue)\": \"\(error?.takeRetainedValue().localizedDescription ?? "nil")\",")
|
|
|
- encryptions.append("\"\(algo.rawValue)\": \"\"")
|
|
|
- continue
|
|
|
+ // Sign the data
|
|
|
+ guard let signature = SecKeyCreateSignature(
|
|
|
+ key,
|
|
|
+ algo,
|
|
|
+ message as CFData,
|
|
|
+ &error
|
|
|
+ ) as Data?
|
|
|
+ else {
|
|
|
+ print("\"\(algo.rawValue)\": \"nil\",")
|
|
|
+ sigs.append("\"\(algo.rawValue)\": \"\"")
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ // Throw the error if we encountered one
|
|
|
+ if let error = error { print("\"\(algo.rawValue)\": \"\(error.takeRetainedValue())\","); continue }
|
|
|
+
|
|
|
+ // Append the signature
|
|
|
+ sigs.append("\"\(algo.rawValue)\": \"\(signature.base64EncodedString())\"")
|
|
|
}
|
|
|
- encryptions.append("\"\(algo.rawValue)\": \"\(encryptedData.base64EncodedString())\"")
|
|
|
+
|
|
|
+ return sigs
|
|
|
}
|
|
|
|
|
|
- return encryptions
|
|
|
+ private func encrypt(data: Data, with key: SecKey) throws -> [String] {
|
|
|
+ let algorithms: [SecKeyAlgorithm] = [
|
|
|
+ .rsaEncryptionRaw,
|
|
|
+ .rsaEncryptionPKCS1
|
|
|
+ ]
|
|
|
+
|
|
|
+ var encryptions: [String] = []
|
|
|
+
|
|
|
+ for algo in algorithms {
|
|
|
+ var error: Unmanaged<CFError>?
|
|
|
+ guard let encryptedData = SecKeyCreateEncryptedData(key, algo, data as CFData, &error) as? Data else {
|
|
|
+ print("\"\(algo.rawValue)\": \"\(error?.takeRetainedValue().localizedDescription ?? "nil")\",")
|
|
|
+ encryptions.append("\"\(algo.rawValue)\": \"\"")
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ encryptions.append("\"\(algo.rawValue)\": \"\(encryptedData.base64EncodedString())\"")
|
|
|
+ }
|
|
|
+
|
|
|
+ return encryptions
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#endif
|