Skip to content

Commit

Permalink
Merge pull request #455 from smallstep/mariano/mackms-certs
Browse files Browse the repository at this point in the history
Add store and load certificates in mackms
  • Loading branch information
maraino authored Mar 19, 2024
2 parents 14dad1b + 69660dc commit 6daa7b9
Show file tree
Hide file tree
Showing 5 changed files with 977 additions and 13 deletions.
7 changes: 6 additions & 1 deletion internal/darwin/corefoundation/core_foundation_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ package corefoundation

/*
#cgo LDFLAGS: -framework CoreFoundation
#include <CoreFoundation/CoreFoundation.h>
*/
import "C"
Expand Down Expand Up @@ -159,6 +158,12 @@ func NewDictionary(m Dictionary) (*DictionaryRef, error) {
}, nil
}

func NewDictionaryRef(ref TypeRef) *DictionaryRef {
return &DictionaryRef{
Value: C.CFDictionaryRef(ref),
}
}

func (v *DictionaryRef) Release() { Release(v) }
func (v *DictionaryRef) TypeRef() CFTypeRef { return C.CFTypeRef(v.Value) }

Expand Down
63 changes: 59 additions & 4 deletions internal/darwin/security/security_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,18 @@ const (
nilSecKey C.SecKeyRef = 0
nilSecAccessControl C.SecAccessControlRef = 0
nilCFString C.CFStringRef = 0
nilCFData C.CFDataRef = 0
)

var ErrNotFound = errors.New("not found")
var (
ErrNotFound = errors.New("not found")
ErrAlreadyExists = errors.New("already exists")
ErrInvalidData = errors.New("invalid data")
)

