2 * Copyright (c) 2004,2006 Apple Computer, 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@
25 * singleItemPicker.cpp - select a key or cert from a keychain
28 #include <clAppUtils/keyPicker.h>
29 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
30 #include <Security/Security.h>
33 #include <clAppUtils/identPicker.h> /* for kcFileName() */
34 #include <clAppUtils/keyPicker.h> /* for getKcItemAttr() */
36 #include "singleItemPicker.h"
39 * Class representing one item in the keychain.
41 class SimplePickerItem
44 SimplePickerItem(SecKeychainItemRef itemRef
);
47 CFDataRef
getPrintName() { return mPrintName
; }
48 SecKeychainItemRef
itemRef() { return mItemRef
; }
49 char *kcFile() { return mKcFile
; }
52 SecKeychainItemRef mItemRef
;
54 char *mKcFile
; // file name of keychain this lives on
57 SimplePickerItem::SimplePickerItem(SecKeychainItemRef itemRef
)
62 OSStatus ortn
= getKcItemAttr(itemRef
, WA_PrintName
, &mPrintName
);
64 throw std::invalid_argument("printName attr not available");
67 /* stash name of the keychain this lives on */
69 ortn
= SecKeychainItemCopyKeychain(itemRef
, &kcRef
);
71 cssmPerror("SecKeychainItemCopyKeychain", ortn
);
72 mKcFile
= strdup("Unnamed keychain");
75 mKcFile
= kcFileName(kcRef
);
82 SimplePickerItem::~SimplePickerItem()
88 CFRelease(mPrintName
);
95 typedef std::vector
<SimplePickerItem
*> ItemVector
;
98 * add SimplePickerItem objects of specified type to a ItemVector.
100 static void getPickerItems(
101 SecKeychainRef kcRef
,
102 SecItemClass itemClass
, // CSSM_DL_DB_RECORD_{PRIVATE,PRIVATE}_KEY, etc.
103 ItemVector
&itemVector
)
105 SecKeychainSearchRef srchRef
= NULL
;
106 SecKeychainItemRef kcItem
;
108 OSStatus ortn
= SecKeychainSearchCreateFromAttributes(kcRef
,
113 cssmPerror("SecKeychainSearchCreateFromAttributes", ortn
);
117 ortn
= SecKeychainSearchCopyNext(srchRef
, &kcItem
);
122 SimplePickerItem
*pickerItem
= new SimplePickerItem(kcItem
);
123 itemVector
.push_back(pickerItem
);
126 printf("**** item failed SimplePickerItem constructor ***\n");
129 /* SimplePickerKey holds a ref */
131 } while(ortn
== noErr
);
136 * Print contents of a CFData assuming it's printable
138 static void printCfData(CFDataRef cfd
)
140 CFIndex len
= CFDataGetLength(cfd
);
141 const UInt8
*cp
= CFDataGetBytePtr(cfd
);
142 for(CFIndex dex
=0; dex
<len
; dex
++) {
153 OSStatus
singleItemPicker(
154 SecKeychainRef kcRef
, // NULL means the default list
155 KP_ItemType itemType
,
156 bool takeFirst
, // take first key found
157 SecKeychainItemRef
*itemRef
) // RETURNED
160 SecItemClass itemClass
;
161 OSStatus ortn
= noErr
;
165 std::vector
<SimplePickerItem
*> items
;
169 itemClass
= kSecPrivateKeyItemClass
;
172 itemClass
= kSecPublicKeyItemClass
;
175 itemClass
= kSecCertificateItemClass
;
178 printf("***BRRZAP! Wrong ItemType for singleItemPicker()\n");
181 /* First create a arrays of all of the items, parsed and ready for use */
182 getPickerItems(kcRef
, itemClass
, items
);
183 numItems
= items
.size();
186 printf("...singleItemPicker: no keys found\n");
187 return errSecItemNotFound
;
190 *itemRef
= items
[0]->itemRef();
195 for(dex
=0; dex
<numItems
; dex
++) {
197 SimplePickerItem
*pi
= items
[dex
];
198 printf("[%d] item : ", dex
);
199 printCfData(pi
->getPrintName());
201 printf(" keychain : %s\n", pi
->kcFile());
205 printf("\nEnter item number or CR to quit : ");
208 getString(resp
, sizeof(resp
));
209 if(resp
[0] == '\0') {
210 ortn
= CSSMERR_CSSM_USER_CANCELED
;
214 if((ires
< 0) || (ires
>= numItems
)) {
215 printf("***Invalid entry. Type a number between 0 and %d\n", numItems
);
222 *itemRef
= items
[ires
]->itemRef();
227 /* clean out SimplePickerItem array */
228 for(dex
=0; dex
<numItems
; dex
++) {