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#ifndef _ACL_SECRET
29#define _ACL_SECRET
30
31#include <security_cdsa_utilities/cssmdata.h>
32#include <security_cdsa_utilities/cssmacl.h>
33#include <string>
34
35
36namespace Security {
37
38
39//
40// SecretAclSubject implements AclSubjects that perform their validation by
41// passing their secret through some deterministic validation mechanism.
42// As a limiting case, the subject can contain the secret itself and validate
43// by comparing for equality.
44//
45// This is not a fully functional ACL subject. You must subclass it.
46//
47// There are three elements to consider here:
48// (1) How to OBTAIN the secret. This is the job of your subclass; SecretAclSubject
49//     is agnostic (and abstract) in this respect.
50// (2) How to VALIDATE the secret. This is delegated to an environment method,
51//     which gets this very subject passed as an argument for maximum flexibility.
52// (3) Whether to use a locally stored copy of the secret for validation (by equality)
53//     or hand it off to the environment validator. This is fully implemented here.
54// This implementation assumes that the secret, whatever it may be, can be stored
55// as a (flat) data blob and can be compared for bit-wise equality. No other
56// interpretation is required at this level.
57//
58class SecretAclSubject : public SimpleAclSubject {
59public:
60    bool validate(const AclValidationContext &ctx, const TypedList &sample) const;
61
62    SecretAclSubject(Allocator &alloc, CSSM_ACL_SUBJECT_TYPE type, const CssmData &secret);
63    SecretAclSubject(Allocator &alloc, CSSM_ACL_SUBJECT_TYPE type, CssmManagedData &secret);
64	SecretAclSubject(Allocator &alloc, CSSM_ACL_SUBJECT_TYPE type, bool doCache);
65
66	bool haveSecret() const		{ return mSecretValid; }
67	bool cacheSecret() const	{ return mCacheSecret; }
68
69    void secret(const CssmData &secret) const;
70    void secret(CssmManagedData &secret) const;
71
72    Allocator &allocator;
73
74	IFDUMP(void debugDump() const);
75
76public:
77	class Environment : virtual public AclValidationEnvironment {
78	public:
79		virtual bool validateSecret(const SecretAclSubject *me,
80			const AccessCredentials *secret) = 0;
81	};
82
83protected:
84	// implement this to get your secret (somehow)
85	virtual bool getSecret(const AclValidationContext &context,
86		const TypedList &sample, CssmOwnedData &secret) const = 0;
87
88	const CssmData &secret() const { assert(mSecretValid); return mSecret; }
89
90private:
91    mutable CssmAutoData mSecret; // locally known secret
92	mutable bool mSecretValid;	// mSecret is valid
93	bool mCacheSecret;			// cache secret locally and validate from cache
94};
95
96} // end namespace Security
97
98
99#endif //_ACL_SECRET
100