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// 37LocalKey::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 47LocalKey::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// 56void 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 76LocalKey::~LocalKey() 77{ 78 secdebug("SSkey", "%p destroyed", this); 79} 80 81 82void 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 92LocalDatabase &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// 102CssmClient::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// 116CSSM_KEYATTR_FLAGS LocalKey::attributes() 117{ 118 return mAttributes; 119} 120 121 122// 123// Return a key's handle and header in external form 124// 125void 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// 149const 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// 168void LocalKey::getKey() 169{ 170 assert(false); 171} 172 173void LocalKey::getHeader(CssmKey::Header &) 174{ 175 assert(false); 176} 177 178 179// 180// Form a KeySpec with checking and masking 181// 182LocalKey::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 189LocalKey::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} 195