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