/ securityd / src / tempdatabase.cpp
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  }