1/*
2 * Copyright (c) 2005 Apple Computer, 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 * TrustSettings.h - class to manage trusted certs.
26 */
27
28#ifndef	_TRUST_SETTINGS_H_
29#define _TRUST_SETTINGS_H_
30
31#include "SecTrust.h"
32#include <security_keychain/StorageManager.h>
33#include <security_keychain/SecTrustSettings.h>
34
35/*
36 * Clarification of the bool arguments to our main constructor.
37 */
38#define CREATE_YES	true
39#define CREATE_NO	false
40#define TRIM_YES	true
41#define TRIM_NO		false
42
43namespace Security
44{
45
46namespace KeychainCore
47{
48
49/*
50 * Additional values for the SecTrustSettingsDomain enum.
51 */
52enum {
53	/*
54	 * This indicates a TrustSettings that exists only in memory; it
55	 * can't be written to disk.
56	 */
57	kSecTrustSettingsDomainMemory = 100
58};
59
60class TrustSettings
61{
62private:
63	TrustSettings(SecTrustSettingsDomain domain);
64
65public:
66
67	/*
68	 * Normal constructor, from disk.
69	 * If create is true, the absence of an on-disk TrustSettings file
70	 * results in the creation of a new empty TrustSettings. If create is
71	 * false and no on-disk TrustSettings exists, errSecItemNotFound is
72	 * thrown.
73	 * If trim is true, the components of the on-disk TrustSettings not
74	 * needed for cert evaluation are discarded. This is for TrustSettings
75	 * that will be cached in memory long-term.
76	 */
77	static OSStatus CreateTrustSettings(
78		SecTrustSettingsDomain				domain,
79		bool								create,
80		bool								trim,
81		TrustSettings*&						ts);
82
83	/*
84	 * Create from external data, obtained by createExternal().
85	 * If externalData is NULL, we'll create an empty mTrustDict.
86	 */
87	static OSStatus CreateTrustSettings(
88		SecTrustSettingsDomain				domain,
89		CFDataRef							externalData,
90		TrustSettings*&						ts);
91
92	~TrustSettings();
93
94	/*
95	 * Evaluate specified cert. Returns true if we found a matching
96 	 * record for the cert.
97	 */
98	bool evaluateCert(
99		CFStringRef				certHashStr,
100		const CSSM_OID			*policyOID,			/* optional */
101		const char				*policyString,		/* optional */
102		SecTrustSettingsKeyUsage keyUsage,			/* optional */
103		bool					isRootCert,			/* for checking default setting */
104		CSSM_RETURN				**allowedErrors,	/* mallocd and RETURNED */
105		uint32					*numAllowedErrors,	/* RETURNED */
106		SecTrustSettingsResult	*resultType,		/* RETURNED */
107		bool					*foundAnyEntry);	/* RETURNED - there is SOME entry for
108													 *   this cert */
109
110	/*
111	 * Only certs with a SecTrustSettingsResult of kSecTrustSettingsResultTrustRoot
112	 * or kSecTrustSettingsResultTrustAsRoot will be returned.
113	 */
114	void findQualifiedCerts(
115		StorageManager::KeychainList	&keychains,
116		/*
117		 * If findAll is true, all certs are returned and the subsequent
118		 * qualifiers are ignored
119		 */
120		bool							findAll,
121		/* if true, only return root (self-signed) certs */
122		bool							onlyRoots,
123		const CSSM_OID					*policyOID,		/* optional */
124		const char						*policyString,	/* optional */
125		SecTrustSettingsKeyUsage		keyUsage,		/* optional */
126		CFMutableArrayRef				certArray);		/* certs appended here */
127
128	/*
129	 * Find all certs in specified keychain list which have entries in this trust record.
130	 * Certs already in the array are not added.
131	 */
132	void findCerts(
133		StorageManager::KeychainList	&keychains,
134		CFMutableArrayRef				certArray);
135
136	/*
137	 * Obtain trust settings for the specified cert. Returned settings array
138	 * is in the public API form; caller must release. Returns NULL
139	 * (does not throw) if the cert is not present in this TrustRecord.
140 	 * The certRef argument can be kSecTrustSettingsDefaultRootCertSetting.
141	 */
142	CFArrayRef copyTrustSettings(
143		SecCertificateRef	certRef);
144
145	/*
146 	 * Obtain the mod date for the specified cert's trust settings.
147     * Returns NULL (does not throw) if the cert is not present in this
148	 * TrustRecord.
149 	 * The certRef argument can be kSecTrustSettingsDefaultRootCertSetting.
150	 */
151	CFDateRef copyModDate(
152		SecCertificateRef	certRef);
153
154	/*
155	 * Modify cert's trust settings, or add a new cert to the record.
156 	 * The certRef argument can be kSecTrustSettingsDefaultRootCertSetting.
157	 */
158	void setTrustSettings(
159		SecCertificateRef	certRef,
160		CFTypeRef			trustSettingsDictOrArray);
161
162	/*
163	 * Delete a certificate's trust settings.
164	 * Throws errSecItemNotFound if there currently are no settings.
165 	 * The certRef argument can be kSecTrustSettingsDefaultRootCertSetting.
166	 */
167	void deleteTrustSettings(
168		SecCertificateRef	certRef);
169
170	/*
171	 * Flush property list data out to disk if dirty.
172	 */
173	void flushToDisk();
174
175	/*
176	 * Obtain external representation of TrustSettings data.
177	 */
178	CFDataRef createExternal();
179
180private:
181	/* common code to init mPropList from raw data */
182	void initFromData(
183		CFDataRef			trustSettingsData);
184
185	/*
186	 * Find a given cert's entry in mTrustDict.
187	 * Returned dictionary is not refcounted.
188	 */
189	CFDictionaryRef findDictionaryForCert(
190		SecCertificateRef	certRef);
191
192	/*
193	 * Find entry in mTrustDict given cert hash string.
194	 */
195	CFDictionaryRef findDictionaryForCertHash(
196		CFStringRef		certHashStr);
197
198	/*
199	 * Validate incoming API-style trust settings, which may be NULL, a
200	 * dictionary, or an array of dictionaries. We return a deep-copied,
201	 * refcounted CFArray, in internal format, in any case as long as the
202	 * incoming parameter is good.
203	 */
204	CFArrayRef validateApiTrustSettings(
205		CFTypeRef trustSettingsDictOrArray,
206		Boolean isSelfSigned);
207
208	/*
209	 * Validate an usage constraint array from disk as part of our mPropDict
210	 * array. Returns true if OK, else returns false.
211	 */
212	bool validateTrustSettingsArray(
213		CFArrayRef trustSettings);
214
215	/*
216	 * Obtain issuer and serial number for specified cert, both
217	 * returned as CFDataRefs owned by caller.
218	 */
219	void copyIssuerAndSerial(
220		SecCertificateRef	cert,
221		CFDataRef			*issuer,		/* optional, RETURNED */
222		CFDataRef			*serial);		/* RETURNED */
223
224	/*
225	 * Validate mPropDict after it's read from disk. Allows subsequent use of
226	 * mPropDict and mTrustDict to proceed with relative impunity.
227	 * If trim is true, we remove fields in the per-cert dictionaries which
228	 * are not needed for cert evaluation. We also release the top-level
229 	 * mPropList, which serves as a "this is trimmed" indicator if NULL.
230	 */
231	void validatePropList(bool trim);
232
233	/* fatal error abort */
234	void abort(
235		const char			*why,
236		OSStatus			err);
237
238	/* the overall parsed TrustSettings - may be NULL if this is trimmed */
239	CFMutableDictionaryRef			mPropList;
240
241	/* and the main thing we work with, the dictionary of per-cert trust settings */
242	CFMutableDictionaryRef			mTrustDict;
243
244	/* version number of mPropDict */
245	SInt32							mDictVersion;
246
247	SecTrustSettingsDomain			mDomain;
248	bool							mDirty;		/* we've changed mPropDict since creation */
249};
250
251} /* end namespace KeychainCore */
252
253} /* end namespace Security */
254
255#endif	/* _TRUST_SETTINGS_H_ */
256
257