1/* 2 * Copyright (c) 2004,2008-2009,2012 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// tempdatabase - temporary (scratch) storage for keys 27// 28#include <security_cdsa_utilities/cssmdata.h> 29#include <security_cdsa_utilities/cssmkey.h> 30#include <security_cdsa_client/wrapkey.h> 31#include "tempdatabase.h" 32#include "localkey.h" 33#include "server.h" 34#include "session.h" 35#include "agentquery.h" 36 37 38// 39// Temporary-space Key objects are almost normal LocalKeys, with the key 40// matter always preloaded (and thus no deferral of instantiation). 41// A TempKey bears its own ACL. 42// 43class TempKey : public LocalKey, public SecurityServerAcl { 44public: 45 TempKey(Database &db, const CssmKey &newKey, uint32 moreAttributes, 46 const AclEntryPrototype *owner = NULL); 47 48 Database *relatedDatabase(); 49 50 SecurityServerAcl &acl() { return *this; } 51 52public: 53 // SecurityServerAcl personality 54 AclKind aclKind() const; 55}; 56 57 58TempKey::TempKey(Database &db, const CssmKey &newKey, uint32 moreAttributes, 59 const AclEntryPrototype *owner) 60 : LocalKey(db, newKey, moreAttributes) 61{ 62 setOwner(owner); 63 db.addReference(*this); 64} 65 66 67AclKind TempKey::aclKind() const 68{ 69 return keyAcl; 70} 71 72 73Database *TempKey::relatedDatabase() 74{ 75 return NULL; 76} 77 78 79// 80// Create a Database object from initial parameters (create operation) 81// 82TempDatabase::TempDatabase(Process &proc) 83 : LocalDatabase(proc) 84{ 85 proc.addReference(*this); 86} 87 88 89// 90// A LocalDatabase itself doesn't really have a database name, 91// but here's an innocent placeholder. 92// 93const char *TempDatabase::dbName() const 94{ 95 return "(transient)"; 96} 97 98bool TempDatabase::transient() const 99{ 100 return true; 101} 102 103 104// 105// Invoke the Security Agent to get a passphrase (other than for a Keychain) 106// 107void TempDatabase::getSecurePassphrase(const Context &context, 108 string &passphrase) 109{ 110 uint32 verify = context.getInt(CSSM_ATTRIBUTE_VERIFY_PASSPHRASE, CSSMERR_CSSM_ATTRIBUTE_NOT_IN_CONTEXT); 111 112 CssmData *promptData = context.get<CssmData>(CSSM_ATTRIBUTE_PROMPT); 113 114 QueryGenericPassphrase agentQuery; 115 agentQuery.inferHints(Server::process()); 116 agentQuery(promptData, verify, passphrase); 117} 118 119 120void TempDatabase::makeSecurePassphraseKey(const Context &context, 121 const AccessCredentials *cred, 122 const AclEntryPrototype *owner, 123 uint32 usage, uint32 attrs, 124 RefPointer<Key> &newKey) 125{ 126 secdebug("SSdb", "requesting secure passphrase"); 127 128 string passphrase; 129 getSecurePassphrase(context, passphrase); 130 131 secdebug("SSdb", "wrapping securely-obtained passphrase as key"); 132 133 // CssmKey rawKey(StringData(passphrase)) confuses gcc 134 StringData passphraseData(passphrase); 135 CssmKey rawKey(passphraseData); 136 rawKey.algorithm(context.algorithm()); 137 rawKey.blobType(CSSM_KEYBLOB_RAW); 138 rawKey.blobFormat(CSSM_KEYBLOB_WRAPPED_FORMAT_NONE); 139 rawKey.keyClass(CSSM_KEYCLASS_SESSION_KEY); 140 141 CssmClient::UnwrapKey unwrap(Server::csp(), CSSM_ALGID_NONE); 142 CssmKey cspKey; 143 unwrap(rawKey, TempKey::KeySpec(usage, attrs), cspKey); 144 145 newKey = makeKey(cspKey, attrs & TempKey::managedAttributes, owner); 146} 147 148 149// 150// Obtain "secure passphrases" for the CSP. Useful for PKCS 12. 151// 152void TempDatabase::generateKey(const Context &context, 153 const AccessCredentials *cred, 154 const AclEntryPrototype *owner, 155 uint32 usage, uint32 attrs, 156 RefPointer<Key> &newKey) 157{ 158 switch (context.algorithm()) 159 { 160 case CSSM_ALGID_SECURE_PASSPHRASE: 161 makeSecurePassphraseKey(context, cred, owner, usage, attrs, newKey); 162 break; 163 default: 164 LocalDatabase::generateKey(context, cred, owner, usage, attrs, newKey); 165 return; 166 } 167} 168 169 170// 171// Make a new TempKey 172// 173RefPointer<Key> TempDatabase::makeKey(const CssmKey &newKey, 174 uint32 moreAttributes, const AclEntryPrototype *owner) 175{ 176 assert(!newKey.attribute(CSSM_KEYATTR_PERMANENT)); 177 return new TempKey(*this, newKey, moreAttributes, owner); 178} 179