Skip to content

Commit

Permalink
Key generation bug fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Consuelita committed Mar 6, 2019
1 parent c59522f commit a031c46
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 59 deletions.
2 changes: 1 addition & 1 deletion Sources/ReplicantSwift/Polish/PolishClientModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class PolishClientModel
return nil
}

guard let newKeyPair = controller.generateKeyPair(withAttributes: controller.generateKeyAttributesDictionary())
guard let newKeyPair = controller.generateKeyPair(withAttributes: controller.generateClientKeyAttributesDictionary())
else
{
return nil
Expand Down
48 changes: 5 additions & 43 deletions Sources/ReplicantSwift/Polish/PolishController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,14 @@ public struct PolishController
{
// Generate private key
var error: Unmanaged<CFError>?
//let attributes = self.generateKeyAttributesDictionary()


guard let privateKey = SecKeyCreateRandomKey(attributes, &error)
else
{
logQueue.enqueue("\nUnable to generate the client private key: \(error!.takeRetainedValue() as Error)\n")
return nil
}

return privateKey
}

Expand All @@ -75,21 +74,6 @@ public struct PolishController
return publicKey
}

func generatePublicKey(usingPrivateKeyData privateKeyData: Data) -> SecKey?
{
var error: Unmanaged<CFError>?
let attributes = [kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyClass: kSecAttrKeyClassPrivate]

guard let publicKey = SecKeyCreateWithData(privateKeyData as CFData, attributes as CFDictionary, &error)
else
{
logQueue.enqueue("\nUnable to generate a public key from the provided private key.\(String(describing: error))\n")
return nil
}

return publicKey
}

func generateKeyPair(withAttributes attributes: CFDictionary) -> (privateKey: SecKey, publicKey: SecKey)?
{
guard let privateKey = generatePrivateKey(withAttributes: attributes)
Expand All @@ -109,7 +93,6 @@ public struct PolishController

func fetchOrCreateServerKeyPair() ->(privateKey: SecKey, publicKey: SecKey)?
{

// Do we already have a key?
var maybeItem: CFTypeRef?
let status = SecItemCopyMatching(generateServerKeySearchQuery(), &maybeItem)
Expand All @@ -130,31 +113,10 @@ public struct PolishController

let privateKey = item as! SecKey

// This is weirdly broken so we have to use data instead
// guard let publicKey = generatePublicKey(usingPrivateKey: privateKey)
// else
// {
// logQueue.enqueue("Unable to generate a public key uding the provided private key.")
// return nil
// }

var error: Unmanaged<CFError>?
var newKeyData: Data

// Encode key as data
guard let keyData = SecKeyCopyExternalRepresentation(privateKey, &error) as Data?
else
{
logQueue.enqueue("\nUnable to generate public key external representation: \(error!.takeRetainedValue() as Error)\n")
return nil
}

newKeyData = keyData

guard let publicKey = generatePublicKey(usingPrivateKeyData: newKeyData)
guard let publicKey = generatePublicKey(usingPrivateKey: privateKey)
else
{
logQueue.enqueue("Unable to generate a public key using the provided private key data.")
logQueue.enqueue("Unable to generate a public key using the provided private key.")
return nil
}

Expand Down Expand Up @@ -186,7 +148,7 @@ public struct PolishController

}

func generateKeyAttributesDictionary() -> CFDictionary
func generateClientKeyAttributesDictionary() -> CFDictionary
{
//FIXME: Secure Enclave
//let access = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleAlwaysThisDeviceOnly, .privateKeyUsage, nil)!
Expand Down
42 changes: 27 additions & 15 deletions Tests/ReplicantSwiftTests/ReplicantSwiftTests.swift
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
import XCTest
import Foundation
import Datable
import SwiftQueue

@testable import ReplicantSwift

final class ReplicantSwiftTests: XCTestCase
{
var polishClientModel: PolishClientModel!
let attributes: [String: Any] =
[kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeySizeInBits as String: 256,
kSecPrivateKeyAttrs as String: [kSecAttrIsPermanent as String: true,
kSecAttrApplicationTag as String: "com.example.keys.mykey".data(using: .utf8)!]
]

let logQueue = Queue<String>()
var polishController: PolishController!
var attributes: CFDictionary!
// let attributes: [String: Any] =
// [kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
// kSecAttrKeySizeInBits as String: 256,
// kSecPrivateKeyAttrs as String: [kSecAttrIsPermanent as String: true,
// kSecAttrApplicationTag as String: "com.example.keys.mykey".data(using: .utf8)!]
// ]

override func setUp()
{
super.setUp()

polishController = PolishController(logQueue: logQueue)
attributes = polishController.generateClientKeyAttributesDictionary()

// Generate private key
var error: Unmanaged<CFError>?



guard let bobPrivate = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else
{
print(error!)
Expand All @@ -38,7 +48,7 @@ final class ReplicantSwiftTests: XCTestCase
return
}

guard let clientModel = PolishClientModel(serverPublicKeyData: keyData)
guard let clientModel = PolishClientModel(serverPublicKeyData: keyData, logQueue: logQueue)
else
{
return
Expand All @@ -51,7 +61,7 @@ final class ReplicantSwiftTests: XCTestCase

func testFetchOrCreateServerKey()
{
let controller = PolishController()
let controller = PolishController(logQueue: logQueue)

// Ask for the keypair and accept either the existing key or a new one
guard let _ = controller.fetchOrCreateServerKeyPair()
Expand Down Expand Up @@ -108,6 +118,7 @@ final class ReplicantSwiftTests: XCTestCase

func testGeneratePrivateUsingPublic()
{
let attributes = polishController.generateClientKeyAttributesDictionary()
guard let privateKey = polishClientModel.controller.generatePrivateKey(withAttributes: attributes as CFDictionary)
else
{
Expand Down Expand Up @@ -205,15 +216,16 @@ final class ReplicantSwiftTests: XCTestCase
var error: Unmanaged<CFError>?

// Generate private key
guard let bobPrivate = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else
guard let bobPrivate = SecKeyCreateRandomKey(attributes, &error) else
{
print(error!)
XCTFail()
return
}

// Generate public key
let bobPublic = SecKeyCopyPublicKey(bobPrivate)!
let bobPublic = polishController.generatePublicKey(usingPrivateKey: bobPrivate)!
//SecKeyCopyPublicKey(bobPrivate)!

let plainText = Data(repeating: 0x0A, count: 4096)

Expand All @@ -238,7 +250,7 @@ final class ReplicantSwiftTests: XCTestCase
}

// Generate public key
let bobPublic = SecKeyCopyPublicKey(bobPrivate)!
let bobPublic = polishController.generatePublicKey(usingPrivateKey: bobPrivate)!

let plainText = Data(repeating: 0x0A, count: 4096)
guard let cipherText = polishClientModel.controller.encrypt(payload: plainText, usingPublicKey: bobPublic)
Expand All @@ -248,15 +260,15 @@ final class ReplicantSwiftTests: XCTestCase
return
}

guard let maybeDecoded = polishClientModel.controller.decrypt(payload: cipherText, usingPrivateKey: bobPrivate)
guard let maybeDecrypted = polishClientModel.controller.decrypt(payload: cipherText, usingPrivateKey: bobPrivate)
else
{
XCTFail()
return
}

XCTAssertNotNil(maybeDecoded)
XCTAssertEqual(maybeDecoded, plainText)
XCTAssertNotNil(maybeDecrypted)
XCTAssertEqual(maybeDecrypted.bytes, plainText.bytes)
}


Expand Down

0 comments on commit a031c46

Please sign in to comment.