]> git.saurik.com Git - apple/security.git/blob - Keychain/SecKeychain.cpp
53d05c19754b2d23604f85ffcdcfcffa3c007584
[apple/security.git] / Keychain / SecKeychain.cpp
1 /*
2 * Copyright (c) 2000-2002 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 #include <Security/SecKeychainAPIPriv.h>
19 #include <Security/SecKeychain.h>
20 #include <Security/KCCursor.h>
21 #include <Security/cssmdata.h>
22 #include <Security/KCExceptions.h>
23 #include "SecBridge.h"
24 #include "CCallbackMgr.h"
25 #include "Schema.h"
26 #include <Security/ktracecodes.h>
27 #include <pwd.h>
28
29 CFTypeID
30 SecKeychainGetTypeID(void)
31 {
32 BEGIN_SECAPI
33
34 secdebug("kc", "SecKeychainGetTypeID()");
35 return gTypes().KeychainImpl.typeID;
36
37 END_SECAPI1(_kCFRuntimeNotATypeID)
38 }
39
40
41 OSStatus
42 SecKeychainGetVersion(UInt32 *returnVers)
43 {
44 secdebug("kc", "SecKeychainGetVersion(%p)", returnVers);
45 if (!returnVers)
46 return noErr;
47
48 *returnVers = 0x02028000;
49 return noErr;
50 }
51
52
53 OSStatus
54 SecKeychainOpen(const char *pathName, SecKeychainRef *keychainRef)
55 {
56 BEGIN_SECAPI
57
58 secdebug("kc", "SecKeychainOpen(\"%s\", %p)", pathName, keychainRef);
59 RequiredParam(keychainRef)=globals().storageManager.make(pathName, false)->handle();
60
61 END_SECAPI
62 }
63
64
65 OSStatus
66 SecKeychainCreate(const char *pathName, UInt32 passwordLength, const void *password,
67 Boolean promptUser, SecAccessRef initialAccess, SecKeychainRef *keychainRef)
68 {
69 BEGIN_SECAPI
70
71 secdebug("kc", "SecKeychainCreate(\"%s\", %lu, %p, %d, %p, %p)", pathName, passwordLength, password, promptUser, initialAccess, keychainRef);
72 KCThrowParamErrIf_(!pathName);
73 Keychain keychain = globals().storageManager.make(pathName);
74
75 // @@@ the call to StorageManager::make above leaves keychain the the cache.
76 // If the create below fails we should probably remove it.
77 if(promptUser)
78 keychain->create();
79 else
80 {
81 KCThrowParamErrIf_(!password);
82 keychain->create(passwordLength, password);
83 }
84 RequiredParam(keychainRef)=keychain->handle();
85
86 END_SECAPI
87 }
88
89
90 OSStatus
91 SecKeychainDelete(SecKeychainRef keychainOrArray)
92 {
93 BEGIN_SECAPI
94
95 secdebug("kc", "SecKeychainDelete(%p)", keychainOrArray);
96 KCThrowIf_(!keychainOrArray, errSecInvalidKeychain);
97 StorageManager::KeychainList keychains;
98 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
99 globals().storageManager.remove(keychains, true);
100
101 END_SECAPI
102 }
103
104
105 OSStatus
106 SecKeychainSetSettings(SecKeychainRef keychainRef, const SecKeychainSettings *newSettings)
107 {
108 BEGIN_SECAPI
109
110 secdebug("kc", "SecKeychainSetSettings(%p, %p)", keychainRef, newSettings);
111 Keychain keychain = Keychain::optional(keychainRef);
112 if (newSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1)
113 {
114 UInt32 lockInterval=newSettings->lockInterval;
115 bool lockOnSleep=newSettings->lockOnSleep;
116 keychain->setSettings(lockInterval, lockOnSleep);
117 }
118
119 END_SECAPI
120 }
121
122
123 OSStatus
124 SecKeychainCopySettings(SecKeychainRef keychainRef, SecKeychainSettings *outSettings)
125 {
126 BEGIN_SECAPI
127
128 secdebug("kc", "SecKeychainCopySettings(%p, %p)", keychainRef, outSettings);
129 Keychain keychain = Keychain::optional(keychainRef);
130 if (outSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1)
131 {
132 UInt32 lockInterval;
133 bool lockOnSleep;
134
135 keychain->getSettings(lockInterval, lockOnSleep);
136 outSettings->lockInterval=lockInterval;
137 outSettings->lockOnSleep=lockOnSleep;
138 }
139
140 END_SECAPI
141 }
142
143
144 OSStatus
145 SecKeychainUnlock(SecKeychainRef keychainRef, UInt32 passwordLength, void *password, Boolean usePassword)
146 {
147 BEGIN_SECAPI
148
149 secdebug("kc", "SecKeychainUnlock(%p, %lu, %p, %d)", keychainRef, passwordLength, password, usePassword);
150 Keychain keychain = Keychain::optional(keychainRef);
151
152 if (usePassword)
153 keychain->unlock(CssmData(password,passwordLength));
154 else
155 keychain->unlock();
156
157 END_SECAPI
158 }
159
160
161 OSStatus
162 SecKeychainLock(SecKeychainRef keychainRef)
163 {
164 BEGIN_SECAPI
165
166 secdebug("kc", "SecKeychainLock(%p)", keychainRef);
167 Keychain keychain = Keychain::optional(keychainRef);
168 keychain->lock();
169
170 END_SECAPI
171 }
172
173
174 OSStatus
175 SecKeychainLockAll(void)
176 {
177 BEGIN_SECAPI
178
179 secdebug("kc", "SecKeychainLockAll()");
180 globals().storageManager.lockAll();
181
182 END_SECAPI
183 }
184
185
186 OSStatus SecKeychainResetLogin(UInt32 passwordLength, const void* password, Boolean resetSearchList)
187 {
188 BEGIN_SECAPI
189 KCThrowParamErrIf_(password==NULL);
190 //
191 // Get the current user (using fallback method if necessary)
192 //
193 char* uName = getenv("USER");
194 string userName = uName ? uName : "";
195 if ( userName.length() == 0 )
196 {
197 uid_t uid = geteuid();
198 if (!uid) uid = getuid();
199 struct passwd *pw = getpwuid(uid); // fallback case...
200 if (pw)
201 userName = pw->pw_name;
202 endpwent();
203 }
204 if ( userName.length() == 0 ) // did we ultimately get one?
205 MacOSError::throwMe(errAuthorizationInternal);
206 //
207 // Clears the plist and moves aside (renames) an existing login.keychain
208 //
209 globals().storageManager.resetKeychain(resetSearchList);
210 //
211 // Creates a login keychain and sets it to the default.
212 //
213 globals().storageManager.login(userName.length(), userName.c_str(), passwordLength, password);
214 Keychain keychain = globals().storageManager.loginKeychain();
215 globals().storageManager.defaultKeychain(keychain);
216 END_SECAPI
217 }
218
219 OSStatus
220 SecKeychainCopyDefault(SecKeychainRef *keychainRef)
221 {
222 BEGIN_SECAPI
223
224 secdebug("kc", "SecKeychainCopyDefault(%p)", keychainRef);
225 RequiredParam(keychainRef)=globals().storageManager.defaultKeychain()->handle();
226
227 END_SECAPI
228 }
229
230
231 OSStatus
232 SecKeychainSetDefault(SecKeychainRef keychainRef)
233 {
234 BEGIN_SECAPI
235
236 secdebug("kc", "SecKeychainSetDefault(%p)", keychainRef);
237 globals().storageManager.defaultKeychain(Keychain::optional(keychainRef));
238
239 END_SECAPI
240 }
241
242 OSStatus SecKeychainCopySearchList(CFArrayRef *searchList)
243 {
244 BEGIN_SECAPI
245
246 secdebug("kc", "SecKeychainCopySearchList(%p)", searchList);
247 RequiredParam(searchList);
248 StorageManager &smr = globals().storageManager;
249 StorageManager::KeychainList keychainList;
250 smr.getSearchList(keychainList);
251 *searchList = smr.convertFromKeychainList(keychainList);
252
253 END_SECAPI
254 }
255
256 OSStatus SecKeychainSetSearchList(CFArrayRef searchList)
257 {
258 BEGIN_SECAPI
259
260 secdebug("kc", "SecKeychainSetSearchList(%p)", searchList);
261 RequiredParam(searchList);
262 StorageManager &smr = globals().storageManager;
263 StorageManager::KeychainList keychainList;
264 smr.convertToKeychainList(searchList, keychainList);
265 smr.setSearchList(keychainList);
266
267 END_SECAPI
268 }
269
270 OSStatus SecKeychainCopyDomainDefault(SecPreferencesDomain domain, SecKeychainRef *keychainRef)
271 {
272 BEGIN_SECAPI
273
274 secdebug("kc", "SecKeychainCopyDefault(%p)", keychainRef);
275 RequiredParam(keychainRef)=globals().storageManager.defaultKeychain(domain)->handle();
276
277 END_SECAPI
278 }
279
280 OSStatus SecKeychainSetDomainDefault(SecPreferencesDomain domain, SecKeychainRef keychainRef)
281 {
282 BEGIN_SECAPI
283
284 secdebug("kc", "SecKeychainSetDefault(%p)", keychainRef);
285 globals().storageManager.defaultKeychain(domain, Keychain::optional(keychainRef));
286
287 END_SECAPI
288 }
289
290 OSStatus SecKeychainCopyDomainSearchList(SecPreferencesDomain domain, CFArrayRef *searchList)
291 {
292 BEGIN_SECAPI
293
294 secdebug("kc", "SecKeychainCopyDomainSearchList(%p)", searchList);
295 RequiredParam(searchList);
296 StorageManager &smr = globals().storageManager;
297 StorageManager::KeychainList keychainList;
298 smr.getSearchList(domain, keychainList);
299 *searchList = smr.convertFromKeychainList(keychainList);
300
301 END_SECAPI
302 }
303
304 OSStatus SecKeychainSetDomainSearchList(SecPreferencesDomain domain, CFArrayRef searchList)
305 {
306 BEGIN_SECAPI
307
308 secdebug("kc", "SecKeychainSetDomainSearchList(%p)", searchList);
309 RequiredParam(searchList);
310 StorageManager &smr = globals().storageManager;
311 StorageManager::KeychainList keychainList;
312 smr.convertToKeychainList(searchList, keychainList);
313 smr.setSearchList(domain, keychainList);
314
315 END_SECAPI
316 }
317
318 OSStatus SecKeychainSetPreferenceDomain(SecPreferencesDomain domain)
319 {
320 BEGIN_SECAPI
321
322 globals().storageManager.domain(domain);
323
324 END_SECAPI
325 }
326
327 OSStatus SecKeychainGetPreferenceDomain(SecPreferencesDomain *domain)
328 {
329 BEGIN_SECAPI
330
331 *domain = globals().storageManager.domain();
332
333 END_SECAPI
334 }
335
336
337 OSStatus
338 SecKeychainGetStatus(SecKeychainRef keychainRef, SecKeychainStatus *keychainStatus)
339 {
340 BEGIN_SECAPI
341
342 secdebug("kc", "SecKeychainGetStatus(%p): %p", keychainRef, keychainStatus);
343 RequiredParam(keychainStatus) = (SecKeychainStatus)Keychain::optional(keychainRef)->status();
344
345 END_SECAPI
346 }
347
348
349 OSStatus
350 SecKeychainGetPath(SecKeychainRef keychainRef, UInt32 *ioPathLength, char *pathName)
351 {
352 BEGIN_SECAPI
353
354 secdebug("kc", "SecKeychainGetPath(%p, %p, %p)", keychainRef, ioPathLength, pathName);
355 RequiredParam(pathName);
356 RequiredParam(ioPathLength);
357
358 const char *name = Keychain::optional(keychainRef)->name();
359 UInt32 nameLen = strlen(name);
360 if (nameLen+1 > *ioPathLength) // if the client's buffer is too small (including null-termination), throw
361 CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL);
362 strncpy(pathName, name, nameLen);
363 pathName[nameLen] = 0;
364 *ioPathLength = nameLen; // set the length.
365
366 END_SECAPI
367 }
368
369
370 // @@@ Depricated
371 UInt16
372 SecKeychainListGetCount(void)
373 {
374 BEGIN_SECAPI
375
376 secdebug("kc", "SecKeychainListGetCount()");
377 return globals().storageManager.size();
378
379 END_SECAPI1(0)
380 }
381
382
383 // @@@ Depricated
384 OSStatus
385 SecKeychainListCopyKeychainAtIndex(UInt16 index, SecKeychainRef *keychainRef)
386 {
387 BEGIN_SECAPI
388
389 secdebug("kc", "SecKeychainListCopyKeychainAtIndex(%d, %p)", index, keychainRef);
390 KeychainCore::StorageManager &smgr=KeychainCore::globals().storageManager;
391 RequiredParam(keychainRef)=smgr[index]->handle();
392
393 END_SECAPI
394 }
395
396
397 // @@@ Depricated
398 OSStatus
399 SecKeychainListRemoveKeychain(SecKeychainRef *keychainRef)
400 {
401 BEGIN_SECAPI
402
403 secdebug("kc", "SecKeychainListRemoveKeychain(%p)", keychainRef);
404 Required(keychainRef);
405 Keychain keychain = Keychain::optional(*keychainRef);
406 StorageManager::KeychainList keychainList;
407 keychainList.push_back(keychain);
408 globals().storageManager.remove(keychainList);
409 *keychainRef = NULL;
410
411 END_SECAPI
412 }
413
414
415 OSStatus
416 SecKeychainAttributeInfoForItemID(SecKeychainRef keychainRef, UInt32 itemID, SecKeychainAttributeInfo **info)
417 {
418 BEGIN_SECAPI
419
420 secdebug("kc", "SecKeychainAttributeInfoForItemID(%p, %lu, %p)", keychainRef, itemID, info);
421 Keychain keychain = Keychain::optional(keychainRef);
422 keychain->getAttributeInfoForItemID(itemID, info);
423
424 END_SECAPI
425 }
426
427
428 OSStatus
429 SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info)
430 {
431 BEGIN_SECAPI
432
433 secdebug("kc", "SecKeychainFreeAttributeInfo(%p)", info);
434 KeychainImpl::freeAttributeInfo(info);
435
436 END_SECAPI
437 }
438
439
440 pascal OSStatus
441 SecKeychainAddCallback(SecKeychainCallback callbackFunction, SecKeychainEventMask eventMask, void* userContext)
442 {
443 BEGIN_SECAPI
444
445 secdebug("kc", "SecKeychainAddCallback(%p, %08lx, %p)", callbackFunction, eventMask, userContext);
446 RequiredParam(callbackFunction);
447 CCallbackMgr::AddCallback(callbackFunction,eventMask,userContext);
448
449 END_SECAPI
450 }
451
452
453 OSStatus
454 SecKeychainRemoveCallback(SecKeychainCallback callbackFunction)
455 {
456 BEGIN_SECAPI
457
458 secdebug("kc", "SecKeychainRemoveCallback(%p)", callbackFunction);
459 RequiredParam(callbackFunction);
460 CCallbackMgr::RemoveCallback(callbackFunction);
461
462 END_SECAPI
463 }
464
465 OSStatus
466 SecKeychainAddInternetPassword(SecKeychainRef keychainRef, UInt32 serverNameLength, const char *serverName, UInt32 securityDomainLength, const char *securityDomain, UInt32 accountNameLength, const char *accountName, UInt32 pathLength, const char *path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef)
467 {
468 BEGIN_SECAPI
469
470 secdebug("kc", "SecKeychainAddInternetPassword(%p)", keychainRef);
471 KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL);
472 // @@@ Get real itemClass
473 Item item(kSecInternetPasswordItemClass, 'aapl', passwordLength, passwordData);
474
475 if (serverName && serverNameLength)
476 {
477 CssmData server(const_cast<void *>(reinterpret_cast<const void *>(serverName)), serverNameLength);
478 item->setAttribute(Schema::attributeInfo(kSecServerItemAttr), server);
479 // use server name as default label
480 item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), server);
481 }
482
483 if (accountName && accountNameLength)
484 {
485 CssmData account(const_cast<void *>(reinterpret_cast<const void *>(accountName)), accountNameLength);
486 item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
487 }
488
489 if (securityDomain && securityDomainLength)
490 item->setAttribute(Schema::attributeInfo(kSecSecurityDomainItemAttr),
491 CssmData(const_cast<void *>(reinterpret_cast<const void *>(securityDomain)), securityDomainLength));
492
493 item->setAttribute(Schema::attributeInfo(kSecPortItemAttr), UInt32(port));
494 item->setAttribute(Schema::attributeInfo(kSecProtocolItemAttr), protocol);
495 item->setAttribute(Schema::attributeInfo(kSecAuthenticationTypeItemAttr), authenticationType);
496
497 if (path && pathLength)
498 item->setAttribute(Schema::attributeInfo(kSecPathItemAttr),
499 CssmData(const_cast<void *>(reinterpret_cast<const void *>(path)), pathLength));
500
501 Keychain keychain = nil;
502 try
503 {
504 keychain = Keychain::optional(keychainRef);
505 if ( !keychain->exists() )
506 {
507 MacOSError::throwMe(errSecNoSuchKeychain); // Might be deleted or not available at this time.
508 }
509 }
510 catch(...)
511 {
512 keychain = globals().storageManager.defaultKeychainUI(item);
513 }
514
515 keychain->add(item);
516
517 if (itemRef)
518 *itemRef = item->handle();
519
520 END_SECAPI
521 }
522
523
524 OSStatus
525 SecKeychainFindInternetPassword(CFTypeRef keychainOrArray, UInt32 serverNameLength, const char *serverName, UInt32 securityDomainLength, const char *securityDomain, UInt32 accountNameLength, const char *accountName, UInt32 pathLength, const char *path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef)
526
527 {
528 BEGIN_SECAPI
529
530 secdebug("kc", "SecKeychainFindInternetPassword(%p)", keychainOrArray);
531 StorageManager::KeychainList keychains;
532 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
533 KCCursor cursor(keychains, kSecInternetPasswordItemClass, NULL);
534
535 if (serverName && serverNameLength)
536 {
537 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServerItemAttr),
538 CssmData(const_cast<char *>(serverName), serverNameLength));
539 }
540
541 if (securityDomain && securityDomainLength)
542 {
543 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecSecurityDomainItemAttr),
544 CssmData (const_cast<char*>(securityDomain), securityDomainLength));
545 }
546
547 if (accountName && accountNameLength)
548 {
549 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecAccountItemAttr),
550 CssmData (const_cast<char*>(accountName), accountNameLength));
551 }
552
553 if (port)
554 {
555 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecPortItemAttr),
556 UInt32(port));
557 }
558
559 if (protocol)
560 {
561 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecProtocolItemAttr),
562 protocol);
563 }
564
565 if (authenticationType)
566 {
567 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecAuthenticationTypeItemAttr),
568 authenticationType);
569 }
570
571 if (path && pathLength)
572 {
573 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecPathItemAttr), path);
574 }
575
576 Item item;
577 if (!cursor->next(item))
578 return errSecItemNotFound;
579
580 // Get its data (only if necessary)
581 if (passwordData || passwordLength)
582 {
583 CssmDataContainer outData;
584 item->getData(outData);
585 *passwordLength=outData.length();
586 outData.Length=0;
587 *passwordData=outData.data();
588 outData.Data=NULL;
589 }
590
591 if (itemRef)
592 *itemRef=item->handle();
593
594 END_SECAPI
595 }
596
597
598 OSStatus
599 SecKeychainAddGenericPassword(SecKeychainRef keychainRef, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef)
600 {
601 BEGIN_SECAPI
602
603 secdebug("kc", "SecKeychainAddGenericPassword(%p)", keychainRef);
604 KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL);
605 // @@@ Get real itemClass
606 Item item(kSecGenericPasswordItemClass, 'aapl', passwordLength, passwordData);
607
608 if (serviceName && serviceNameLength)
609 {
610 CssmData service(const_cast<void *>(reinterpret_cast<const void *>(serviceName)), serviceNameLength);
611 item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), service);
612 // use service name as default label
613 item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), service);
614 }
615
616 if (accountName && accountNameLength)
617 {
618 CssmData account(const_cast<void *>(reinterpret_cast<const void *>(accountName)), accountNameLength);
619 item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
620 }
621
622 Keychain keychain = nil;
623 try
624 {
625 keychain = Keychain::optional(keychainRef);
626 if ( !keychain->exists() )
627 {
628 MacOSError::throwMe(errSecNoSuchKeychain); // Might be deleted or not available at this time.
629 }
630 }
631 catch(...)
632 {
633 keychain = globals().storageManager.defaultKeychainUI(item);
634 }
635
636 keychain->add(item);
637 if (itemRef)
638 *itemRef = item->handle();
639
640 END_SECAPI
641 }
642
643
644 OSStatus
645 SecKeychainFindGenericPassword(CFTypeRef keychainOrArray, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef)
646
647 {
648 Debug::trace (kSecTraceSecurityFrameworkSecKeychainFindGenericPasswordBegin);
649
650 BEGIN_SECAPI
651
652 secdebug("kc", "SecKeychainFindGenericPassword(%p)", keychainOrArray);
653 StorageManager::KeychainList keychains;
654 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
655 KCCursor cursor(keychains, kSecGenericPasswordItemClass, NULL);
656
657 if (serviceName && serviceNameLength)
658 {
659 cursor->add (CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr),
660 const_cast<char*>(serviceName));
661 }
662
663 if (accountName && accountNameLength)
664 {
665 cursor->add (CSSM_DB_EQUAL, Schema::attributeInfo(kSecAccountItemAttr),
666 const_cast<char*>(accountName));
667 }
668
669 Item item;
670 if (!cursor->next(item))
671 return errSecItemNotFound;
672
673 // Get its data (only if necessary)
674 if (passwordData || passwordLength)
675 {
676 CssmDataContainer outData;
677 item->getData(outData);
678 *passwordLength=outData.length();
679 outData.Length=0;
680 *passwordData=outData.data();
681 outData.Data=NULL;
682 }
683
684 if (itemRef)
685 *itemRef=item->handle();
686
687 END_SECAPI
688 }
689
690
691 OSStatus
692 SecKeychainSetUserInteractionAllowed(Boolean state)
693 {
694 BEGIN_SECAPI
695
696 secdebug("kc", "SecKeychainSetUserInteractionAllowed(%d)", state);
697 globals().setUserInteractionAllowed(state);
698
699 END_SECAPI
700 }
701
702
703 OSStatus
704 SecKeychainGetUserInteractionAllowed(Boolean *state)
705 {
706 BEGIN_SECAPI
707
708 secdebug("kc", "SecKeychainGetUserInteractionAllowed()");
709 Required(state)=globals().getUserInteractionAllowed();
710
711 END_SECAPI
712 }
713
714
715 OSStatus
716 SecKeychainGetDLDBHandle(SecKeychainRef keychainRef, CSSM_DL_DB_HANDLE *dldbHandle)
717 {
718 BEGIN_SECAPI
719
720 secdebug("kc", "SecKeychainGetDLDBHandle(%p, %p)", keychainRef, dldbHandle);
721 RequiredParam(dldbHandle);
722
723 Keychain keychain = Keychain::optional(keychainRef);
724 *dldbHandle = keychain->database()->handle();
725
726 END_SECAPI
727 }
728
729
730 OSStatus
731 SecKeychainGetCSPHandle(SecKeychainRef keychainRef, CSSM_CSP_HANDLE *cspHandle)
732 {
733 BEGIN_SECAPI
734
735 secdebug("kc", "SecKeychainGetCSPHandle(%p, %p)", keychainRef, cspHandle);
736 RequiredParam(cspHandle);
737
738 Keychain keychain = Keychain::optional(keychainRef);
739 *cspHandle = keychain->csp()->handle();
740
741 END_SECAPI
742 }
743
744
745 OSStatus
746 SecKeychainCopyAccess(SecKeychainRef keychainRef, SecAccessRef *accessRef)
747 {
748 BEGIN_SECAPI
749
750 secdebug("kc", "SecKeychainCopyAccess(%p, %p)", keychainRef, accessRef);
751 MacOSError::throwMe(unimpErr);//%%%for now
752
753 END_SECAPI
754 }
755
756
757 OSStatus
758 SecKeychainSetAccess(SecKeychainRef keychainRef, SecAccessRef accessRef)
759 {
760 BEGIN_SECAPI
761
762 secdebug("kc", "SecKeychainSetAccess(%p, %p)", keychainRef, accessRef);
763 MacOSError::throwMe(unimpErr);//%%%for now
764
765 END_SECAPI
766 }
767
768
769 #pragma mark ---- Private API ----
770
771
772 OSStatus
773 SecKeychainChangePassword(SecKeychainRef keychainRef, UInt32 oldPasswordLength, const void *oldPassword, UInt32 newPasswordLength, const void *newPassword)
774 {
775 BEGIN_SECAPI
776
777 secdebug("kc", "SecKeychainChangePassword(%p, %lu, %p, %lu, %p)", keychainRef,
778 oldPasswordLength, oldPassword, newPasswordLength, newPassword);
779 Keychain keychain = Keychain::optional(keychainRef);
780 keychain->changePassphrase (oldPasswordLength, oldPassword, newPasswordLength, newPassword);
781
782 END_SECAPI
783 }
784
785
786 OSStatus
787 SecKeychainCopyLogin(SecKeychainRef *keychainRef)
788 {
789 BEGIN_SECAPI
790
791 secdebug("kc", "SecKeychainCopyLogin(%p)", keychainRef);
792 RequiredParam(keychainRef)=globals().storageManager.loginKeychain()->handle();
793
794 END_SECAPI
795 }
796
797
798 OSStatus
799 SecKeychainLogin(UInt32 nameLength, void* name, UInt32 passwordLength, void* password)
800 {
801 BEGIN_SECAPI
802
803 secdebug("kc", "SecKeychainLogin(%lu, %p, %lu, %p)", nameLength, name, passwordLength, password);
804 globals().storageManager.login(nameLength, name, passwordLength, password);
805
806 END_SECAPI
807 }
808
809
810 OSStatus
811 SecKeychainLogout()
812 {
813 BEGIN_SECAPI
814
815 secdebug("kc", "SecKeychainLogout()");
816 globals().storageManager.logout();
817
818 END_SECAPI
819 }
820
821 static CFStringRef copyErrorMessageFromBundle(OSStatus status,CFStringRef tableName);
822
823 // caller MUST release the string, since it is gotten with "CFCopyLocalizedStringFromTableInBundle"
824 // intended use of reserved param is to pass in CFStringRef with name of the Table for lookup
825 // Will look by default in "SecErrorMessages.strings" in the resources of Security.framework.
826
827
828 CFStringRef SecCopyErrorMessageString(OSStatus status, void *reserved)
829 {
830 BEGIN_SECAPI
831
832 return copyErrorMessageFromBundle(status,CFSTR("SecErrorMessages"));
833
834 END_SECAPI1(NULL)
835 }
836
837 CFStringRef copyErrorMessageFromBundle(OSStatus status,CFStringRef tableName)
838 {
839 CFStringRef errorString = nil;
840 CFStringRef keyString = nil;
841 CFURLRef bundleURL = NULL;
842 CFBundleRef secBundle = NULL;
843
844 // Make a CFURLRef from the CFString representation of the bundleƕs path.
845 bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
846 CFSTR("/System/Library/Frameworks/Security.framework/"),kCFURLPOSIXPathStyle,true); // Resources/
847 if (!bundleURL)
848 goto xit;
849
850 // Make a bundle instance using the URLRef.
851 secBundle = CFBundleCreate(kCFAllocatorDefault,bundleURL);
852 if (!secBundle)
853 goto xit;
854
855 // Convert status to Int32 string representation, e.g. "-25924"
856 keyString = CFStringCreateWithFormat (kCFAllocatorDefault,NULL,CFSTR("%d"),status);
857 if (!keyString)
858 goto xit;
859
860 errorString = CFCopyLocalizedStringFromTableInBundle(keyString,tableName,secBundle,NULL);
861
862 xit:
863 if (bundleURL)
864 CFRelease(bundleURL);
865 if (secBundle)
866 CFRelease(secBundle);
867 if (keyString)
868 CFRelease(keyString);
869
870 return errorString;
871 }
872