Skip to content

Commit

Permalink
Extract se fact from key properties
Browse files Browse the repository at this point in the history
  • Loading branch information
hslatman committed Jul 25, 2024
1 parent a870eb8 commit 9c3c6e2
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 30 deletions.
20 changes: 1 addition & 19 deletions internal/darwin/corefoundation/core_foundation_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,20 +173,6 @@ func NewDictionaryRef(ref TypeRef) *DictionaryRef {
func (v *DictionaryRef) Release() { Release(v) }
func (v *DictionaryRef) TypeRef() CFTypeRef { return C.CFTypeRef(v.Value) }

func (v *DictionaryRef) XML() []byte {
if v == nil {
return nil
}

ref := C.CFPropertyListCreateData(AllocatorDefault, v.TypeRef(), C.kCFPropertyListXMLFormat_v1_0, 0, nil)

// TODO: release?
return C.GoBytes(
unsafe.Pointer(C.CFDataGetBytePtr(ref)),
C.int(C.CFDataGetLength(ref)),
)
}

type ArrayRef struct {
Value C.CFArrayRef
}
Expand All @@ -201,11 +187,7 @@ func (v *ArrayRef) Release() { Release(v) }
func (v *ArrayRef) TypeRef() CFTypeRef { return C.CFTypeRef(v.Value) }

func (v *ArrayRef) Len() int {
arrayCount := C.CFArrayGetCount(v.Value)

// TODO: release array count?

return int(arrayCount)
return int(C.CFArrayGetCount(v.Value))
}

func (v *ArrayRef) Get(index int) TypeRef {
Expand Down
35 changes: 33 additions & 2 deletions internal/darwin/security/security_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,15 +334,46 @@ func GetSecAttrApplicationTag(v *cf.DictionaryRef) string {
))
}

func GetSecAttrLabel(v *cf.DictionaryRef) string {
func GetSecAttrLabel(v *cf.DictionaryRef) (label string) {
ref := C.CFStringRef(C.CFDictionaryGetValue(C.CFDictionaryRef(v.Value), unsafe.Pointer(C.kSecAttrLabel)))
label := ""
if cstr := C.CFStringGetCStringPtr(ref, C.kCFStringEncodingUTF8); cstr != nil {
label = C.GoString(cstr)
}
return label
}

func GetSecAttrTokenID(v *cf.DictionaryRef) (tokenID string) {
ref := C.CFStringRef(C.CFDictionaryGetValue(C.CFDictionaryRef(v.Value), unsafe.Pointer(C.kSecAttrTokenID)))
if cstr := C.CFStringGetCStringPtr(ref, C.kCFStringEncodingUTF8); cstr != nil {
tokenID = C.GoString(cstr)
}
return tokenID
}

func GetSecAttrAccessControl(v *cf.DictionaryRef) *SecAccessControlRef {
var keyAttributes unsafe.Pointer
tokenID := GetSecAttrTokenID(v)
if tokenID == "com.apple.setoken" {
keyAttributes = C.CFDictionaryGetValue(C.CFDictionaryRef(v.Value), unsafe.Pointer(C.kSecPrivateKeyAttrs))
} else {
keyAttributes = C.CFDictionaryGetValue(C.CFDictionaryRef(v.Value), unsafe.Pointer(C.kSecPublicKeyAttrs))
}
if keyAttributes == nil {
return nil
}

dv := C.CFDictionaryGetValue(C.CFDictionaryRef(keyAttributes), unsafe.Pointer(C.kSecAttrAccessControl))
if dv == nil {
return nil
}

ref := &SecAccessControlRef{
ref: C.SecAccessControlRef(dv),
}

return ref
}

func GetSecValueData(v *cf.DictionaryRef) []byte {
data := C.CFDataRef(C.CFDictionaryGetValue(C.CFDictionaryRef(v.Value), unsafe.Pointer(C.kSecValueData)))
return C.GoBytes(
Expand Down
2 changes: 1 addition & 1 deletion kms/apiv1/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type KeyManager interface {
}

// SearchableKeyManager is an optional interface for KMS implementations
// that support searching for keys based on crtain attributes.
// that support searching for keys based on certain attributes.
//
// # Experimental
//
Expand Down
10 changes: 2 additions & 8 deletions kms/mackms/mackms.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ func (k *MacKMS) SearchKeys(req *apiv1.SearchKeysRequest) (*apiv1.SearchKeysResp

u, err := parseSearchURI(req.Query)
if err != nil {
return nil, fmt.Errorf("mackms CreateKey failed: %w", err)
return nil, fmt.Errorf("failed parsing query: %w", err)
}

keys, err := getPrivateKeys(u)
Expand All @@ -575,21 +575,15 @@ func (k *MacKMS) SearchKeys(req *apiv1.SearchKeysRequest) (*apiv1.SearchKeysResp
d := cf.NewDictionaryRef(cf.TypeRef(key.TypeRef()))
defer d.Release()

fmt.Println(string(d.XML())) // TODO: remove debug

name := uri.New(Scheme, url.Values{
"hash": []string{hex.EncodeToString(security.GetSecAttrApplicationLabel(d))},
"label": []string{security.GetSecAttrLabel(d)},
"tag": []string{security.GetSecAttrApplicationTag(d)},
})

// TODO: extract those from the attributes too
if u.useSecureEnclave {
if tokenID := security.GetSecAttrTokenID(d); tokenID == "com.apple.setoken" {
name.Values.Set("se", "true")
}
if u.useBiometrics {
name.Values.Set("bio", "true")
}

// obtain the public key by requesting it, as the current
// representation of the key are just the attributes.
Expand Down

0 comments on commit 9c3c6e2

Please sign in to comment.