2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // key - representation of SecurityServer key objects
24 #include "xdatabase.h"
25 #include <Security/acl_any.h>
29 // Create a Key object from a database-encoded blob.
30 // Note that this doesn't decode the blob (yet).
32 Key::Key(Database
&db
, const KeyBlob
*blob
)
33 : SecurityServerAcl(keyAcl
, CssmAllocator::standard())
35 // perform basic validation on the incoming blob
37 blob
->validate(CSSMERR_APPLEDL_INVALID_KEY_BLOB
);
38 switch (blob
->version
) {
39 #if defined(COMPAT_OSX_10_0)
40 case blob
->version_MacOS_10_0
:
43 case blob
->version_MacOS_10_1
:
46 CssmError::throwMe(CSSMERR_APPLEDL_INCOMPATIBLE_KEY_BLOB
);
51 mBlob
= blob
->copy(CssmAllocator::standard());
56 debug("SSkey", "%p created from blob version %lx", this, blob
->version
);
61 // Create a Key from an explicit CssmKey.
63 Key::Key(Database
*db
, const CssmKey
&newKey
, uint32 moreAttributes
,
64 const AclEntryPrototype
*owner
)
65 : SecurityServerAcl(keyAcl
, CssmAllocator::standard())
67 if (moreAttributes
& CSSM_KEYATTR_PERMANENT
) {
68 // better have a database to make it permanent in...
70 CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_DL_DB_HANDLE
);
72 // non-permanent; ignore database
81 setup(newKey
, moreAttributes
);
83 // establish initial ACL
85 cssmSetInitial(*owner
);
87 cssmSetInitial(new AnyAclSubject());
88 debug("SSkey", "%p created from key alg=%ld use=0x%lx attr=0x%lx",
89 this, mKey
.algorithm(), mKey
.usage(), mAttributes
);
94 // Set up the CssmKey part of this Key according to instructions.
96 void Key::setup(const CssmKey
&newKey
, uint32 moreAttributes
)
98 CssmKey::Header
&header
= mKey
.header();
101 header
= newKey
.header();
102 mAttributes
= header
.attributes() | moreAttributes
;
104 // apply initial values of derived attributes (these are all in managedAttributes)
105 if (!(mAttributes
& CSSM_KEYATTR_EXTRACTABLE
))
106 mAttributes
|= CSSM_KEYATTR_NEVER_EXTRACTABLE
;
107 if (mAttributes
& CSSM_KEYATTR_SENSITIVE
)
108 mAttributes
|= CSSM_KEYATTR_ALWAYS_SENSITIVE
;
110 // verify internal/external attribute separation
111 assert(!(header
.attributes() & managedAttributes
));
113 // copy key data field @@@ crud - replace after MM reorg
114 mKey
.KeyData
= CssmData(memcpy(malloc(newKey
.length()), newKey
.data(), newKey
.length()), newKey
.length());
120 CssmAllocator::standard().free(mBlob
);
122 Server::csp()->freeKey(mKey
);
123 debug("SSkey", "%p destroyed", this);
128 // Retrieve the actual CssmKey value for the key object.
129 // This will decode its blob if needed (and appropriate).
131 CssmKey
&Key::keyValue()
139 // Ensure that a key is fully decoded.
140 // This makes the mKey key value available for use, as well as its ACL.
145 assert(mDatabase
); // have to have a database (to decode the blob)
146 assert(mValidBlob
); // must have a blob to decode
149 void *publicAcl
, *privateAcl
;
150 database()->decodeKey(mBlob
, mKey
, publicAcl
, privateAcl
);
151 importBlob(publicAcl
, privateAcl
);
152 // publicAcl points into the blob; privateAcl was allocated for us
153 CssmAllocator::standard().free(privateAcl
);
155 // extract managed attribute bits
156 mAttributes
= mKey
.attributes() & managedAttributes
;
157 mKey
.clearAttribute(managedAttributes
);
166 // Retrieve the header (only) of a key.
167 // This is taking the clear header from the blob *without* verifying it.
169 CssmKey::Header
&Key::keyHeader()
172 return mKey
.header();
175 return mBlob
->header
;
181 // Return a key's handle and header in external form
183 void Key::returnKey(Handle
&h
, CssmKey::Header
&hdr
)
188 // return header with external attributes merged
190 hdr
.setAttribute(mAttributes
);
195 // Encode a key into a blob.
196 // We'll have to ask our Database to do this - we don't have its keys.
197 // Note that this returns memory we own and keep.
201 if (mDatabase
== NULL
) // can't encode independent keys
202 CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE
);
204 assert(mValidKey
); // must have valid key to encode
205 //@@@ release mBlob memory here
207 // export Key ACL to blob form
208 CssmData pubAcl
, privAcl
;
209 exportBlob(pubAcl
, privAcl
);
211 // assemble external key form
212 CssmKey externalKey
= mKey
;
213 externalKey
.setAttribute(mAttributes
);
215 // encode the key and replace blob
216 KeyBlob
*newBlob
= database()->encodeKey(externalKey
, pubAcl
, privAcl
);
217 CssmAllocator::standard().free(mBlob
);
222 database()->allocator
.free(pubAcl
);
223 database()->allocator
.free(privAcl
);
230 // Return the UID of a key (the hash of its bits)
235 //@@@ calculate UID here
236 memset(&mUID
, 0, sizeof(mUID
));
244 // Intercept ACL change requests and reset blob validity
246 void Key::instantiateAcl()
251 void Key::noticeAclChange()
256 const Database
*Key::relatedDatabase() const
257 { return database(); }