Skip to content

Commit 3a8464f

Browse files
authored
Merge pull request #630 from smallstep/mariano/mackms-conversions
Fix cgo data conversion for bytes and strings
2 parents 96300f0 + 9882b2b commit 3a8464f

File tree

1 file changed

+43
-25
lines changed

1 file changed

+43
-25
lines changed

internal/darwin/security/security_darwin.go

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -320,34 +320,22 @@ func SecCopyErrorMessageString(status C.OSStatus) *cf.StringRef {
320320

321321
func GetSecAttrApplicationLabel(v *cf.DictionaryRef) []byte {
322322
data := C.CFDataRef(C.CFDictionaryGetValue(C.CFDictionaryRef(v.Value), unsafe.Pointer(C.kSecAttrApplicationLabel)))
323-
return C.GoBytes(
324-
unsafe.Pointer(C.CFDataGetBytePtr(data)),
325-
C.int(C.CFDataGetLength(data)),
326-
)
323+
return goBytes(data)
327324
}
328325

329326
func GetSecAttrApplicationTag(v *cf.DictionaryRef) string {
330327
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-
))
328+
return string(goBytes(data))
335329
}
336330

337-
func GetSecAttrLabel(v *cf.DictionaryRef) (label string) {
331+
func GetSecAttrLabel(v *cf.DictionaryRef) string {
338332
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
333+
return goString(ref)
343334
}
344335

345-
func GetSecAttrTokenID(v *cf.DictionaryRef) (tokenID string) {
336+
func GetSecAttrTokenID(v *cf.DictionaryRef) string {
346337
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
338+
return goString(ref)
351339
}
352340

353341
func GetSecAttrAccessControl(v *cf.DictionaryRef) *SecAccessControlRef {
@@ -376,10 +364,7 @@ func GetSecAttrAccessControl(v *cf.DictionaryRef) *SecAccessControlRef {
376364

377365
func GetSecValueData(v *cf.DictionaryRef) []byte {
378366
data := C.CFDataRef(C.CFDictionaryGetValue(C.CFDictionaryRef(v.Value), unsafe.Pointer(C.kSecValueData)))
379-
return C.GoBytes(
380-
unsafe.Pointer(C.CFDataGetBytePtr(data)),
381-
C.int(C.CFDataGetLength(data)),
382-
)
367+
return goBytes(data)
383368
}
384369

385370
type osStatusError struct {
@@ -406,9 +391,7 @@ func goOSStatus(status C.OSStatus) error {
406391

407392
var message string
408393
if ref := SecCopyErrorMessageString(status); ref.Value != 0 {
409-
if cstr := C.CFStringGetCStringPtr(C.CFStringRef(ref.Value), C.kCFStringEncodingUTF8); cstr != nil {
410-
message = C.GoString(cstr)
411-
}
394+
message = goString(C.CFStringRef(ref.Value))
412395
defer ref.Release()
413396
}
414397
return osStatusError{
@@ -417,6 +400,41 @@ func goOSStatus(status C.OSStatus) error {
417400
}
418401
}
419402

403+
func goBytes(data C.CFDataRef) []byte {
404+
if data == 0 {
405+
return nil
406+
}
407+
return C.GoBytes(
408+
unsafe.Pointer(C.CFDataGetBytePtr(data)),
409+
C.int(C.CFDataGetLength(data)),
410+
)
411+
}
412+
413+
func goString(ref C.CFStringRef) string {
414+
if ref == 0 {
415+
return ""
416+
}
417+
418+
// CFStringGetCStringPtr either returns the requested pointer immediately,
419+
// with no memory allocations and no copying, in constant time, or returns
420+
// NULL.
421+
if cstr := C.CFStringGetCStringPtr(ref, C.kCFStringEncodingUTF8); cstr != nil {
422+
return C.GoString(cstr)
423+
}
424+
425+
// The documentation recommends using CFStringGetCString if the previous one
426+
// fails.
427+
length := C.CFStringGetLength(ref)
428+
buf := (*C.char)(C.malloc(C.size_t(length) + 1))
429+
defer C.free(unsafe.Pointer(buf))
430+
431+
if C.CFStringGetCString(ref, buf, length+1, C.kCFStringEncodingUTF8) == 0 {
432+
return ""
433+
}
434+
435+
return C.GoString(buf)
436+
}
437+
420438
type cfError struct {
421439
code int
422440
message string

0 commit comments

Comments
 (0)