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// 38SecretAclSubject::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 44SecretAclSubject::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 50SecretAclSubject::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// 64void 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 secdebug("aclsecret", "%p secret stored", this); 71 } else 72 secdebug("aclsecret", "%p refused to store secret", this); 73} 74 75void SecretAclSubject::secret(CssmManagedData &s) const 76{ 77 assert(!mSecretValid); // can't re-set it 78 if (mCacheSecret) { 79 mSecret = s; 80 mSecretValid = true; 81 secdebug("aclsecret", "%p secret stored", this); 82 } else 83 secdebug("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// 91bool SecretAclSubject::validate(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 117void 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 128