8080 KSecClassIdentity = cf .TypeRef (C .kSecClassIdentity )
8181 KSecMatchLimit = cf .TypeRef (C .kSecMatchLimit )
8282 KSecMatchLimitOne = cf .TypeRef (C .kSecMatchLimitOne )
83+ KSecMatchLimitAll = cf .TypeRef (C .kSecMatchLimitAll )
8384 KSecPublicKeyAttrs = cf .TypeRef (C .kSecPublicKeyAttrs )
8485 KSecPrivateKeyAttrs = cf .TypeRef (C .kSecPrivateKeyAttrs )
8586 KSecReturnRef = cf .TypeRef (C .kSecReturnRef )
87+ KSecReturnAttributes = cf .TypeRef (C .kSecReturnAttributes )
8688 KSecValueRef = cf .TypeRef (C .kSecValueRef )
8789 KSecValueData = cf .TypeRef (C .kSecValueData )
8890)
@@ -138,6 +140,20 @@ const (
138140 KSecAccessControlOr = SecAccessControlCreateFlags (C .kSecAccessControlOr )
139141)
140142
143+ type SecKeychainItemRef struct {
144+ Value C.SecKeychainItemRef
145+ }
146+
147+ func NewSecKeychainItemRef (ref cf.TypeRef ) * SecKeychainItemRef {
148+ return & SecKeychainItemRef {
149+ Value : C .SecKeychainItemRef (ref ),
150+ }
151+ }
152+
153+ func (v * SecKeychainItemRef ) Release () { cf .Release (v ) }
154+ func (v * SecKeychainItemRef ) TypeRef () cf.CFTypeRef { return cf .CFTypeRef (v .Value ) }
155+ func (v * SecKeychainItemRef ) Retain () { cf .Retain (v ) }
156+
141157type SecKeyRef struct {
142158 Value C.SecKeyRef
143159}
@@ -150,6 +166,7 @@ func NewSecKeyRef(ref cf.TypeRef) *SecKeyRef {
150166
151167func (v * SecKeyRef ) Release () { cf .Release (v ) }
152168func (v * SecKeyRef ) TypeRef () cf.CFTypeRef { return cf .CFTypeRef (v .Value ) }
169+ func (v * SecKeyRef ) Retain () { cf .Retain (v ) }
153170
154171type SecCertificateRef struct {
155172 Value C.SecCertificateRef
@@ -309,6 +326,54 @@ func GetSecAttrApplicationLabel(v *cf.DictionaryRef) []byte {
309326 )
310327}
311328
329+ func GetSecAttrApplicationTag (v * cf.DictionaryRef ) string {
330+ data := C .CFDataRef (C .CFDictionaryGetValue (C .CFDictionaryRef (v .Value ), unsafe .Pointer (C .kSecAttrApplicationTag )))
331+ return string (C .GoBytes (
332+ unsafe .Pointer (C .CFDataGetBytePtr (data )),
333+ C .int (C .CFDataGetLength (data )),
334+ ))
335+ }
336+
337+ func GetSecAttrLabel (v * cf.DictionaryRef ) (label string ) {
338+ ref := C .CFStringRef (C .CFDictionaryGetValue (C .CFDictionaryRef (v .Value ), unsafe .Pointer (C .kSecAttrLabel )))
339+ if cstr := C .CFStringGetCStringPtr (ref , C .kCFStringEncodingUTF8 ); cstr != nil {
340+ label = C .GoString (cstr )
341+ }
342+ return label
343+ }
344+
345+ func GetSecAttrTokenID (v * cf.DictionaryRef ) (tokenID string ) {
346+ ref := C .CFStringRef (C .CFDictionaryGetValue (C .CFDictionaryRef (v .Value ), unsafe .Pointer (C .kSecAttrTokenID )))
347+ if cstr := C .CFStringGetCStringPtr (ref , C .kCFStringEncodingUTF8 ); cstr != nil {
348+ tokenID = C .GoString (cstr )
349+ }
350+ return tokenID
351+ }
352+
353+ func GetSecAttrAccessControl (v * cf.DictionaryRef ) * SecAccessControlRef {
354+ var keyAttributes unsafe.Pointer
355+ tokenID := GetSecAttrTokenID (v )
356+ if tokenID == "com.apple.setoken" {
357+ keyAttributes = C .CFDictionaryGetValue (C .CFDictionaryRef (v .Value ), unsafe .Pointer (C .kSecPrivateKeyAttrs ))
358+ } else {
359+ keyAttributes = C .CFDictionaryGetValue (C .CFDictionaryRef (v .Value ), unsafe .Pointer (C .kSecPublicKeyAttrs ))
360+ }
361+ if keyAttributes == nil {
362+ return nil
363+ }
364+
365+ dv := C .CFDictionaryGetValue (C .CFDictionaryRef (keyAttributes ), unsafe .Pointer (C .kSecAttrAccessControl ))
366+ if dv == nil {
367+ return nil
368+ }
369+
370+ ref := & SecAccessControlRef {
371+ ref : C .SecAccessControlRef (dv ),
372+ }
373+
374+ return ref
375+ }
376+
312377func GetSecValueData (v * cf.DictionaryRef ) []byte {
313378 data := C .CFDataRef (C .CFDictionaryGetValue (C .CFDictionaryRef (v .Value ), unsafe .Pointer (C .kSecValueData )))
314379 return C .GoBytes (
0 commit comments