2 * Copyright (c) 2002-2004,2011-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <Security/SecBase.h>
25 #include <Security/SecAccess.h>
26 #include <Security/SecAccessPriv.h>
27 #include <Security/SecTrustedApplication.h>
28 #include <Security/SecTrustedApplicationPriv.h>
29 #include <security_keychain/Access.h>
30 #include <security_utilities/casts.h>
31 #include <utilities/SecCFRelease.h>
32 #include "SecBridge.h"
33 #include <sys/param.h>
35 #include <utilities/SecCFWrappers.h>
37 #include "LegacyAPICounts.h"
39 /* No restrictions. Permission to perform all operations on
40 the resource or available to an ACL owner. */
43 const CFStringRef kSecACLAuthorizationAny
= CFSTR("ACLAuthorizationAny");
45 const CFStringRef kSecACLAuthorizationLogin
= CFSTR("ACLAuthorizationLogin");
46 const CFStringRef kSecACLAuthorizationGenKey
= CFSTR("ACLAuthorizationGenKey");
47 const CFStringRef kSecACLAuthorizationDelete
= CFSTR("ACLAuthorizationDelete");
48 const CFStringRef kSecACLAuthorizationExportWrapped
= CFSTR("ACLAuthorizationExportWrapped");
49 const CFStringRef kSecACLAuthorizationExportClear
= CFSTR("ACLAuthorizationExportClear");
50 const CFStringRef kSecACLAuthorizationImportWrapped
= CFSTR("ACLAuthorizationImportWrapped");
51 const CFStringRef kSecACLAuthorizationImportClear
= CFSTR("ACLAuthorizationImportClear");
52 const CFStringRef kSecACLAuthorizationSign
= CFSTR("ACLAuthorizationSign");
53 const CFStringRef kSecACLAuthorizationEncrypt
= CFSTR("ACLAuthorizationEncrypt");
54 const CFStringRef kSecACLAuthorizationDecrypt
= CFSTR("ACLAuthorizationDecrypt");
55 const CFStringRef kSecACLAuthorizationMAC
= CFSTR("ACLAuthorizationMAC");
56 const CFStringRef kSecACLAuthorizationDerive
= CFSTR("ACLAuthorizationDerive");
58 /* Defined authorization tag values for Keychain */
62 const CFStringRef kSecACLAuthorizationKeychainCreate
= CFSTR("ACLAuthorizationKeychainCreate");
63 const CFStringRef kSecACLAuthorizationKeychainDelete
= CFSTR("ACLAuthorizationKeychainDelete");
64 const CFStringRef kSecACLAuthorizationKeychainItemRead
= CFSTR("ACLAuthorizationKeychainItemRead");
65 const CFStringRef kSecACLAuthorizationKeychainItemInsert
= CFSTR("ACLAuthorizationKeychainItemInsert");
66 const CFStringRef kSecACLAuthorizationKeychainItemModify
= CFSTR("ACLAuthorizationKeychainItemModify");
67 const CFStringRef kSecACLAuthorizationKeychainItemDelete
= CFSTR("ACLAuthorizationKeychainItemDelete");
69 const CFStringRef kSecACLAuthorizationChangeACL
= CFSTR("ACLAuthorizationChangeACL");
70 const CFStringRef kSecACLAuthorizationChangeOwner
= CFSTR("ACLAuthorizationChangeOwner");
71 const CFStringRef kSecACLAuthorizationPartitionID
= CFSTR("ACLAuthorizationPartitionID");
72 const CFStringRef kSecACLAuthorizationIntegrity
= CFSTR("ACLAuthorizationIntegrity");
75 static CFArrayRef
copyTrustedAppListFromBundle(CFStringRef bundlePath
, CFStringRef trustedAppListFileName
);
77 static CFStringRef gKeys
[] =
79 kSecACLAuthorizationAny
,
80 kSecACLAuthorizationLogin
,
81 kSecACLAuthorizationGenKey
,
82 kSecACLAuthorizationDelete
,
83 kSecACLAuthorizationExportWrapped
,
84 kSecACLAuthorizationExportClear
,
85 kSecACLAuthorizationImportWrapped
,
86 kSecACLAuthorizationImportClear
,
87 kSecACLAuthorizationSign
,
88 kSecACLAuthorizationEncrypt
,
89 kSecACLAuthorizationDecrypt
,
90 kSecACLAuthorizationMAC
,
91 kSecACLAuthorizationDerive
,
93 /* Defined authorization tag values for Keychain */
94 kSecACLAuthorizationKeychainCreate
,
95 kSecACLAuthorizationKeychainDelete
,
96 kSecACLAuthorizationKeychainItemRead
,
97 kSecACLAuthorizationKeychainItemInsert
,
98 kSecACLAuthorizationKeychainItemModify
,
99 kSecACLAuthorizationKeychainItemDelete
,
101 kSecACLAuthorizationChangeACL
,
102 kSecACLAuthorizationChangeOwner
,
103 kSecACLAuthorizationPartitionID
,
104 kSecACLAuthorizationIntegrity
107 static sint32 gValues
[] =
109 CSSM_ACL_AUTHORIZATION_ANY
,
110 CSSM_ACL_AUTHORIZATION_LOGIN
,
111 CSSM_ACL_AUTHORIZATION_GENKEY
,
112 CSSM_ACL_AUTHORIZATION_DELETE
,
113 CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED
,
114 CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR
,
115 CSSM_ACL_AUTHORIZATION_IMPORT_WRAPPED
,
116 CSSM_ACL_AUTHORIZATION_IMPORT_CLEAR
,
117 CSSM_ACL_AUTHORIZATION_SIGN
,
118 CSSM_ACL_AUTHORIZATION_ENCRYPT
,
119 CSSM_ACL_AUTHORIZATION_DECRYPT
,
120 CSSM_ACL_AUTHORIZATION_MAC
,
121 CSSM_ACL_AUTHORIZATION_DERIVE
,
122 CSSM_ACL_AUTHORIZATION_DBS_CREATE
,
123 CSSM_ACL_AUTHORIZATION_DBS_DELETE
,
124 CSSM_ACL_AUTHORIZATION_DB_READ
,
125 CSSM_ACL_AUTHORIZATION_DB_INSERT
,
126 CSSM_ACL_AUTHORIZATION_DB_MODIFY
,
127 CSSM_ACL_AUTHORIZATION_DB_DELETE
,
128 CSSM_ACL_AUTHORIZATION_CHANGE_ACL
,
129 CSSM_ACL_AUTHORIZATION_CHANGE_OWNER
,
130 CSSM_ACL_AUTHORIZATION_PARTITION_ID
,
131 CSSM_ACL_AUTHORIZATION_INTEGRITY
135 CFDictionaryRef
CreateStringToNumDictionary()
137 int numItems
= (sizeof(gValues
) / sizeof(sint32
));
138 CFMutableDictionaryRef tempDict
= CFDictionaryCreateMutable(kCFAllocatorDefault
, numItems
, &kCFCopyStringDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
140 for (int iCnt
= 0; iCnt
< numItems
; iCnt
++)
142 sint32 aNumber
= gValues
[iCnt
];
143 CFNumberRef aNum
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
, &aNumber
);
145 CFStringRef aString
= gKeys
[iCnt
];
146 CFDictionaryAddValue(tempDict
, aString
, aNum
);
150 CFDictionaryRef result
= CFDictionaryCreateCopy(kCFAllocatorDefault
, tempDict
);
157 CFDictionaryRef
CreateNumToStringDictionary()
159 int numItems
= (sizeof(gValues
) / sizeof(sint32
));
161 CFMutableDictionaryRef tempDict
= CFDictionaryCreateMutable(kCFAllocatorDefault
, numItems
, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
163 for (int iCnt
= 0; iCnt
< numItems
; iCnt
++)
165 sint32 aNumber
= gValues
[iCnt
];
166 CFNumberRef aNum
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
, &aNumber
);
168 CFStringRef aString
= gKeys
[iCnt
];
169 CFDictionaryAddValue(tempDict
, aNum
, aString
);
174 CFDictionaryRef result
= CFDictionaryCreateCopy(kCFAllocatorDefault
, tempDict
);
180 /* TODO: This should be in some header */
181 sint32
GetACLAuthorizationTagFromString(CFStringRef aclStr
);
182 sint32
GetACLAuthorizationTagFromString(CFStringRef aclStr
)
187 CFShow(CFSTR("GetACLAuthorizationTagFromString aclStr is NULL"));
192 static CFDictionaryRef gACLMapping
= NULL
;
194 if (NULL
== gACLMapping
)
196 gACLMapping
= CreateStringToNumDictionary();
200 CFNumberRef valueResult
= (CFNumberRef
)CFDictionaryGetValue(gACLMapping
, aclStr
);
201 if (NULL
!= valueResult
)
203 if (!CFNumberGetValue(valueResult
, kCFNumberSInt32Type
, &result
))
218 /* TODO: This should be in some header */
219 CFStringRef
GetAuthStringFromACLAuthorizationTag(sint32 tag
);
220 CFStringRef
GetAuthStringFromACLAuthorizationTag(sint32 tag
)
222 static CFDictionaryRef gTagMapping
= NULL
;
223 CFNumberRef aNum
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
, &tag
);
225 if (NULL
== gTagMapping
)
227 gTagMapping
= CreateNumToStringDictionary();
230 CFStringRef result
= (CFStringRef
)kSecACLAuthorizationAny
;
232 if (NULL
!= gTagMapping
&& CFDictionaryContainsKey(gTagMapping
, aNum
))
234 result
= (CFStringRef
)CFDictionaryGetValue(gTagMapping
, aNum
);
243 CFTypeID
SecAccessGetTypeID(void)
246 return gTypes().Access
.typeID
;
247 END_SECAPI1(_kCFRuntimeNotATypeID
)
255 * Create a new SecAccessRef that is set to the default configuration
256 * of a (newly created) security object.
258 OSStatus
SecAccessCreate(CFStringRef descriptor
, CFArrayRef trustedList
, SecAccessRef
*accessRef
)
261 Required(descriptor
);
262 SecPointer
<Access
> access
;
264 CFIndex length
= CFArrayGetCount(trustedList
);
265 ACL::ApplicationList trusted
;
266 for (CFIndex n
= 0; n
< length
; n
++)
267 trusted
.push_back(TrustedApplication::required(
268 SecTrustedApplicationRef(CFArrayGetValueAtIndex(trustedList
, n
))));
269 access
= new Access(cfString(descriptor
), trusted
);
271 access
= new Access(cfString(descriptor
));
273 Required(accessRef
) = access
->handle();
280 OSStatus
SecAccessCreateFromOwnerAndACL(const CSSM_ACL_OWNER_PROTOTYPE
*owner
,
281 uint32 aclCount
, const CSSM_ACL_ENTRY_INFO
*acls
,
282 SecAccessRef
*accessRef
)
285 Required(accessRef
); // preflight
286 SecPointer
<Access
> access
= new Access(Required(owner
), aclCount
, &Required(acls
));
287 *accessRef
= access
->handle();
291 SecAccessRef
SecAccessCreateWithOwnerAndACL(uid_t userId
, gid_t groupId
, SecAccessOwnerType ownerType
, CFArrayRef acls
, CFErrorRef
*error
)
294 SecAccessRef result
= NULL
;
296 CSSM_ACL_PROCESS_SUBJECT_SELECTOR selector
=
298 CSSM_ACL_PROCESS_SELECTOR_CURRENT_VERSION
, // selector version
299 int_cast
<UInt32
, uint16
>(ownerType
),
304 CSSM_LIST_ELEMENT subject2
= { NULL
, 0 };
305 subject2
.Element
.Word
.Data
= (UInt8
*)&selector
;
306 subject2
.Element
.Word
.Length
= sizeof(selector
);
307 CSSM_LIST_ELEMENT subject1
=
309 &subject2
, CSSM_ACL_SUBJECT_TYPE_PROCESS
, CSSM_LIST_ELEMENT_WORDID
316 numAcls
= CFArrayGetCount(acls
);
320 CFStringRef debugStr
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
,
321 CFSTR("SecAccessCreateWithOwnerAndACL: processing %d acls"), (int)numAcls
);
326 std::vector
<CSSM_ACL_AUTHORIZATION_TAG
> rights(numAcls
);
328 for (CFIndex iCnt
= 0; iCnt
< numAcls
; iCnt
++)
330 CFStringRef aclStr
= (CFStringRef
)CFArrayGetValueAtIndex(acls
, iCnt
);
333 debugStr
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
,
334 CFSTR("SecAccessCreateWithOwnerAndACL: acls[%d] = %@"), (int)iCnt
, aclStr
);
340 CSSM_ACL_AUTHORIZATION_TAG aTag
= GetACLAuthorizationTagFromString(aclStr
);
343 debugStr
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
,
344 CFSTR("SecAccessCreateWithOwnerAndACL: rights[%d] = %d"), (int)iCnt
, aTag
);
354 for (CFIndex iCnt
= 0; iCnt
< numAcls
; iCnt
++)
357 debugStr
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
,
358 CFSTR("SecAccessCreateWithOwnerAndACL: rights[%d] = %d"), (int)iCnt
, rights
[iCnt
]);
367 CSSM_ACL_OWNER_PROTOTYPE owner
=
370 { CSSM_LIST_TYPE_UNKNOWN
, &subject1
, &subject2
},
376 // ACL entries (any number, just one here)
377 CSSM_ACL_ENTRY_INFO acl_rights
[] =
383 { CSSM_LIST_TYPE_UNKNOWN
, &subject1
, &subject2
},
385 // rights for this entry
386 { (uint32
)numAcls
, rights
.data() },
392 OSStatus err
= SecAccessCreateFromOwnerAndACL(&owner
,
393 sizeof(acl_rights
) / sizeof(acl_rights
[0]), acl_rights
, &result
);
395 if (errSecSuccess
!= err
)
400 *error
= CFErrorCreate(kCFAllocatorDefault
, CFSTR("FIX ME"), err
, NULL
);
409 OSStatus
SecAccessGetOwnerAndACL(SecAccessRef accessRef
,
410 CSSM_ACL_OWNER_PROTOTYPE_PTR
*owner
,
411 uint32
*aclCount
, CSSM_ACL_ENTRY_INFO_PTR
*acls
)
414 Access::required(accessRef
)->copyOwnerAndAcl(
415 Required(owner
), Required(aclCount
), Required(acls
));
419 OSStatus
SecAccessCopyOwnerAndACL(SecAccessRef accessRef
, uid_t
* userId
, gid_t
* groupId
, SecAccessOwnerType
* ownerType
, CFArrayRef
* aclList
)
422 CSSM_ACL_OWNER_PROTOTYPE_PTR owner
= NULL
;
423 CSSM_ACL_ENTRY_INFO_PTR acls
= NULL
;
425 OSStatus result
= SecAccessGetOwnerAndACL(accessRef
, &owner
, &aclCount
, &acls
);
426 if (errSecSuccess
!= result
)
433 CSSM_LIST_ELEMENT_PTR listHead
= owner
->TypedSubject
.Head
;
434 if (listHead
!= NULL
&& listHead
->ElementType
== CSSM_LIST_ELEMENT_WORDID
)
436 CSSM_LIST_ELEMENT_PTR nextElement
= listHead
->NextElement
;
437 if (listHead
->WordID
== CSSM_ACL_SUBJECT_TYPE_PROCESS
&& listHead
->ElementType
== CSSM_LIST_ELEMENT_WORDID
)
439 // nextElement contains the required data
440 CSSM_ACL_PROCESS_SUBJECT_SELECTOR
* selectorPtr
= (CSSM_ACL_PROCESS_SUBJECT_SELECTOR
*)nextElement
->Element
.Word
.Data
;
441 if (NULL
!= selectorPtr
)
445 *userId
= (uid_t
)selectorPtr
->uid
;
450 *groupId
= (gid_t
)selectorPtr
->gid
;
453 if (NULL
!= ownerType
)
455 *ownerType
= (SecAccessOwnerType
)selectorPtr
->mask
;
467 CFShow(CFSTR("SecAccessCopyOwnerAndACL: processing the ACL list"));
470 CFMutableArrayRef stringArray
= CFArrayCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeArrayCallBacks
);
471 CSSM_ACL_OWNER_PROTOTYPE_PTR protoPtr
= NULL
;
473 CSSM_ACL_ENTRY_INFO_PTR aclEntry
= NULL
;
475 result
= SecAccessGetOwnerAndACL(accessRef
, &protoPtr
, &numAcls
, &aclEntry
);
476 if (errSecSuccess
== result
)
479 CFStringRef tempStr
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("SecAccessCopyOwnerAndACL: numAcls = %d"), numAcls
);
484 for (uint32 iCnt
= 0; iCnt
< numAcls
; iCnt
++)
486 CSSM_ACL_ENTRY_PROTOTYPE prototype
= aclEntry
[iCnt
].EntryPublicInfo
;
487 CSSM_AUTHORIZATIONGROUP authGroup
= prototype
.Authorization
;
488 int numAuthTags
= (int)authGroup
.NumberOfAuthTags
;
490 for (int jCnt
= 0; jCnt
< numAuthTags
; jCnt
++)
493 sint32 aTag
= authGroup
.AuthTags
[jCnt
];
494 CFStringRef aString
= GetAuthStringFromACLAuthorizationTag(aTag
);
496 CFArrayAppendValue(stringArray
, aString
);
501 if (NULL
!= stringArray
)
503 if (0 < CFArrayGetCount(stringArray
))
505 *aclList
= CFArrayCreateCopy(kCFAllocatorDefault
, stringArray
);
507 CFRelease(stringArray
);
516 OSStatus
SecAccessCopyACLList(SecAccessRef accessRef
,
520 Required(aclList
) = Access::required(accessRef
)->copySecACLs();
527 OSStatus
SecAccessCopySelectedACLList(SecAccessRef accessRef
,
528 CSSM_ACL_AUTHORIZATION_TAG action
,
532 Required(aclList
) = Access::required(accessRef
)->copySecACLs(action
);
536 CFArrayRef
SecAccessCopyMatchingACLList(SecAccessRef accessRef
, CFTypeRef authorizationTag
)
539 CFArrayRef result
= NULL
;
540 CSSM_ACL_AUTHORIZATION_TAG tag
= GetACLAuthorizationTagFromString((CFStringRef
)authorizationTag
);
541 OSStatus err
= SecAccessCopySelectedACLList(accessRef
, tag
, &result
);
542 if (errSecSuccess
!= err
)
549 CFArrayRef
copyTrustedAppListFromBundle(CFStringRef bundlePath
, CFStringRef trustedAppListFileName
)
551 CFStringRef errorString
= nil
;
552 CFURLRef bundleURL
,trustedAppsURL
= NULL
;
553 CFBundleRef secBundle
= NULL
;
554 CFPropertyListRef trustedAppsPlist
= NULL
;
555 CFDataRef xmlDataRef
= NULL
;
557 CFArrayRef trustedAppList
= NULL
;
558 CFMutableStringRef trustedAppListFileNameWithoutExtension
= NULL
;
560 // Make a CFURLRef from the CFString representation of the bundleĆs path.
561 bundleURL
= CFURLCreateWithFileSystemPath(
562 kCFAllocatorDefault
,bundlePath
,kCFURLPOSIXPathStyle
,true);
564 CFRange wholeStrRange
;
569 // Make a bundle instance using the URLRef.
570 secBundle
= CFBundleCreate(kCFAllocatorDefault
,bundleURL
);
575 trustedAppListFileNameWithoutExtension
=
576 CFStringCreateMutableCopy(NULL
,CFStringGetLength(trustedAppListFileName
),trustedAppListFileName
);
577 wholeStrRange
= CFStringFind(trustedAppListFileName
,CFSTR(".plist"),0);
579 CFStringDelete(trustedAppListFileNameWithoutExtension
,wholeStrRange
);
581 // Look for a resource in the bundle by name and type
582 trustedAppsURL
= CFBundleCopyResourceURL(secBundle
,trustedAppListFileNameWithoutExtension
,CFSTR("plist"),NULL
);
583 if (!trustedAppsURL
) {
587 if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault
,trustedAppsURL
,&xmlDataRef
,NULL
,NULL
,&errorCode
)) {
591 trustedAppsPlist
= CFPropertyListCreateFromXMLData(kCFAllocatorDefault
,xmlDataRef
,kCFPropertyListImmutable
,&errorString
);
592 trustedAppList
= (CFArrayRef
)trustedAppsPlist
;
595 CFReleaseNull(trustedAppListFileNameWithoutExtension
);
597 CFRelease(bundleURL
);
599 CFRelease(secBundle
);
601 CFRelease(trustedAppsURL
);
603 CFRelease(xmlDataRef
);
605 CFRelease(errorString
);
607 return trustedAppList
;
610 OSStatus
SecAccessCreateWithTrustedApplications(CFStringRef trustedApplicationsPListPath
, CFStringRef accessLabel
, Boolean allowAny
, SecAccessRef
* returnedAccess
)
613 OSStatus err
= errSecSuccess
;
614 SecAccessRef accessToReturn
=nil
;
615 CFMutableArrayRef trustedApplications
=nil
;
617 if (!allowAny
) // use default access ("confirm access")
619 // make an exception list of applications you want to trust,
620 // which are allowed to access the item without requiring user confirmation
621 SecTrustedApplicationRef myself
=NULL
, someOther
=NULL
;
622 CFArrayRef trustedAppListFromBundle
=NULL
;
624 trustedApplications
=CFArrayCreateMutable(kCFAllocatorDefault
,0,&kCFTypeArrayCallBacks
);
625 err
= SecTrustedApplicationCreateFromPath(NULL
, &myself
);
627 CFArrayAppendValue(trustedApplications
,myself
);
629 CFURLRef url
= CFURLCreateWithFileSystemPath(NULL
, trustedApplicationsPListPath
, kCFURLPOSIXPathStyle
, 0);
630 CFStringRef leafStr
= NULL
;
631 leafStr
= CFURLCopyLastPathComponent(url
);
633 CFURLRef bndlPathURL
= NULL
;
634 bndlPathURL
= CFURLCreateCopyDeletingLastPathComponent(NULL
, url
);
635 CFStringRef bndlPath
= NULL
;
636 bndlPath
= CFURLCopyFileSystemPath(bndlPathURL
, kCFURLPOSIXPathStyle
);
637 trustedAppListFromBundle
=copyTrustedAppListFromBundle(bndlPath
, leafStr
);
645 CFRelease(bndlPathURL
);
646 if (trustedAppListFromBundle
)
649 char buffer
[MAXPATHLEN
];
650 top
= CFArrayGetCount(trustedAppListFromBundle
);
651 for (ix
=0;ix
<top
;ix
++)
653 CFStringRef filename
= (CFStringRef
)CFArrayGetValueAtIndex(trustedAppListFromBundle
,ix
);
654 CFIndex stringLength
= CFStringGetLength(filename
);
657 if (stringLength
!= CFStringGetBytes(filename
,CFRangeMake(0,stringLength
),kCFStringEncodingUTF8
,0,
658 false,(UInt8
*)&buffer
,MAXPATHLEN
, &usedBufLen
))
660 buffer
[usedBufLen
] = 0;
662 // Support specification of trusted applications by either
663 // a full pathname or a code requirement string.
667 err
= SecTrustedApplicationCreateFromPath(buffer
,&someOther
);
672 CFStringRef reqStr
= filename
;
673 CFArrayRef descArray
= CFStringCreateArrayBySeparatingStrings(NULL
, reqStr
, CFSTR("\""));
674 if (descArray
&& (CFArrayGetCount(descArray
) > 1))
676 CFStringRef descStr
= (CFStringRef
) CFArrayGetValueAtIndex(descArray
, 1);
678 buf
= CFStringToCString(descStr
);
680 SecRequirementRef reqRef
= NULL
;
681 err
= SecRequirementCreateWithString(reqStr
, kSecCSDefaultFlags
, &reqRef
);
683 err
= SecTrustedApplicationCreateFromRequirement((const char *)buf
, reqRef
, &someOther
);
686 CFReleaseSafe(reqRef
);
687 CFReleaseSafe(descArray
);
690 CFArrayAppendValue(trustedApplications
,someOther
);
693 CFReleaseNull(someOther
);
695 CFRelease(trustedAppListFromBundle
);
699 err
= SecAccessCreate((CFStringRef
)accessLabel
, (CFArrayRef
)trustedApplications
, &accessToReturn
);
702 if (allowAny
) // change access to be wide-open for decryption ("always allow access")
704 // get the access control list for decryption operations
705 CFArrayRef aclList
=nil
;
706 err
= SecAccessCopySelectedACLList(accessToReturn
, CSSM_ACL_AUTHORIZATION_DECRYPT
, &aclList
);
709 // get the first entry in the access control list
710 SecACLRef aclRef
=(SecACLRef
)CFArrayGetValueAtIndex(aclList
, 0);
711 CFArrayRef appList
=nil
;
712 CFStringRef promptDescription
=nil
;
713 CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR promptSelector
;
714 err
= SecACLCopySimpleContents(aclRef
, &appList
, &promptDescription
, &promptSelector
);
716 // modify the default ACL to not require the passphrase, and have a nil application list
717 promptSelector
.flags
&= ~CSSM_ACL_KEYCHAIN_PROMPT_REQUIRE_PASSPHRASE
;
718 err
= SecACLSetSimpleContents(aclRef
, NULL
, promptDescription
, &promptSelector
);
720 if (appList
) CFRelease(appList
);
721 if (promptDescription
) CFRelease(promptDescription
);
725 *returnedAccess
= accessToReturn
;