This commit is contained in:
Ben Toews 2017-08-22 10:10:15 -06:00
Родитель e6121ad799
Коммит 5babfb7eb7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E9C423BE17EFEE70
5 изменённых файлов: 58 добавлений и 34 удалений

Просмотреть файл

@ -10,6 +10,7 @@ import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Fix up legacy keychain items.
U2FRegistration.repair()
if CLI(CommandLine.arguments).run() {
@ -27,7 +28,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
func applicationDidBecomeActive(_ notification: Notification) {
// Chrome gives ignores our U2F responses if it isn't active when we send them.
// Chrome ignores our U2F responses if it isn't active when we send them.
// This hack should give focus back to Chrome immediately after the user interacts
// with our notification.
NSApplication.shared().hide(nil)

Просмотреть файл

@ -43,6 +43,12 @@ class CLI {
}
private func listRegistrations() {
let registrations = U2FRegistration.all
if registrations.count == 0 {
print("No registrations to list")
return
}
print("The following is a list of U2F registrations stored in your keychain. Each key contains several fields:")
print(" - Key handle: This is the key handle that we registered with a website. For Soft U2F, the key handle is simply a hash of the public key.")
print(" - Application parameter: This is the sha256 of the app-id of the site.")
@ -51,7 +57,7 @@ class CLI {
print(" — In SEP: Whether this registration's private key is stored in the SEP.")
print("")
U2FRegistration.all.forEach { reg in
registrations.forEach { reg in
print("Key handle: ", reg.keyHandle.base64EncodedString())
print("Application parameter: ", reg.applicationParameter.base64EncodedString())

Просмотреть файл

@ -8,6 +8,7 @@
import Foundation
class KeyPair {
// Fix up legacy keychain items.
static func repair(label: String) {
Keychain.repair(attrLabel: label as CFString)
}

Просмотреть файл

@ -155,6 +155,10 @@ class Keychain {
var optionalOpaqueResult: CFTypeRef? = nil
let err = SecItemCopyMatching(query, &optionalOpaqueResult)
if err == errSecItemNotFound {
return []
}
if err != errSecSuccess {
print("Error from keychain: \(err)")
return []
@ -295,8 +299,15 @@ class Keychain {
return ret
}
// Previously, we had been storing both the public and private key in the keychain and
// using the application tag attribute on the public key for smuggling the U2F
// registration's counter. When generating a private key in the SEP, the public key
// isn't persisted in the keychain. From now on, we're using the application tag
// attribute on the private key for storing the counter and just deriving the public
// key from the private key whenever we need it. This function makes legacy keys
// consistent by deleting the public key from the keychain and copying its application
// tag into the private key.
static func repair(attrLabel: CFString) {
// Lookup public keys
let query = makeCFDictionary(
(kSecClass, kSecClassKey),
(kSecAttrKeyType, kSecAttrKeyTypeEC),
@ -309,6 +320,10 @@ class Keychain {
var optionalOpaqueResult: CFTypeRef? = nil
let err = SecItemCopyMatching(query, &optionalOpaqueResult)
if err == errSecItemNotFound {
return
}
if err != errSecSuccess {
print("Error from keychain: \(err)")
return

Просмотреть файл

@ -32,6 +32,7 @@ class U2FRegistration {
return KeyPair.count(label: namespace)
}
// Fix up legacy keychain items.
static func repair() {
KeyPair.repair(label: namespace)
}