]> git.saurik.com Git - apple/security.git/blob - Keychain/SecKeychainAPI.cpp
1c9c123c138dd18e799ea8de16d80497a93b0913
[apple/security.git] / Keychain / SecKeychainAPI.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 * SecKeychainAPI.cpp
21 * SecurityCore
22 *
23 * Copyright: (c) 2000 by Apple Computer, Inc., all rights reserved
24 *
25 */
26
27
28 #include <Security/SecKeychainAPI.h>
29 #include "SecKeychainAPIPriv.h"
30 #include "Keychains.h"
31 #include "Globals.h"
32 #include "KCUtilities.h"
33 #include "KCEventNotifier.h"
34 #include "KCCursor.h"
35 #include "CCallbackMgr.h"
36 #include "KCExceptions.h"
37 #include "Schema.h"
38 #include <Security/globalizer.h>
39
40 using namespace Security;
41
42 using namespace KeychainCore;
43
44 //
45 // API boilerplate macros. These provide a frame for C++ code that is impermeable to exceptions.
46 // Usage:
47 // BEGIN_API
48 // ... your C++ code here ...
49 // END_API // returns CSSM_RETURN on exception
50 // END_API0 // returns nothing (void) on exception
51 // END_API1(bad) // return (bad) on exception
52 //
53 #define BEGIN_SECAPI \
54 try { \
55 StLock<Mutex> _(globals().apiLock);
56 #define END_SECAPI \
57 } \
58 catch (const MacOSError &err) { return err.osStatus(); } \
59 catch (const CssmCommonError &err) { return GetKeychainErrFromCSSMErr(err.cssmError())/*err.cssmError(CSSM_CSSM_BASE_ERROR)*/; } \
60 catch (::std::bad_alloc) { return memFullErr; } \
61 catch (...) { return internalComponentErr; } \
62 return noErr;
63 #define END_SECAPI0 } catch (...) { return; }
64 #define END_SECAPI1(bad) } catch (...) { return bad; }
65
66
67 OSStatus SecKeychainGetVersion(UInt32 *returnVers)
68 {
69 if (!returnVers) return noErr;
70
71 *returnVers=0x02028000;
72 return noErr;
73 }
74
75
76 OSStatus SecKeychainOpen(const char *pathName, SecKeychainRef *keychainRef)
77 {
78 BEGIN_SECAPI
79 RequiredParam(keychainRef)=KeychainRef::handle(globals().storageManager.make(pathName));
80 END_SECAPI
81 }
82
83 OSStatus SecKeychainCreateNew(const char *pathName, SecKeychainRef *keychainRef, UInt32 passwordLength, const void *password, Boolean promptUser)
84 {
85 BEGIN_SECAPI
86
87 KCThrowParamErrIf_(!pathName);
88
89 Keychain keychain = globals().storageManager.make(pathName);
90
91 if(promptUser)
92 {
93 keychain->create();
94 }
95 else
96 {
97 KCThrowParamErrIf_(!password);
98
99 keychain->create(passwordLength, password);
100 }
101 RequiredParam(keychainRef)=KeychainRef::handle(keychain);
102
103 END_SECAPI
104 }
105
106 OSStatus SecKeychainDelete(SecKeychainRef keychainRef)
107 {
108 BEGIN_SECAPI
109
110 Keychain keychain = Keychain::optional(keychainRef);
111 keychain->database()->deleteDb();
112
113 list<SecKeychainRef> SecKeychainRefToRemove;
114 SecKeychainRefToRemove.push_back(keychainRef);
115 KeychainCore::StorageManager &smgr=KeychainCore::globals().storageManager;
116 smgr.remove(SecKeychainRefToRemove);
117 return noErr;
118
119 END_SECAPI
120
121
122 }
123 OSStatus SecKeychainSetSettings(SecKeychainRef keychainRef, const SecKeychainSettings *newSettings)
124 {
125 BEGIN_SECAPI
126 Keychain keychain = Keychain::optional(keychainRef);
127 if(newSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1)
128 {
129 UInt32 lockInterval=newSettings->lockInterval;
130 bool lockOnSleep=newSettings->lockOnSleep;
131
132 keychain->setSettings(lockInterval, lockOnSleep);
133 }
134 END_SECAPI
135 }
136
137
138 OSStatus SecKeychainCopySettings(SecKeychainRef keychainRef, SecKeychainSettings *outSettings)
139 {
140 BEGIN_SECAPI
141 Keychain keychain = Keychain::optional(keychainRef);
142 if(outSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1)
143 {
144 UInt32 lockInterval;
145 bool lockOnSleep;
146
147 keychain->getSettings(lockInterval, lockOnSleep);
148 outSettings->lockInterval=lockInterval;
149 outSettings->lockOnSleep=lockOnSleep;
150 }
151 END_SECAPI
152 }
153
154
155 OSStatus SecKeychainUnlock(SecKeychainRef keychainRef, UInt32 passwordLength, void *password, Boolean usePassword)
156 {
157 BEGIN_SECAPI
158 Keychain keychain = Keychain::optional(keychainRef);
159
160 if(usePassword)
161 keychain->unlock(CssmData(password,passwordLength));
162 else
163 keychain->unlock();
164 END_SECAPI
165 }
166
167
168 OSStatus SecKeychainLock(SecKeychainRef keychainRef)
169 {
170 BEGIN_SECAPI
171 Keychain keychain = Keychain::optional(keychainRef);
172 keychain->lock();
173 END_SECAPI
174 }
175
176
177 OSStatus SecKeychainLockAll()
178 {
179 BEGIN_SECAPI
180 globals().storageManager.lockAll();
181 END_SECAPI
182 }
183
184
185 OSStatus SecKeychainRelease(SecKeychainRef keychainRef)
186 {
187 BEGIN_SECAPI
188 KeychainRef::release(keychainRef);
189 END_SECAPI
190 }
191
192
193 OSStatus SecKeychainCopyDefault(SecKeychainRef *keychainRef)
194 {
195 BEGIN_SECAPI
196 RequiredParam(keychainRef)=KeychainRef::handle(globals().defaultKeychain.keychain());
197 END_SECAPI
198 }
199
200
201 OSStatus SecKeychainSetDefault(SecKeychainRef keychainRef)
202 {
203 BEGIN_SECAPI
204 globals().defaultKeychain.keychain(Keychain::optional(keychainRef));
205 END_SECAPI
206 }
207
208
209 OSStatus SecKeychainGetStatus(SecKeychainRef keychainRef, SecKeychainStatus *keychainStatus)
210 {
211 BEGIN_SECAPI
212 RequiredParam(keychainStatus) = (SecKeychainStatus)Keychain::optional(keychainRef)->status();
213 END_SECAPI
214 }
215
216
217 OSStatus SecKeychainGetPath(SecKeychainRef keychainRef, UInt32 * ioPathLength, char *pathName)
218 {
219 BEGIN_SECAPI
220 RequiredParam(pathName);
221 const char *name = Keychain::optional(keychainRef)->name();
222 UInt32 nameLen = strlen(name);
223 memcpy(pathName, name, *ioPathLength);
224 if(nameLen < *ioPathLength) // if the size is smaller then the buffer
225 *ioPathLength=nameLen; // set the length. otherwise the size is clipped because
226 // the buffer is too small.
227
228 END_SECAPI
229 }
230
231
232 UInt16 SecKeychainListGetCount(void)
233 {
234 BEGIN_SECAPI
235 return globals().storageManager.size();
236 END_SECAPI
237 }
238
239
240 OSStatus SecKeychainListCopyKeychainAtIndex(UInt16 index, SecKeychainRef *keychainRef)
241 {
242 BEGIN_SECAPI
243 KeychainCore::StorageManager &smgr=KeychainCore::globals().storageManager;
244 RequiredParam(keychainRef)=KeychainRef::handle(smgr[index]);
245 END_SECAPI
246 }
247
248 OSStatus SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void *data, SecKeychainRef keychainRef, SecKeychainItemRef *itemRef)
249 {
250 BEGIN_SECAPI
251 KCThrowParamErrIf_(length!=0 && data==NULL);
252 Item item(itemClass, attrList, length, data);
253 Keychain::optional(keychainRef)->add(item);
254 if (itemRef)
255 *itemRef = ItemRef::handle(item);
256 END_SECAPI
257 }
258
259 OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data)
260 {
261 BEGIN_SECAPI
262 Item item = ItemRef::required(itemRef);
263 item->modifyContent(attrList, length, data);
264 END_SECAPI
265 }
266
267
268 OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData)
269 {
270 BEGIN_SECAPI
271 Item item = ItemRef::required(itemRef);
272 item->getContent(itemClass, attrList, length, outData);
273 END_SECAPI
274 }
275
276 OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList *attrList, void *data)
277 {
278 BEGIN_SECAPI
279 ItemImpl::freeContent(attrList, data);
280 END_SECAPI
281 }
282
283
284 OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef keychainRef, UInt32 itemID, SecKeychainAttributeInfo **info)
285 {
286 BEGIN_SECAPI
287 Keychain keychain = Keychain::optional(keychainRef);
288 keychain->getAttributeInfoForItemID(itemID, info);
289 END_SECAPI
290 }
291
292 OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info)
293 {
294 BEGIN_SECAPI
295 KeychainImpl::freeAttributeInfo(info);
296 END_SECAPI
297 }
298
299 OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data)
300 {
301 BEGIN_SECAPI
302 Item item = ItemRef::required(itemRef);
303 item->modifyAttributesAndData(attrList, length, data);
304 END_SECAPI
305 }
306
307 OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, UInt32 *length, void **outData)
308 {
309 BEGIN_SECAPI
310 Item item = ItemRef::required(itemRef);
311 item->getAttributesAndData(info, itemClass, attrList, length, outData);
312 END_SECAPI
313 }
314
315 OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList *attrList, void *data)
316 {
317 BEGIN_SECAPI
318 ItemImpl::freeAttributesAndData(attrList, data);
319 END_SECAPI
320 }
321
322 OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef)
323 {
324 BEGIN_SECAPI
325 Item item = ItemRef::required( itemRef );
326 Keychain keychain = item->keychain();
327 KCThrowIf_( !keychain, errSecInvalidItemRef );
328
329 keychain->deleteItem( item ); // item must be persistant.
330 END_SECAPI
331 }
332
333
334 OSStatus SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef* keychainRef)
335 {
336 BEGIN_SECAPI
337 Required(keychainRef) = KeychainRef::handle(ItemRef::required(itemRef)->keychain());
338 END_SECAPI
339 }
340
341
342 OSStatus SecKeychainItemCreateCopy(SecKeychainItemRef itemRef, SecKeychainItemRef *itemCopy, SecKeychainRef destKeychainRef)
343 {
344 BEGIN_SECAPI
345 Item copy = ItemRef::required(itemRef)->copyTo(Keychain::optional(destKeychainRef));
346 if (itemCopy)
347 *itemCopy = ItemRef::handle(copy);
348 END_SECAPI
349 }
350
351
352 OSStatus SecKeychainItemRelease(SecKeychainItemRef itemRef)
353 {
354 BEGIN_SECAPI
355 ItemRef::release(itemRef);
356 END_SECAPI
357 }
358
359 OSStatus SecKeychainSearchCreateFromAttributes(SecKeychainRef keychainRef, SecItemClass itemClass, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef)
360 {
361 BEGIN_SECAPI
362
363 Required(searchRef); // Make sure that searchRef is an invalid SearchRef
364
365 KCCursor cursor;
366 if (keychainRef)
367 cursor = Keychain::optional(keychainRef)->createCursor(itemClass, attrList);
368 else
369 cursor = globals().storageManager.createCursor(itemClass, attrList);
370
371 *searchRef = KCCursorRef::handle(cursor);
372
373 END_SECAPI
374 }
375
376
377 OSStatus SecKeychainCopySearchNextItem(SecKeychainSearchRef searchRef, SecKeychainItemRef *itemRef)
378 {
379 BEGIN_SECAPI
380 RequiredParam(itemRef);
381 Item item;
382 if (!KCCursorRef::required(searchRef)->next(item))
383 return errSecItemNotFound;
384
385 *itemRef=ItemRef::handle(item);
386 END_SECAPI
387 }
388
389 OSStatus SecKeychainSearchRelease(SecKeychainSearchRef searchRef)
390 {
391 BEGIN_SECAPI
392 KCCursorRef::release(searchRef);
393 END_SECAPI
394 }
395
396
397 OSStatus SecKeychainListRemoveKeychain(SecKeychainRef *keychainRef)
398 {
399 BEGIN_SECAPI
400 list<SecKeychainRef> SecKeychainRefToRemove;
401 SecKeychainRefToRemove.push_back(RequiredParam(keychainRef));
402 StorageManager &smgr = globals().storageManager;
403 smgr.remove(SecKeychainRefToRemove);
404 return noErr;
405 END_SECAPI
406 }
407
408
409 pascal OSStatus SecKeychainAddCallback(SecKeychainCallbackProcPtr callbackFunction, SecKeychainEventMask eventMask, void* userContext)
410 {
411 BEGIN_SECAPI
412 RequiredParam(callbackFunction);
413 CCallbackMgr::AddCallback(callbackFunction,eventMask,userContext);
414 END_SECAPI
415 }
416
417 OSStatus SecKeychainRemoveCallback(SecKeychainCallbackProcPtr callbackFunction)
418 {
419 BEGIN_SECAPI
420 RequiredParam(callbackFunction);
421 CCallbackMgr::RemoveCallback(callbackFunction);
422 END_SECAPI
423 }
424
425
426 // --- Private API
427
428 OSStatus SecKeychainChangePassword(SecKeychainRef keychainRef, UInt32 oldPasswordLength, const void *oldPassword, UInt32 newPasswordLength, const void *newPassword)
429 {
430 BEGIN_SECAPI
431 globals().storageManager.changeLoginPassword(oldPasswordLength, oldPassword, newPasswordLength, newPassword);
432 END_SECAPI
433 }
434
435 OSStatus SecKeychainCopyLogin(SecKeychainRef *keychainRef)
436 {
437 BEGIN_SECAPI
438 // NOTE: operates on default Keychain! It shouldn't... we want to
439 // have code that operates of a login keychain.
440 RequiredParam(keychainRef)=KeychainRef::handle(globals().defaultKeychain.keychain());
441 END_SECAPI
442 }
443
444
445 OSStatus SecKeychainAddInternetPassword(SecKeychainRef keychainRef, UInt32 serverNameLength, char *serverName,
446 UInt32 securityDomainLength, char *securityDomain, UInt32 accountNameLength, char *accountName,
447 UInt32 pathLength, char *path, UInt16 port, OSType protocol, OSType authType,
448 UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef)
449 {
450 BEGIN_SECAPI
451 KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL);
452 // @@@ Get real itemClass
453 Item item(kSecInternetPasswordItemClass, 'aapl', passwordLength, passwordData);
454
455 if (serverName && serverNameLength)
456 item->setAttribute(Schema::attributeInfo(kSecServerItemAttr),
457 CssmData(serverName, serverNameLength));
458
459 if (accountName && accountNameLength)
460 {
461 CssmData account(accountName, accountNameLength);
462 item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
463 // @@@ We should probably leave setting of label up to lower level code.
464 item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), account);
465 }
466
467 if (securityDomain && securityDomainLength)
468 item->setAttribute(Schema::attributeInfo(kSecSecurityDomainItemAttr),
469 CssmData(securityDomain, securityDomainLength));
470
471 item->setAttribute(Schema::attributeInfo(kSecPortItemAttr), UInt32(port));
472 item->setAttribute(Schema::attributeInfo(kSecProtocolItemAttr), protocol);
473 item->setAttribute(Schema::attributeInfo(kSecAuthTypeItemAttr), authType);
474
475 if (path && pathLength)
476 item->setAttribute(Schema::attributeInfo(kSecPathItemAttr),
477 CssmData(path, pathLength));
478
479 Keychain::optional(keychainRef)->add(item);
480 if (itemRef)
481 *itemRef = ItemRef::handle(item);
482
483 END_SECAPI
484 }
485
486 OSStatus SecKeychainFindInternetPassword(SecKeychainRef keychainRef, UInt32 serverNameLength, char *serverName,
487 UInt32 securityDomainLength, char *securityDomain, UInt32 accountNameLength, char *accountName,
488 UInt32 pathLength, char *path, UInt16 port, OSType protocol, OSType authType,
489 UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef)
490
491 {
492 BEGIN_SECAPI
493
494
495 UInt32 attrCount = 0;
496
497 // The number of attributes to search on depends on what was passed in
498 if ( serverName && serverNameLength)
499 attrCount++;
500
501 if ( securityDomain && securityDomainLength )
502 attrCount++;
503
504 if ( accountName && accountNameLength)
505 attrCount++;
506
507 if ( port )
508 attrCount++;
509
510 if ( protocol )
511 attrCount++;
512
513 if ( authType )
514 attrCount++;
515
516 if ( path && pathLength )
517 attrCount++;
518
519 auto_array<SecKeychainAttribute> attrs(attrCount);
520 attrCount = 0;
521
522 if ( serverName && serverNameLength )
523 {
524 attrs[attrCount].tag = kSecServerItemAttr;
525 attrs[attrCount].length = serverNameLength;
526 attrs[attrCount].data = serverName;
527 attrCount++;
528 }
529 if ( securityDomain && securityDomainLength )
530 {
531 attrs[attrCount].tag = kSecSecurityDomainItemAttr;
532 attrs[attrCount].length = securityDomainLength;
533 attrs[attrCount].data = securityDomain;
534 attrCount++;
535 }
536 if ( accountName && accountNameLength )
537 {
538 attrs[attrCount].tag = kSecAccountItemAttr;
539 attrs[attrCount].length = accountNameLength;
540 attrs[attrCount].data = accountName;
541 attrCount++;
542 }
543
544 if ( port )
545 {
546 attrs[attrCount].tag = kSecPortItemAttr;
547 attrs[attrCount].length = sizeof( port );
548 attrs[attrCount].data = &port;
549 attrCount++;
550 }
551 if ( protocol )
552 {
553 attrs[attrCount].tag = kSecProtocolItemAttr;
554 attrs[attrCount].length = sizeof( protocol );
555 attrs[attrCount].data = &protocol;
556 attrCount++;
557 }
558 if ( authType )
559 {
560 attrs[attrCount].tag = kSecAuthTypeItemAttr;
561 attrs[attrCount].length = sizeof( authType );
562 attrs[attrCount].data = &authType;
563 attrCount++;
564 }
565
566 if ( path && pathLength )
567 {
568 attrs[attrCount].tag = kSecPathItemAttr;
569 attrs[attrCount].length = pathLength;
570 attrs[attrCount].data = path;
571 attrCount++;
572 }
573
574 SecKeychainAttributeList attrList;
575 attrList.count = attrCount;
576 attrList.attr = attrs.get();
577
578 Item item;
579
580 KCCursor cursor;
581 if (keychainRef)
582 cursor = Keychain::optional(keychainRef)->createCursor(kSecInternetPasswordItemClass, &attrList);
583 else
584 cursor = globals().storageManager.createCursor(kSecInternetPasswordItemClass, &attrList);
585
586 if (!cursor->next(item))
587 return errSecItemNotFound;
588
589
590 // Get its data (only if necessary)
591 if ( passwordData || passwordLength )
592 {
593 CssmDataContainer outData;
594 item->getData(outData);
595 *passwordLength=outData.length();
596 outData.Length=NULL;
597 *passwordData=outData.data();
598 outData.Data=NULL;
599 }
600
601 if (itemRef)
602 *itemRef=ItemRef::handle(item);
603
604
605 END_SECAPI
606
607
608
609 }
610
611 OSStatus SecKeychainAddGenericPassword(SecKeychainRef keychainRef, UInt32 serviceNameLength, char *serviceName,
612 UInt32 accountNameLength, char *accountName,
613 UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef)
614
615 {
616 BEGIN_SECAPI
617
618 KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL);
619 // @@@ Get real itemClass
620 Item item(kSecGenericPasswordItemClass, 'aapl', passwordLength, passwordData);
621
622 if (serviceName && serviceNameLength)
623 item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), CssmData(serviceName, serviceNameLength));
624
625 if (accountName && accountNameLength)
626 {
627 CssmData account(accountName, accountNameLength);
628 item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
629 // @@@ We should probably leave setting of label up to lower level code.
630 item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), account);
631 }
632
633 Keychain::optional(keychainRef)->add(item);
634 if (itemRef)
635 *itemRef = ItemRef::handle(item);
636
637 END_SECAPI
638 }
639
640 OSStatus SecKeychainFindGenericPassword(SecKeychainRef keychainRef, UInt32 serviceNameLength, char *serviceName,
641 UInt32 accountNameLength, char *accountName,
642 UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef)
643
644 {
645 BEGIN_SECAPI
646 UInt32 attrCount = 0;
647
648 // The number of attributes to search on depends on what was passed in
649 if (serviceName && serviceNameLength)
650 attrCount++;
651
652 if (accountName && accountNameLength)
653 attrCount++;
654
655 auto_array<SecKeychainAttribute> attrs(attrCount);
656 attrCount = 0;
657
658 if (serviceName && serviceNameLength)
659 {
660 attrs[attrCount].tag = kSecServiceItemAttr;
661 attrs[attrCount].length = serviceNameLength;
662 attrs[attrCount].data = serviceName;
663 attrCount++;
664 }
665 if (accountName && accountNameLength)
666 {
667 attrs[attrCount].tag = kSecAccountItemAttr;
668 attrs[attrCount].length = accountNameLength;
669 attrs[attrCount].data = accountName;
670 attrCount++;
671 }
672
673 SecKeychainAttributeList attrList;
674 attrList.count = attrCount;
675 attrList.attr = attrs.get();
676
677 Item item;
678
679 KCCursor cursor;
680 if (keychainRef)
681 cursor = Keychain::optional(keychainRef)->createCursor(kSecGenericPasswordItemClass, &attrList);
682 else
683 cursor = globals().storageManager.createCursor(kSecGenericPasswordItemClass, &attrList);
684
685 if (!cursor->next(item))
686 return errSecItemNotFound;
687
688
689 // Get its data (only if necessary)
690 if ( passwordData || passwordLength )
691 {
692 CssmDataContainer outData;
693 item->getData(outData);
694 *passwordLength=outData.length();
695 outData.Length=NULL;
696 *passwordData=outData.data();
697 outData.Data=NULL;
698 }
699
700 if (itemRef)
701 *itemRef=ItemRef::handle(item);
702
703
704 END_SECAPI
705 }
706
707 OSStatus SecKeychainLogin(UInt32 nameLength, void* name, UInt32 passwordLength, void* password)
708 {
709 BEGIN_SECAPI
710 globals().storageManager.login(nameLength, name, passwordLength, password);
711 END_SECAPI
712 }
713
714 OSStatus SecKeychainLogout()
715 {
716 BEGIN_SECAPI
717 globals().storageManager.logout();
718 END_SECAPI
719 }
720
721 OSStatus SecKeychainSetUserInteractionAllowed(Boolean state)
722 {
723 BEGIN_SECAPI
724 globals().setUserInteractionAllowed(state);
725 END_SECAPI
726
727 }
728
729 OSStatus SecKeychainGetUserInteractionAllowed(Boolean *state)
730 {
731 BEGIN_SECAPI
732 Required(state)=globals().getUserInteractionAllowed();
733 END_SECAPI
734
735 }
736