77
88import Foundation
99
10- fileprivate class tmpKeyPair {
11- var label : String
12- var applicationLabel : Data
13- var publicKey : SecKey ?
14- var privateKey : SecKey ?
15-
16- var keyPair : KeyPair ? {
17- guard let pub = publicKey else { return nil }
18- guard let priv = privateKey else { return nil }
19-
20- return KeyPair ( label: label, appLabel: applicationLabel, publicKey: pub, privateKey: priv)
21- }
22-
23- init ( label l: String , applicationLabel al: Data ) {
24- label = l
25- applicationLabel = al
26- }
27- }
28-
2910class KeyPair {
11+ // Fix up legacy keychain items.
12+ static func repair( label: String ) {
13+ Keychain . repair ( attrLabel: label as CFString )
14+ }
15+
3016 /// Get all KeyPairs with the given label.
3117 static func all( label: String ) -> [ KeyPair ] {
32- let secKeys = Keychain . getSecKeys ( attrLabel: label as CFString )
33- var tmpKeyPairs : [ tmpKeyPair ] = [ ]
18+ let secKeys = Keychain . getPrivateSecKeys ( attrLabel: label as CFString )
3419 var keyPairs : [ KeyPair ] = [ ]
3520
36- secKeys. forEach { secKey in
37- guard let appLabel: CFData = Keychain . getSecKeyAttr ( key: secKey, attr: kSecAttrApplicationLabel) else { return }
38-
39- let applicationLabel = appLabel as Data
40- var tmpKP : tmpKeyPair
41-
42- if let kp = tmpKeyPairs. first ( where: { $0. applicationLabel == applicationLabel } ) {
43- tmpKP = kp
44- } else {
45- tmpKP = tmpKeyPair. init ( label: label, applicationLabel: applicationLabel)
46- tmpKeyPairs. append ( tmpKP)
47- }
48-
49- guard let klass: CFString = Keychain . getSecKeyAttr ( key: secKey, attr: kSecAttrKeyClass) else { return }
50-
51- if klass == kSecAttrKeyClassPublic {
52- tmpKP. publicKey = secKey
53- } else {
54- tmpKP. privateKey = secKey
55- }
56- }
57-
58- tmpKeyPairs. forEach { tmpKP in
59- guard let kp = tmpKP. keyPair else { return }
60-
21+ secKeys. forEach { priv in
22+ guard let pub = SecKeyCopyPublicKey ( priv) else { return }
23+ guard let appLabel: CFData = Keychain . getSecKeyAttr ( key: priv, attr: kSecAttrApplicationLabel) else { return }
24+
25+ let kp = KeyPair ( label: label, appLabel: appLabel as Data , publicKey: pub, privateKey: priv)
26+
6127 keyPairs. append ( kp)
6228 }
6329
6430 return keyPairs
6531 }
6632
67- // The number of key pairs ( keys/2) in the keychain.
33+ // The number of private keys in the keychain.
6834 static func count( label: String ) -> Int ? {
69- guard let c = Keychain . count ( attrLabel: label as CFString ) else { return nil }
70-
71- if c % 2 != 0 {
72- print ( " Uneven number of keys in the keychain. " )
73- return nil
74- }
75-
76- return c / 2
35+ return Keychain . count ( attrLabel: label as CFString )
7736 }
7837
7938 // Delete all keys with the given label from the keychain.
@@ -97,19 +56,25 @@ class KeyPair {
9756
9857 set {
9958 let value = ( newValue ?? Data ( ) )
100- Keychain . setSecItemAttr ( attrAppLabel: applicationLabel as CFData , name: kSecAttrApplicationTag, value: value as CFData )
59+ _ = Keychain . setSecItemAttr ( attrAppLabel: applicationLabel as CFData , name: kSecAttrApplicationTag, value: value as CFData )
10160 }
10261 }
10362
10463 var publicKeyData : Data ? {
105- return Keychain . getSecItemData ( attrAppLabel: applicationLabel)
64+ return Keychain . exportSecKey ( publicKey)
65+ }
66+
67+ var inSEP : Bool {
68+ let tokenID : String = Keychain . getSecItemAttr ( attrAppLabel: applicationLabel as CFData , name: kSecAttrTokenID) ?? " nope "
69+
70+ return tokenID == kSecAttrTokenIDSecureEnclave as String
10671 }
10772
10873 // Generate a new key pair.
109- init ? ( label l: String ) {
74+ init ? ( label l: String , inSEP sep : Bool ) {
11075 label = l
11176
112- guard let ( pub, priv) = Keychain . generateKeyPair ( attrLabel: label as CFString ) else { return nil }
77+ guard let ( pub, priv) = Keychain . generateKeyPair ( attrLabel: label as CFString , inSEP : sep ) else { return nil }
11378 publicKey = pub
11479 privateKey = priv
11580
@@ -118,17 +83,17 @@ class KeyPair {
11883 }
11984
12085 // Find a key pair with the given label and application label.
121- init ? ( label l: String , appLabel al: Data ) {
86+ init ? ( label l: String , appLabel al: Data , signPrompt sp : String ) {
12287 label = l
12388 applicationLabel = al
12489
125- // Lookup public key.
126- guard let pub = Keychain . getSecKey ( attrAppLabel: applicationLabel as CFData , keyClass: kSecAttrKeyClassPublic) else { return nil }
127- publicKey = pub
128-
12990 // Lookup private key.
130- guard let priv = Keychain . getSecKey ( attrAppLabel: applicationLabel as CFData , keyClass : kSecAttrKeyClassPrivate ) else { return nil }
91+ guard let priv = Keychain . getPrivateSecKey ( attrAppLabel: applicationLabel as CFData , signPrompt : sp as CFString ) else { return nil }
13192 privateKey = priv
93+
94+ // Generate public key from private key
95+ guard let pub = SecKeyCopyPublicKey ( priv) else { return nil }
96+ publicKey = pub
13297 }
13398
13499 // Initialize a key pair with all the necessary data.
0 commit comments