tempdatabase.cpp
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 // 43 class TempKey : public LocalKey, public SecurityServerAcl { 44 public: 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 52 public: 53 // SecurityServerAcl personality 54 AclKind aclKind() const; 55 }; 56 57 58 TempKey::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 67 AclKind TempKey::aclKind() const 68 { 69 return keyAcl; 70 } 71 72 73 Database *TempKey::relatedDatabase() 74 { 75 return NULL; 76 } 77 78 79 // 80 // Create a Database object from initial parameters (create operation) 81 // 82 TempDatabase::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 // 93 const char *TempDatabase::dbName() const 94 { 95 return "(transient)"; 96 } 97 98 // 99 // A TempDatabase doesn't have a common object or a version, really, so overload the function to return some base version 100 // 101 uint32 TempDatabase::dbVersion() { 102 return CommonBlob::version_MacOS_10_0; 103 } 104 105 bool TempDatabase::transient() const 106 { 107 return true; 108 } 109 110 111 // 112 // Invoke the Security Agent to get a passphrase (other than for a Keychain) 113 // 114 void TempDatabase::getSecurePassphrase(const Context &context, 115 string &passphrase) 116 { 117 uint32 verify = context.getInt(CSSM_ATTRIBUTE_VERIFY_PASSPHRASE, CSSMERR_CSSM_ATTRIBUTE_NOT_IN_CONTEXT); 118 119 CssmData *promptData = context.get<CssmData>(CSSM_ATTRIBUTE_PROMPT); 120 121 QueryGenericPassphrase agentQuery; 122 agentQuery.inferHints(Server::process()); 123 agentQuery(promptData, verify, passphrase); 124 } 125 126 127 void TempDatabase::makeSecurePassphraseKey(const Context &context, 128 const AccessCredentials *cred, 129 const AclEntryPrototype *owner, 130 uint32 usage, uint32 attrs, 131 RefPointer<Key> &newKey) 132 { 133 secinfo("SSdb", "requesting secure passphrase"); 134 135 string passphrase; 136 getSecurePassphrase(context, passphrase); 137 138 secinfo("SSdb", "wrapping securely-obtained passphrase as key"); 139 140 // CssmKey rawKey(StringData(passphrase)) confuses gcc 141 StringData passphraseData(passphrase); 142 CssmKey rawKey(passphraseData); 143 rawKey.algorithm(context.algorithm()); 144 rawKey.blobType(CSSM_KEYBLOB_RAW); 145 rawKey.blobFormat(CSSM_KEYBLOB_WRAPPED_FORMAT_NONE); 146 rawKey.keyClass(CSSM_KEYCLASS_SESSION_KEY); 147 148 CssmClient::UnwrapKey unwrap(Server::csp(), CSSM_ALGID_NONE); 149 CssmKey cspKey; 150 unwrap(rawKey, TempKey::KeySpec(usage, attrs), cspKey); 151 152 newKey = makeKey(cspKey, attrs & TempKey::managedAttributes, owner); 153 } 154 155 156 // 157 // Obtain "secure passphrases" for the CSP. Useful for PKCS 12. 158 // 159 void TempDatabase::generateKey(const Context &context, 160 const AccessCredentials *cred, 161 const AclEntryPrototype *owner, 162 uint32 usage, uint32 attrs, 163 RefPointer<Key> &newKey) 164 { 165 switch (context.algorithm()) 166 { 167 case CSSM_ALGID_SECURE_PASSPHRASE: 168 makeSecurePassphraseKey(context, cred, owner, usage, attrs, newKey); 169 break; 170 default: 171 LocalDatabase::generateKey(context, cred, owner, usage, attrs, newKey); 172 return; 173 } 174 } 175 176 177 // 178 // Make a new TempKey 179 // 180 RefPointer<Key> TempDatabase::makeKey(const CssmKey &newKey, 181 uint32 moreAttributes, const AclEntryPrototype *owner) 182 { 183 assert(!newKey.attribute(CSSM_KEYATTR_PERMANENT)); 184 return new TempKey(*this, newKey, moreAttributes, owner); 185 }