]>
Commit | Line | Data |
---|---|---|
d8f41ccd A |
1 | /* |
2 | * Copyright (c) 2000-2001,2004,2006-2008 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 | // localkey - Key objects that store a local CSSM key object | |
27 | // | |
28 | #include "localkey.h" | |
29 | #include "server.h" | |
30 | #include "database.h" | |
31 | #include <security_cdsa_utilities/acl_any.h> | |
e3d460c9 A |
32 | #include <security_utilities/cfmunge.h> |
33 | #include <security_utilities/logging.h> | |
d8f41ccd A |
34 | |
35 | ||
36 | // | |
37 | // Create a Key from an explicit CssmKey. | |
38 | // | |
39 | LocalKey::LocalKey(Database &db, const CssmKey &newKey, CSSM_KEYATTR_FLAGS moreAttributes) | |
40 | : Key(db), mDigest(Server::csp().allocator()) | |
41 | { | |
42 | mValidKey = true; | |
43 | setup(newKey, moreAttributes); | |
fa7225c8 | 44 | secinfo("SSkey", "%p (handle %#x) created from key alg=%u use=0x%x attr=0x%x db=%p", |
d8f41ccd A |
45 | this, handle(), mKey.header().algorithm(), mKey.header().usage(), mAttributes, &db); |
46 | } | |
47 | ||
48 | ||
49 | LocalKey::LocalKey(Database &db, CSSM_KEYATTR_FLAGS attributes) | |
50 | : Key(db), mValidKey(false), mAttributes(attributes), mDigest(Server::csp().allocator()) | |
51 | { | |
52 | } | |
53 | ||
54 | ||
55 | // | |
56 | // Set up the CssmKey part of this Key according to instructions. | |
57 | // | |
58 | void LocalKey::setup(const CssmKey &newKey, CSSM_KEYATTR_FLAGS moreAttributes) | |
59 | { | |
60 | mKey = CssmClient::Key(Server::csp(), newKey, false); | |
61 | CssmKey::Header &header = mKey->header(); | |
62 | ||
63 | // copy key header | |
64 | header = newKey.header(); | |
65 | mAttributes = (header.attributes() & ~forcedAttributes) | moreAttributes; | |
66 | ||
67 | // apply initial values of derived attributes (these are all in managedAttributes) | |
68 | if (!(mAttributes & CSSM_KEYATTR_EXTRACTABLE)) | |
69 | mAttributes |= CSSM_KEYATTR_NEVER_EXTRACTABLE; | |
70 | if (mAttributes & CSSM_KEYATTR_SENSITIVE) | |
71 | mAttributes |= CSSM_KEYATTR_ALWAYS_SENSITIVE; | |
72 | ||
73 | // verify internal/external attribute separation | |
74 | assert((header.attributes() & managedAttributes) == forcedAttributes); | |
75 | } | |
76 | ||
77 | ||
78 | LocalKey::~LocalKey() | |
79 | { | |
fa7225c8 | 80 | secinfo("SSkey", "%p destroyed", this); |
d8f41ccd A |
81 | } |
82 | ||
83 | ||
84 | void LocalKey::setOwner(const AclEntryPrototype *owner) | |
85 | { | |
86 | // establish initial ACL; reinterpret empty (null-list) owner as NULL for resilence's sake | |
87 | if (owner && !owner->subject().empty()) | |
88 | acl().cssmSetInitial(*owner); // specified | |
89 | else | |
90 | acl().cssmSetInitial(new AnyAclSubject()); // defaulted | |
e3d460c9 A |
91 | |
92 | if (this->database().dbVersion() >= CommonBlob::version_partition) { | |
93 | // put payload into an AclEntry tagged as CSSM_APPLE_ACL_TAG_PARTITION_ID... | |
94 | // ... unless the client has the "converter" entitlement as attested by Apple | |
95 | if (!(process().checkAppleSigned() && process().hasEntitlement(migrationEntitlement))) | |
96 | this->acl().createClientPartitionID(this->process()); | |
97 | } | |
d8f41ccd A |
98 | } |
99 | ||
100 | ||
101 | LocalDatabase &LocalKey::database() const | |
102 | { | |
103 | return referent<LocalDatabase>(); | |
104 | } | |
105 | ||
106 | ||
107 | // | |
108 | // Retrieve the actual CssmKey value for the key object. | |
109 | // This will decode its blob if needed (and appropriate). | |
110 | // | |
111 | CssmClient::Key LocalKey::keyValue() | |
112 | { | |
113 | StLock<Mutex> _(*this); | |
114 | if (!mValidKey) { | |
115 | getKey(); | |
116 | mValidKey = true; | |
117 | } | |
118 | return mKey; | |
119 | } | |
120 | ||
121 | ||
122 | // | |
123 | // Return external key attributees | |
124 | // | |
125 | CSSM_KEYATTR_FLAGS LocalKey::attributes() | |
126 | { | |
127 | return mAttributes; | |
128 | } | |
129 | ||
130 | ||
131 | // | |
132 | // Return a key's handle and header in external form | |
133 | // | |
134 | void LocalKey::returnKey(U32HandleObject::Handle &h, CssmKey::Header &hdr) | |
135 | { | |
136 | StLock<Mutex> _(*this); | |
137 | ||
138 | // return handle | |
139 | h = this->handle(); | |
140 | ||
141 | // obtain the key header, from the valid key or the blob if no valid key | |
142 | if (mValidKey) { | |
143 | hdr = mKey.header(); | |
144 | } else { | |
145 | getHeader(hdr); | |
146 | } | |
147 | ||
148 | // adjust for external attributes | |
149 | hdr.clearAttribute(forcedAttributes); | |
150 | hdr.setAttribute(mAttributes); | |
151 | } | |
152 | ||
153 | ||
154 | // | |
155 | // Generate the canonical key digest. | |
156 | // This is defined by a CSP feature that we invoke here. | |
157 | // | |
158 | const CssmData &LocalKey::canonicalDigest() | |
159 | { | |
160 | StLock<Mutex> _(*this); | |
161 | if (!mDigest) { | |
162 | CssmClient::PassThrough ctx(Server::csp()); | |
163 | ctx.key(keyValue()); | |
164 | CssmData *digest = NULL; | |
165 | ctx(CSSM_APPLECSP_KEYDIGEST, (const void *)NULL, &digest); | |
166 | assert(digest); | |
167 | mDigest.set(*digest); // takes ownership of digest data | |
168 | Server::csp().allocator().free(digest); // the CssmData itself | |
169 | } | |
170 | return mDigest.get(); | |
171 | } | |
172 | ||
173 | ||
174 | // | |
175 | // Default getKey/getHeader calls - should never be called | |
176 | // | |
177 | void LocalKey::getKey() | |
178 | { | |
179 | assert(false); | |
180 | } | |
181 | ||
182 | void LocalKey::getHeader(CssmKey::Header &) | |
183 | { | |
184 | assert(false); | |
185 | } | |
186 | ||
187 | ||
188 | // | |
189 | // Form a KeySpec with checking and masking | |
190 | // | |
191 | LocalKey::KeySpec::KeySpec(CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attrs) | |
192 | : CssmClient::KeySpec(usage, (attrs & ~managedAttributes) | forcedAttributes) | |
193 | { | |
194 | if (attrs & generatedAttributes) | |
195 | CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK); | |
196 | } | |
197 | ||
198 | LocalKey::KeySpec::KeySpec(CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attrs, const CssmData &label) | |
199 | : CssmClient::KeySpec(usage, (attrs & ~managedAttributes) | forcedAttributes, label) | |
200 | { | |
201 | if (attrs & generatedAttributes) | |
202 | CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK); | |
203 | } |