var (
KSecAttrAccessControl = cf.TypeRef(C.kSecAttrAccessControl)
KSecAttrAccessGroup = cf.TypeRef(C.kSecAttrAccessGroup)
KSecAttrAccessibleWhenUnlocked = cf.TypeRef(C.kSecAttrAccessibleWhenUnlocked)
KSecAttrAccessibleWhenPasscodeSetThisDeviceOnly = cf.TypeRef(C.kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)
KSecAttrAccessibleWhenUnlockedThisDeviceOnly = cf.TypeRef(C.kSecAttrAccessibleWhenUnlockedThisDeviceOnly)
Expand All @@ -62,14 +68,23 @@ var (
KSecAttrLabel = cf.TypeRef(C.kSecAttrLabel)
KSecAttrTokenID = cf.TypeRef(C.kSecAttrTokenID)
KSecAttrTokenIDSecureEnclave = cf.TypeRef(C.kSecAttrTokenIDSecureEnclave)
KSecAttrSerialNumber = cf.TypeRef(C.kSecAttrSerialNumber)
KSecAttrSubjectKeyID = cf.TypeRef(C.kSecAttrSubjectKeyID)
KSecAttrSubject = cf.TypeRef(C.kSecAttrSubject)
KSecAttrIssuer = cf.TypeRef(C.kSecAttrIssuer)
KSecAttrSynchronizable = cf.TypeRef(C.kSecAttrSynchronizable)
KSecUseDataProtectionKeychain = cf.TypeRef(C.kSecUseDataProtectionKeychain)
KSecClass = cf.TypeRef(C.kSecClass)
KSecClassKey = cf.TypeRef(C.kSecClassKey)
KSecClassCertificate = cf.TypeRef(C.kSecClassCertificate)
KSecClassIdentity = cf.TypeRef(C.kSecClassIdentity)
KSecMatchLimit = cf.TypeRef(C.kSecMatchLimit)
KSecMatchLimitOne = cf.TypeRef(C.kSecMatchLimitOne)
KSecPublicKeyAttrs = cf.TypeRef(C.kSecPublicKeyAttrs)
KSecPrivateKeyAttrs = cf.TypeRef(C.kSecPrivateKeyAttrs)
KSecReturnRef = cf.TypeRef(C.kSecReturnRef)
KSecValueRef = cf.TypeRef(C.kSecValueRef)
KSecValueData = cf.TypeRef(C.kSecValueData)
)

type SecKeyAlgorithm = C.SecKeyAlgorithm
Expand Down Expand Up @@ -135,6 +150,19 @@ func NewSecKeyRef(ref cf.TypeRef) *SecKeyRef {
func (v *SecKeyRef) Release() { cf.Release(v) }
func (v *SecKeyRef) TypeRef() cf.CFTypeRef { return cf.CFTypeRef(v.Value) }

type SecCertificateRef struct {
Value C.SecCertificateRef
}

func NewSecCertificateRef(ref cf.TypeRef) *SecCertificateRef {
return &SecCertificateRef{
Value: C.SecCertificateRef(ref),
}
}

func (v *SecCertificateRef) Release() { cf.Release(v) }
func (v *SecCertificateRef) TypeRef() cf.CFTypeRef { return cf.CFTypeRef(v.Value) }

type SecAccessControlRef struct {
ref C.SecAccessControlRef
}
Expand All @@ -147,6 +175,11 @@ func SecItemAdd(attributes *cf.DictionaryRef, result *cf.TypeRef) error {
return goOSStatus(status)
}

func SecItemUpdate(query *cf.DictionaryRef, attributesToUpdate *cf.DictionaryRef) error {
status := C.SecItemUpdate(C.CFDictionaryRef(query.Value), C.CFDictionaryRef(attributesToUpdate.Value))
return goOSStatus(status)
}

func SecItemDelete(query *cf.DictionaryRef) error {
status := C.SecItemDelete(C.CFDictionaryRef(query.Value))
return goOSStatus(status)
Expand Down Expand Up @@ -218,6 +251,26 @@ func SecKeyCreateSignature(key *SecKeyRef, algorithm SecKeyAlgorithm, dataToSign
}, nil
}

func SecCertificateCopyData(cert *SecCertificateRef) (*cf.DataRef, error) {
data := C.SecCertificateCopyData(cert.Value)
if data == nilCFData {
return nil, ErrInvalidData
}
return &cf.DataRef{
Value: cf.CFDataRef(data),
}, nil
}

func SecCertificateCreateWithData(certData *cf.DataRef) (*SecCertificateRef, error) {
certRef := C.SecCertificateCreateWithData(C.kCFAllocatorDefault, C.CFDataRef(certData.Value))
if certRef == 0 {
return nil, ErrInvalidData
}
return &SecCertificateRef{
Value: certRef,
}, nil
}

func SecCopyErrorMessageString(status C.OSStatus) *cf.StringRef {
s := C.SecCopyErrorMessageString(status, nil)
return &cf.StringRef{
Expand Down Expand Up @@ -254,11 +307,13 @@ func (e osStatusError) Error() string {
}

func goOSStatus(status C.OSStatus) error {
if status == 0 {
switch status {
case 0:
return nil
}
if status == C.errSecItemNotFound {
case C.errSecItemNotFound: // -25300
return ErrNotFound
case C.errSecDuplicateItem: // -25299
return ErrAlreadyExists
}

var message string
Expand Down
13 changes: 12 additions & 1 deletion kms/apiv1/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ type GetPublicKeyRequest struct {
type CreateKeyRequest struct {
// Name represents the key name or label used to identify a key.
//
// Used by: awskms, cloudkms, azurekms, pkcs11, yubikey, tpmkms.
// Used by: awskms, cloudkms, azurekms, pkcs11, yubikey, tpmkms, mackms.
Name string

// SignatureAlgorithm represents the type of key to create.
Expand Down Expand Up @@ -298,3 +298,14 @@ type CreateAttestationResponse struct {
type DeleteKeyRequest struct {
Name string
}

// DeleteCertificateRequest is the parameter used in the kms.DeleteCertificate
// method.
//
// # Experimental
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a later
// release.
type DeleteCertificateRequest struct {
Name string
}
Loading

0 comments on commit 6daa7b9

Please sign in to comment.