]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/lib/Password.cpp
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / lib / Password.cpp
1 /*
2 * Copyright (c) 2002-2004,2011-2012,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 //
25 // Password.cpp
26 //
27 #include "Password.h"
28 #include <Security/SecBase.h>
29 #include "SecBridge.h"
30
31 #include "KCCursor.h"
32
33 using namespace KeychainCore;
34 using namespace CssmClient;
35
36 PasswordImpl::PasswordImpl(SecItemClass itemClass, SecKeychainAttributeList *searchAttrList, SecKeychainAttributeList *itemAttrList) :
37 mItem(itemClass, itemAttrList, 0, NULL), mUseKeychain(false), mFoundInKeychain(false), mRememberInKeychain(false), mMutex(Mutex::recursive)
38 {
39 if (searchAttrList && itemAttrList)
40 {
41 mUseKeychain = true;
42 mKeychain = Keychain::optional(NULL);
43 mRememberInKeychain = true;
44
45 // initialize mFoundInKeychain to true if mItem is found
46
47 StorageManager::KeychainList keychains;
48 globals().storageManager.optionalSearchList(NULL, keychains);
49 KCCursor cursor(keychains, itemClass, searchAttrList);
50
51 if (cursor->next(mItem))
52 mFoundInKeychain = true;
53 }
54 }
55
56 PasswordImpl::PasswordImpl(PasswordImpl& existing)
57 {
58 mKeychain = existing.mKeychain;
59 mItem = existing.mItem;
60 mUseKeychain = existing.mUseKeychain;
61 mFoundInKeychain = existing.mFoundInKeychain;
62 mRememberInKeychain = existing.mRememberInKeychain;
63 }
64
65
66
67 PasswordImpl::~PasswordImpl() _NOEXCEPT
68 {
69 }
70
71 void
72 PasswordImpl::setAccess(Access *access)
73 {
74 // changing an existing ACL is more work than this SPI wants to do
75 if (!mFoundInKeychain)
76 mItem->setAccess(access);
77 }
78
79 void
80 PasswordImpl::setData(UInt32 length, const void *data)
81 {
82 assert(mUseKeychain);
83
84 // do different things based on mFoundInKeychain?
85 mItem->setData(length,data);
86 }
87
88 bool
89 PasswordImpl::getData(UInt32 *length, const void **data)
90 {
91 if (mItem->isPersistent())
92 {
93 // try to retrieve it
94 CssmDataContainer outData;
95 try
96 {
97 mItem->getData(outData);
98 if (length && data)
99 {
100 *length=(uint32)outData.length();
101 outData.Length=0;
102 *data=outData.data();
103 outData.Data=NULL;
104 }
105 return true;
106 }
107 catch (...)
108 {
109 // cancel unlock: CSP_USER_CANCELED
110 // deny rogue app CSP_OPERATION_AUTH_DENIED
111 return false;
112 }
113 }
114 else
115 return false;
116 }
117
118 void
119 PasswordImpl::save()
120 {
121 assert(mUseKeychain);
122
123 if (mFoundInKeychain)
124 {
125 mItem->update();
126 }
127 else
128 {
129 mKeychain->add(mItem);
130
131 // reinitialize mItem now it's on mKeychain
132 mFoundInKeychain = true; // should be set by member that resets mItem
133 }
134 }
135
136 Password::Password(SecItemClass itemClass, SecKeychainAttributeList *searchAttrList, SecKeychainAttributeList *itemAttrList) :
137 SecPointer<PasswordImpl>(new PasswordImpl(itemClass, searchAttrList, itemAttrList))
138 {
139 }
140
141 Password::Password(PasswordImpl *impl) : SecPointer<PasswordImpl>(impl)
142 {
143 }
144
145 Password::Password(PasswordImpl &impl) : SecPointer<PasswordImpl>(new PasswordImpl(impl))
146 {
147 }