]> git.saurik.com Git - apple/security.git/blame - Keychain/SecKeychain.cpp
Security-54.1.9.tar.gz
[apple/security.git] / Keychain / SecKeychain.cpp
CommitLineData
29654253
A
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/cssmdata.h>
21#include <Security/KCExceptions.h>
22#include "SecBridge.h"
23#include "CCallbackMgr.h"
24#include "Schema.h"
25
26
27CFTypeID
28SecKeychainGetTypeID(void)
29{
30 BEGIN_SECAPI
31
32 return gTypes().keychain.typeId;
33
34 END_SECAPI1(_kCFRuntimeNotATypeID)
35}
36
37
38OSStatus
39SecKeychainGetVersion(UInt32 *returnVers)
40{
41 if (!returnVers)
42 return noErr;
43
44 *returnVers = 0x02028000;
45 return noErr;
46}
47
48
49OSStatus
50SecKeychainOpen(const char *pathName, SecKeychainRef *keychainRef)
51{
52 BEGIN_SECAPI
53
54 RequiredParam(keychainRef)=gTypes().keychain.handle(*globals().storageManager.make(pathName));
55
56 END_SECAPI
57}
58
59
60OSStatus
61SecKeychainCreate(const char *pathName, UInt32 passwordLength, const void *password,
62 Boolean promptUser, SecAccessRef initialAccess, SecKeychainRef *keychainRef)
63{
64 BEGIN_SECAPI
65
66 KCThrowParamErrIf_(!pathName);
67 Keychain keychain = globals().storageManager.make(pathName);
68
69 // @@@ the call to StorageManager::make above leaves keychain the the cache.
70 // If the create below fails we should probably remove it.
71 if(promptUser)
72 keychain->create();
73 else
74 {
75 KCThrowParamErrIf_(!password);
76 keychain->create(passwordLength, password);
77 }
78 RequiredParam(keychainRef)=gTypes().keychain.handle(*keychain);
79
80 END_SECAPI
81}
82
83
84OSStatus
85SecKeychainDelete(SecKeychainRef keychainOrArray)
86{
87 BEGIN_SECAPI
88
89 StorageManager::KeychainList keychains;
90 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
91 globals().storageManager.remove(keychains, true);
92
93 END_SECAPI
94}
95
96
97OSStatus
98SecKeychainSetSettings(SecKeychainRef keychainRef, const SecKeychainSettings *newSettings)
99{
100 BEGIN_SECAPI
101
102 Keychain keychain = Keychain::optional(keychainRef);
103 if (newSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1)
104 {
105 UInt32 lockInterval=newSettings->lockInterval;
106 bool lockOnSleep=newSettings->lockOnSleep;
107 keychain->setSettings(lockInterval, lockOnSleep);
108 }
109
110 END_SECAPI
111}
112
113
114OSStatus
115SecKeychainCopySettings(SecKeychainRef keychainRef, SecKeychainSettings *outSettings)
116{
117 BEGIN_SECAPI
118
119 Keychain keychain = Keychain::optional(keychainRef);
120 if (outSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1)
121 {
122 UInt32 lockInterval;
123 bool lockOnSleep;
124
125 keychain->getSettings(lockInterval, lockOnSleep);
126 outSettings->lockInterval=lockInterval;
127 outSettings->lockOnSleep=lockOnSleep;
128 }
129
130 END_SECAPI
131}
132
133
134OSStatus
135SecKeychainUnlock(SecKeychainRef keychainRef, UInt32 passwordLength, void *password, Boolean usePassword)
136{
137 BEGIN_SECAPI
138
139 Keychain keychain = Keychain::optional(keychainRef);
140
141 if(usePassword)
142 keychain->unlock(CssmData(password,passwordLength));
143 else
144 keychain->unlock();
145
146 END_SECAPI
147}
148
149
150OSStatus
151SecKeychainLock(SecKeychainRef keychainRef)
152{
153 BEGIN_SECAPI
154
155 Keychain keychain = Keychain::optional(keychainRef);
156 keychain->lock();
157
158 END_SECAPI
159}
160
161
162OSStatus
163SecKeychainLockAll(void)
164{
165 BEGIN_SECAPI
166
167 globals().storageManager.lockAll();
168
169 END_SECAPI
170}
171
172
173OSStatus
174SecKeychainCopyDefault(SecKeychainRef *keychainRef)
175{
176 BEGIN_SECAPI
177
178 RequiredParam(keychainRef)=gTypes().keychain.handle(*globals().defaultKeychain.keychain());
179
180 END_SECAPI
181}
182
183
184OSStatus
185SecKeychainSetDefault(SecKeychainRef keychainRef)
186{
187 BEGIN_SECAPI
188
189 globals().defaultKeychain.keychain(Keychain::optional(keychainRef));
190
191 END_SECAPI
192}
193
194OSStatus SecKeychainCopySearchList(CFArrayRef* searchList)
195{
196 BEGIN_SECAPI
197
198 RequiredParam(searchList);
199 StorageManager &smr = globals().storageManager;
200 StorageManager::KeychainList keychainList;
201 smr.getSearchList(keychainList);
202 *searchList = smr.convertFromKeychainList(keychainList);
203
204 END_SECAPI
205}
206
207OSStatus SecKeychainSetSearchList(CFArrayRef searchList)
208{
209 BEGIN_SECAPI
210
211 RequiredParam(searchList);
212 StorageManager &smr = globals().storageManager;
213 StorageManager::KeychainList keychainList;
214 smr.convertToKeychainList(searchList, keychainList);
215 smr.setSearchList(keychainList);
216
217 END_SECAPI
218}
219
220OSStatus
221SecKeychainGetStatus(SecKeychainRef keychainRef, SecKeychainStatus *keychainStatus)
222{
223 BEGIN_SECAPI
224
225 RequiredParam(keychainStatus) = (SecKeychainStatus)Keychain::optional(keychainRef)->status();
226
227 END_SECAPI
228}
229
230
231OSStatus
232SecKeychainGetPath(SecKeychainRef keychainRef, UInt32 * ioPathLength, char *pathName)
233{
234 BEGIN_SECAPI
235
236 RequiredParam(pathName);
237
238 const char *name = Keychain::optional(keychainRef)->name();
239 UInt32 nameLen = strlen(name);
240 if (nameLen+1 > *ioPathLength) // if the client's buffer is too small (including null-termination), throw
241 CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL);
242 strncpy(pathName, name, nameLen);
243 pathName[nameLen] = 0;
244 *ioPathLength = nameLen; // set the length.
245
246 END_SECAPI
247}
248
249
250// @@@ Depricated
251UInt16
252SecKeychainListGetCount(void)
253{
254 BEGIN_SECAPI
255
256 return globals().storageManager.size();
257
258 END_SECAPI1(0)
259}
260
261
262// @@@ Depricated
263OSStatus
264SecKeychainListCopyKeychainAtIndex(UInt16 index, SecKeychainRef *keychainRef)
265{
266 BEGIN_SECAPI
267
268 KeychainCore::StorageManager &smgr=KeychainCore::globals().storageManager;
269 RequiredParam(keychainRef)=gTypes().keychain.handle(*smgr[index]);
270
271 END_SECAPI
272}
273
274
275// @@@ Depricated
276OSStatus
277SecKeychainListRemoveKeychain(SecKeychainRef *keychainRef)
278{
279 BEGIN_SECAPI
280
281 Required(keychainRef);
282 Keychain keychain = Keychain::optional(*keychainRef);
283 StorageManager::KeychainList keychainList;
284 keychainList.push_back(keychain);
285 globals().storageManager.remove(keychainList);
286 *keychainRef = NULL;
287
288 END_SECAPI
289}
290
291
292OSStatus
293SecKeychainAttributeInfoForItemID(SecKeychainRef keychainRef, UInt32 itemID, SecKeychainAttributeInfo **info)
294{
295 BEGIN_SECAPI
296
297 Keychain keychain = Keychain::optional(keychainRef);
298 keychain->getAttributeInfoForItemID(itemID, info);
299
300 END_SECAPI
301}
302
303
304OSStatus
305SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info)
306{
307 BEGIN_SECAPI
308
309 KeychainImpl::freeAttributeInfo(info);
310
311 END_SECAPI
312}
313
314
315pascal OSStatus
316SecKeychainAddCallback(SecKeychainCallback callbackFunction, SecKeychainEventMask eventMask, void* userContext)
317{
318 BEGIN_SECAPI
319
320 RequiredParam(callbackFunction);
321 CCallbackMgr::AddCallback(callbackFunction,eventMask,userContext);
322
323 END_SECAPI
324}
325
326
327OSStatus
328SecKeychainRemoveCallback(SecKeychainCallback callbackFunction)
329{
330 BEGIN_SECAPI
331
332 RequiredParam(callbackFunction);
333 CCallbackMgr::RemoveCallback(callbackFunction);
334
335 END_SECAPI
336}
337
338
339OSStatus
340SecKeychainAddInternetPassword(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)
341{
342 BEGIN_SECAPI
343
344 KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL);
345 // @@@ Get real itemClass
346 Item item(kSecInternetPasswordItemClass, 'aapl', passwordLength, passwordData);
347
348 if (serverName && serverNameLength)
349 item->setAttribute(Schema::attributeInfo(kSecServerItemAttr),
350 CssmData(const_cast<void *>(reinterpret_cast<const void *>(serverName)), serverNameLength));
351
352 if (accountName && accountNameLength)
353 {
354 CssmData account(const_cast<void *>(reinterpret_cast<const void *>(accountName)), accountNameLength);
355 item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
356 // @@@ We should probably leave setting of label up to lower level code.
357 item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), account);
358 }
359
360 if (securityDomain && securityDomainLength)
361 item->setAttribute(Schema::attributeInfo(kSecSecurityDomainItemAttr),
362 CssmData(const_cast<void *>(reinterpret_cast<const void *>(securityDomain)), securityDomainLength));
363
364 item->setAttribute(Schema::attributeInfo(kSecPortItemAttr), UInt32(port));
365 item->setAttribute(Schema::attributeInfo(kSecProtocolItemAttr), protocol);
366 item->setAttribute(Schema::attributeInfo(kSecAuthenticationTypeItemAttr), authenticationType);
367
368 if (path && pathLength)
369 item->setAttribute(Schema::attributeInfo(kSecPathItemAttr),
370 CssmData(const_cast<void *>(reinterpret_cast<const void *>(path)), pathLength));
371
372 Keychain::optional(keychainRef)->add(item);
373 if (itemRef)
374 *itemRef = gTypes().item.handle(*item);
375
376 END_SECAPI
377}
378
379
380OSStatus
381SecKeychainFindInternetPassword(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)
382
383{
384 BEGIN_SECAPI
385
386 StorageManager::KeychainList keychains;
387 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
388 KCCursor cursor(keychains, kSecInternetPasswordItemClass, NULL);
389
390 if (serverName && serverNameLength)
391 {
392 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServerItemAttr),
393 CssmData(const_cast<char *>(serverName), serverNameLength));
394 }
395
396 if (securityDomain && securityDomainLength)
397 {
398 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecSecurityDomainItemAttr),
399 CssmData (const_cast<char*>(securityDomain), securityDomainLength));
400 }
401
402 if (accountName && accountNameLength)
403 {
404 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecAccountItemAttr),
405 CssmData (const_cast<char*>(accountName), accountNameLength));
406 }
407
408 if (port)
409 {
410 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecPortItemAttr),
411 UInt32(port));
412 }
413
414 if (protocol)
415 {
416 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecProtocolItemAttr),
417 protocol);
418 }
419
420 if (authenticationType)
421 {
422 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecAuthenticationTypeItemAttr),
423 authenticationType);
424 }
425
426 if (path && pathLength)
427 {
428 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecPathItemAttr), path);
429 }
430
431 Item item;
432 if (!cursor->next(item))
433 return errSecItemNotFound;
434
435 // Get its data (only if necessary)
436 if (passwordData || passwordLength)
437 {
438 CssmDataContainer outData;
439 item->getData(outData);
440 *passwordLength=outData.length();
441 outData.Length=0;
442 *passwordData=outData.data();
443 outData.Data=NULL;
444 }
445
446 if (itemRef)
447 *itemRef=gTypes().item.handle(*item);
448
449 END_SECAPI
450}
451
452
453OSStatus
454SecKeychainAddGenericPassword(SecKeychainRef keychainRef, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef)
455
456{
457 BEGIN_SECAPI
458
459 KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL);
460 // @@@ Get real itemClass
461 Item item(kSecGenericPasswordItemClass, 'aapl', passwordLength, passwordData);
462
463 if (serviceName && serviceNameLength)
464 item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), CssmData(const_cast<void *>(reinterpret_cast<const void *>(serviceName)), serviceNameLength));
465
466 if (accountName && accountNameLength)
467 {
468 CssmData account(const_cast<void *>(reinterpret_cast<const void *>(accountName)), accountNameLength);
469 item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
470 // @@@ We should probably leave setting of label up to lower level code.
471 item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), account);
472 }
473
474 Keychain::optional(keychainRef)->add(item);
475 if (itemRef)
476 *itemRef = gTypes().item.handle(*item);
477
478 END_SECAPI
479}
480
481
482OSStatus
483SecKeychainFindGenericPassword(CFTypeRef keychainOrArray, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef)
484
485{
486 BEGIN_SECAPI
487
488 StorageManager::KeychainList keychains;
489 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
490 KCCursor cursor(keychains, kSecGenericPasswordItemClass, NULL);
491
492 if (serviceName && serviceNameLength)
493 {
494 cursor->add (CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr),
495 const_cast<char*>(serviceName));
496 }
497
498 if (accountName && accountNameLength)
499 {
500 cursor->add (CSSM_DB_EQUAL, Schema::attributeInfo(kSecAccountItemAttr),
501 const_cast<char*>(accountName));
502 }
503
504 Item item;
505 if (!cursor->next(item))
506 return errSecItemNotFound;
507
508 // Get its data (only if necessary)
509 if (passwordData || passwordLength)
510 {
511 CssmDataContainer outData;
512 item->getData(outData);
513 *passwordLength=outData.length();
514 outData.Length=0;
515 *passwordData=outData.data();
516 outData.Data=NULL;
517 }
518
519 if (itemRef)
520 *itemRef=gTypes().item.handle(*item);
521
522 END_SECAPI
523}
524
525
526OSStatus
527SecKeychainSetUserInteractionAllowed(Boolean state)
528{
529 BEGIN_SECAPI
530
531 globals().setUserInteractionAllowed(state);
532
533 END_SECAPI
534}
535
536
537OSStatus
538SecKeychainGetUserInteractionAllowed(Boolean *state)
539{
540 BEGIN_SECAPI
541
542 Required(state)=globals().getUserInteractionAllowed();
543
544 END_SECAPI
545}
546
547
548OSStatus
549SecKeychainGetDLDBHandle(SecKeychainRef keychainRef, CSSM_DL_DB_HANDLE *dldbHandle)
550{
551 BEGIN_SECAPI
552
553 RequiredParam(dldbHandle);
554
555 Keychain keychain = Keychain::optional(keychainRef);
556 *dldbHandle = keychain->database()->handle();
557
558 END_SECAPI
559}
560
561
562OSStatus
563SecKeychainGetCSPHandle(SecKeychainRef keychainRef, CSSM_CSP_HANDLE *cspHandle)
564{
565 BEGIN_SECAPI
566
567 RequiredParam(cspHandle);
568
569 Keychain keychain = Keychain::optional(keychainRef);
570 *cspHandle = keychain->csp()->handle();
571
572 END_SECAPI
573}
574
575
576OSStatus
577SecKeychainCopyAccess(SecKeychainRef keychainRef, SecAccessRef *accessRef)
578{
579 BEGIN_SECAPI
580
581 MacOSError::throwMe(unimpErr);//%%%for now
582
583 END_SECAPI
584}
585
586
587OSStatus
588SecKeychainSetAccess(SecKeychainRef keychainRef, SecAccessRef accessRef)
589{
590 BEGIN_SECAPI
591
592 MacOSError::throwMe(unimpErr);//%%%for now
593
594 END_SECAPI
595}
596
597
598#pragma mark ---- Private API ----
599
600
601OSStatus
602SecKeychainChangePassword(SecKeychainRef keychainRef, UInt32 oldPasswordLength, const void *oldPassword, UInt32 newPasswordLength, const void *newPassword)
603{
604 BEGIN_SECAPI
605
606 Keychain keychain = Keychain::optional(keychainRef);
607 keychain->changePassphrase (oldPasswordLength, oldPassword, newPasswordLength, newPassword);
608
609 END_SECAPI
610}
611
612
613OSStatus
614SecKeychainCopyLogin(SecKeychainRef *keychainRef)
615{
616 BEGIN_SECAPI
617
618 // NOTE: operates on default Keychain! It shouldn't... we want to
619 // have code that operates of a login keychain.
620 RequiredParam(keychainRef)=gTypes().keychain.handle(*globals().defaultKeychain.keychain());
621
622 END_SECAPI
623}
624
625
626OSStatus
627SecKeychainLogin(UInt32 nameLength, void* name, UInt32 passwordLength, void* password)
628{
629 BEGIN_SECAPI
630
631 globals().storageManager.login(nameLength, name, passwordLength, password);
632
633 END_SECAPI
634}
635
636
637OSStatus
638SecKeychainLogout()
639{
640 BEGIN_SECAPI
641
642 globals().storageManager.logout();
643
644 END_SECAPI
645}