]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cdsa_utilities/lib/acl_secret.cpp
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / libsecurity_cdsa_utilities / lib / acl_secret.cpp
1 /*
2 * Copyright (c) 2000-2004,2006,2011,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 //
26 // acl_secret - secret-validation password ACLs framework.
27 //
28 #include <security_cdsa_utilities/acl_secret.h>
29 #include <security_utilities/trackingallocator.h>
30 #include <security_utilities/debugging.h>
31 #include <security_utilities/endian.h>
32 #include <algorithm>
33
34
35 //
36 // Construct a secret-bearing ACL subject
37 //
38 SecretAclSubject::SecretAclSubject(Allocator &alloc,
39 CSSM_ACL_SUBJECT_TYPE type, const CssmData &password)
40 : SimpleAclSubject(type), allocator(alloc),
41 mSecret(alloc, password), mSecretValid(true), mCacheSecret(false)
42 { }
43
44 SecretAclSubject::SecretAclSubject(Allocator &alloc,
45 CSSM_ACL_SUBJECT_TYPE type, CssmManagedData &password)
46 : SimpleAclSubject(type), allocator(alloc),
47 mSecret(alloc, password), mSecretValid(true), mCacheSecret(false)
48 { }
49
50 SecretAclSubject::SecretAclSubject(Allocator &alloc,
51 CSSM_ACL_SUBJECT_TYPE type, bool doCache)
52 : SimpleAclSubject(type), allocator(alloc),
53 mSecret(alloc), mSecretValid(false), mCacheSecret(doCache)
54 { }
55
56
57 //
58 // Set the secret after creation.
59 //
60 // These are const methods by design, even though they obvious (may) set
61 // a field in the SecretAclSubject. The fields are mutable, following the
62 // general convention that transient state in AclSubjects is mutable.
63 //
64 void SecretAclSubject::secret(const CssmData &s) const
65 {
66 assert(!mSecretValid); // can't re-set it
67 if (mCacheSecret) {
68 mSecret = s;
69 mSecretValid = true;
70 secinfo("aclsecret", "%p secret stored", this);
71 } else
72 secinfo("aclsecret", "%p refused to store secret", this);
73 }
74
75 void SecretAclSubject::secret(CssmManagedData &s) const
76 {
77 assert(!mSecretValid); // can't re-set it
78 if (mCacheSecret) {
79 mSecret = s;
80 mSecretValid = true;
81 secinfo("aclsecret", "%p secret stored", this);
82 } else
83 secinfo("aclsecret", "%p refused to store secret", this);
84 }
85
86
87 //
88 // Validate a secret.
89 // The subclass has to come up with the secret somehow. We just validate it.
90 //
91 bool SecretAclSubject::validates(const AclValidationContext &context,
92 const TypedList &sample) const
93 {
94 CssmAutoData secret(allocator);
95
96 // try to get the secret; fail if we can't
97 if (!getSecret(context, sample, secret))
98 return false;
99
100 // now validate the secret
101 if (mSecretValid) {
102 return mSecret == secret;
103 } else if (Environment *env = context.environment<Environment>()) {
104 TrackingAllocator alloc(Allocator::standard());
105 TypedList data(alloc, type(), new(alloc) ListElement(secret.get()));
106 CssmSample sample(data);
107 AccessCredentials cred((SampleGroup(sample)), context.credTag());
108 return env->validateSecret(this, &cred);
109 } else {
110 return false;
111 }
112 }
113
114
115 #ifdef DEBUGDUMP
116
117 void SecretAclSubject::debugDump() const
118 {
119 if (mSecretValid) {
120 Debug::dump(" ");
121 Debug::dumpData(mSecret.data(), mSecret.length());
122 }
123 if (mCacheSecret)
124 Debug::dump("; CACHING");
125 }
126
127 #endif //DEBUGDUMP