]> git.saurik.com Git - apple/security.git/blob - securityd/src/localkey.cpp
Security-59754.80.3.tar.gz
[apple/security.git] / securityd / src / localkey.cpp
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>
32 #include <security_utilities/cfmunge.h>
33 #include <security_utilities/logging.h>
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);
44 secinfo("SSkey", "%p (handle %#x) created from key alg=%u use=0x%x attr=0x%x db=%p",
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 {
80 secinfo("SSkey", "%p destroyed", this);
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
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 }
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 }