securestorage.h
1 /* 2 * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. 3 * 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 8 * using this file. 9 * 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. 16 */ 17 18 19 // 20 // securestorage - client interface to CSP DLs and their operations 21 // 22 #ifndef _H_CDSA_CLIENT_SECURESTORAGE 23 #define _H_CDSA_CLIENT_SECURESTORAGE 1 24 25 #include <security_cdsa_client/cspclient.h> 26 #include <security_cdsa_client/dlclient.h> 27 #include <security_cdsa_client/keyclient.h> 28 29 namespace Security 30 { 31 32 namespace CssmClient 33 { 34 35 // 36 // A CSP and a DL attachment of the same subservice 37 // 38 // This gives us 2 Object instances, but we make sure that have the same 39 // mImpl. Currently this class has no behaviour, but it will get some in 40 // the future. 41 // 42 class CSPDLImpl : public CSPImpl, public DLImpl 43 { 44 public: 45 CSPDLImpl(const Guid &guid); 46 CSPDLImpl(const Module &module); 47 virtual ~CSPDLImpl(); 48 49 // Object methods. 50 bool isActive() const { return CSPImpl::isActive() || DLImpl::isActive(); } 51 52 virtual Allocator &allocator() const; 53 virtual void allocator(Allocator &alloc); 54 55 virtual bool operator <(const CSPDLImpl &other) const; 56 virtual bool operator ==(const CSPDLImpl &other) const; 57 58 // Attachment methods. 59 virtual CSSM_SERVICE_MASK subserviceMask() const; 60 virtual void subserviceId(uint32 id); 61 62 uint32 subserviceId() const { return CSPImpl::subserviceId(); } 63 CSSM_ATTACH_FLAGS cspFlags() const { return CSPImpl::flags(); } 64 void cspFlags(CSSM_ATTACH_FLAGS f) { CSPImpl::flags(f); } 65 CSSM_ATTACH_FLAGS dlFlags() const { return DLImpl::flags(); } 66 void dlFlags(CSSM_ATTACH_FLAGS f) { DLImpl::flags(f); } 67 68 void attach() { CSPImpl::attach(); DLImpl::attach(); } 69 void detach() { CSPImpl::detach(); DLImpl::detach(); } 70 bool attached() const { return CSPImpl::attached() || DLImpl::attached(); } 71 72 Module module() const { return CSPImpl::module(); } 73 const Guid &guid() const { return CSPImpl::guid(); } 74 CSSM_MODULE_HANDLE cspHandle() { return CSPImpl::handle(); } 75 CSSM_MODULE_HANDLE dlHandle() { return DLImpl::handle(); } 76 77 CssmSubserviceUid subserviceUid() const 78 { return CSPImpl::subserviceUid(); } 79 80 private: 81 }; 82 83 84 class CSPDL : public CSP, public DL 85 { 86 public: 87 typedef CSPDLImpl Impl; 88 89 explicit CSPDL(Impl *impl) : CSP(impl), DL(impl) {} 90 CSPDL(const Guid &guid) : CSP(new Impl(guid)), DL(&CSP::impl<Impl>()) {} 91 CSPDL(const Module &module) 92 : CSP(new Impl(module)), DL(&CSP::impl<Impl>()) {} 93 94 //template <class _Impl> _Impl &impl() const 95 //{ return CSP::impl<_Impl>(); } 96 97 Impl *get() const { return &CSP::impl<Impl>(); } 98 Impl *operator ->() const { return &CSP::impl<Impl>(); } 99 Impl &operator *() const { return CSP::impl<Impl>(); } 100 101 // Conversion operators must be here 102 bool operator !() const { return !get(); } 103 operator bool() const { return get(); } 104 105 bool operator <(const CSPDL &other) const 106 { return *this && other ? **this < *other : get() < other.get(); } 107 bool operator ==(const CSPDL &other) const 108 { return *this && other ? **this == *other : get() == other.get(); } 109 }; 110 111 112 // 113 // SSCSPDL -- Secure storage class 114 // 115 class SSCSPDLImpl : public CSPDLImpl 116 { 117 public: 118 SSCSPDLImpl(const Guid &guid); 119 SSCSPDLImpl(const Module &module); 120 virtual ~SSCSPDLImpl(); 121 122 // DbMaker 123 DbImpl *newDb(const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation); 124 private: 125 }; 126 127 class SSCSPDL : public CSPDL 128 { 129 public: 130 typedef SSCSPDLImpl Impl; 131 132 explicit SSCSPDL(Impl *impl) : CSPDL(impl) {} 133 SSCSPDL(const Guid &guid) : CSPDL(new Impl(guid)) {} 134 SSCSPDL(const Module &module) : CSPDL(new Impl(module)) {} 135 136 Impl *operator ->() const { return &CSP::impl<Impl>(); } 137 Impl &operator *() const { return CSP::impl<Impl>(); } 138 }; 139 140 141 // 142 // SSDbImpl -- A Security Storage Db object. 143 // 144 class SSGroup; 145 class SSDbUniqueRecord; 146 147 class SSDbImpl : public DbImpl 148 { 149 public: 150 SSDbImpl(const SSCSPDL &cspdl, 151 const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation); 152 virtual ~SSDbImpl(); 153 154 void create(); 155 void open(); 156 157 // This insert is here to explicitly catch calls to DbImpl's insert. You probably want the ssInsert calls below. 158 DbUniqueRecord insert(CSSM_DB_RECORDTYPE recordType, 159 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes, 160 const CSSM_DATA *data); 161 162 SSDbUniqueRecord ssInsert(CSSM_DB_RECORDTYPE recordType, 163 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes, 164 const CSSM_DATA *data, 165 const CSSM_RESOURCE_CONTROL_CONTEXT *rc = NULL); 166 167 SSDbUniqueRecord ssInsert(CSSM_DB_RECORDTYPE recordType, 168 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes, 169 const CSSM_DATA *data, const SSGroup &group, 170 const CSSM_ACCESS_CREDENTIALS *cred); 171 172 // DbCursorMaker 173 DbCursorImpl *newDbCursor(const CSSM_QUERY &query, 174 Allocator &allocator); 175 DbCursorImpl *newDbCursor(uint32 capacity, Allocator &allocator); 176 177 // SSDbUniqueRecordMaker 178 DbUniqueRecordImpl *newDbUniqueRecord(); 179 180 CSP csp() { return parent<CSP>(); } 181 }; 182 183 class SSDb : public Db 184 { 185 public: 186 typedef SSDbImpl Impl; 187 188 explicit SSDb(Impl *impl) : Db(impl) {} 189 SSDb(const SSCSPDL &cspdl, const char *inDbName, 190 const CSSM_NET_ADDRESS *inDbLocation = NULL) 191 : Db(cspdl->newDb(inDbName, inDbLocation)) {} 192 193 Impl *operator ->() const { return &impl<Impl>(); } 194 Impl &operator *() const { return impl<Impl>(); } 195 }; 196 197 198 // 199 // SSGroup -- Group key with acl, used to protect a group of items. 200 // 201 class SSGroupImpl : public KeyImpl 202 { 203 public: 204 SSGroupImpl(const SSDb &ssDb, const CSSM_DATA &dataBlob); 205 SSGroupImpl(const SSDb &ssDb, 206 const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry); 207 208 static bool isGroup(const CSSM_DATA &dataBlob); 209 210 const CssmData label() const; 211 void decodeDataBlob(const CSSM_DATA &dataBlob, 212 const CSSM_ACCESS_CREDENTIALS *cred, 213 Allocator &allocator, CSSM_DATA &data); 214 void encodeDataBlob(const CSSM_DATA *data, 215 const CSSM_ACCESS_CREDENTIALS *cred, 216 CssmDataContainer &dataBlob); 217 218 private: 219 // Constants 220 enum 221 { 222 // Label prefix for a secure storage group 223 kGroupMagic = FOUR_CHAR_CODE('ssgp'), 224 225 // Size of label (including prefix) 226 kLabelSize = 20, 227 228 // Size of IV 229 kIVSize = 8 230 }; 231 232 CSSM_DB_ATTR_DECL(kLabel); 233 234 CssmDataContainer mLabel; 235 }; 236 237 class SSGroup : public Key 238 { 239 public: 240 typedef SSGroupImpl Impl; 241 explicit SSGroup(Impl *impl) : Key(impl) {} 242 243 SSGroup() : Key(NULL) {} 244 245 // Create a new group. 246 SSGroup(const SSDb &ssDb, 247 const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry) 248 : Key(new Impl(ssDb, credAndAclEntry)) {} 249 250 // Lookup an existing group based on a dataBlob. 251 SSGroup(const SSDb &ssDb, const CSSM_DATA &dataBlob) 252 : Key(new Impl(ssDb, dataBlob)) {} 253 254 Impl *operator ->() const { return &impl<Impl>(); } 255 Impl &operator *() const { return impl<Impl>(); } 256 }; 257 258 259 // 260 // SSDbCursor -- Cursor for iterating over Securely Stored records (or keys) 261 // 262 class SSDbCursorImpl : public DbDbCursorImpl 263 { 264 public: 265 SSDbCursorImpl(const Db &db, const CSSM_QUERY &query, 266 Allocator &allocator); 267 SSDbCursorImpl(const Db &db, uint32 capacity, 268 Allocator &allocator); 269 270 bool next(DbAttributes *attributes, ::CssmDataContainer *data, 271 DbUniqueRecord &uniqueId); 272 bool next(DbAttributes *attributes, ::CssmDataContainer *data, 273 DbUniqueRecord &uniqueId, const CSSM_ACCESS_CREDENTIALS *cred); 274 bool nextKey(DbAttributes *attributes, Key &key, DbUniqueRecord &uniqueId); 275 //bool nextGroup(DbAttributes *attributes, SSGroup &group, DbUniqueRecord &uniqueId); 276 277 SSDb database() { return parent<SSDb>(); } 278 protected: 279 void activate(); 280 void deactivate(); 281 }; 282 283 class SSDbCursor : public DbCursor 284 { 285 public: 286 typedef SSDbCursorImpl Impl; 287 288 explicit SSDbCursor(Impl *impl) : DbCursor(impl) {} 289 SSDbCursor(const SSDb &ssDb, const CSSM_QUERY &query, 290 Allocator &allocator = Allocator::standard()) 291 : DbCursor(ssDb->newDbCursor(query, allocator)) {} 292 SSDbCursor(const SSDb &ssDb, const uint32 capacity = 0, 293 Allocator &allocator = Allocator::standard()) 294 : DbCursor(ssDb->newDbCursor(capacity, allocator)) {} 295 296 Impl *operator ->() const { return &impl<Impl>(); } 297 Impl &operator *() const { return impl<Impl>(); } 298 }; 299 300 301 // 302 // SSDbUniqueRecord 303 // 304 class SSDbUniqueRecordImpl : public DbUniqueRecordImpl 305 { 306 public: 307 SSDbUniqueRecordImpl(const Db &db); 308 virtual ~SSDbUniqueRecordImpl(); 309 310 void deleteRecord(); 311 void deleteRecord(const CSSM_ACCESS_CREDENTIALS *cred); 312 void modify(CSSM_DB_RECORDTYPE recordType, 313 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes, 314 const CSSM_DATA *data, 315 CSSM_DB_MODIFY_MODE modifyMode); 316 void modify(CSSM_DB_RECORDTYPE recordType, 317 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes, 318 const CSSM_DATA *data, 319 CSSM_DB_MODIFY_MODE modifyMode, 320 const CSSM_ACCESS_CREDENTIALS *cred); 321 void get(DbAttributes *attributes, ::CssmDataContainer *data); 322 void get(DbAttributes *attributes, ::CssmDataContainer *data, 323 const CSSM_ACCESS_CREDENTIALS *cred); 324 325 SSDb database() { return parent<SSDb>(); } 326 327 // Return the group that this record is in. 328 SSGroup group(); 329 }; 330 331 class SSDbUniqueRecord : public DbUniqueRecord 332 { 333 public: 334 typedef SSDbUniqueRecordImpl Impl; 335 336 explicit SSDbUniqueRecord(Impl *impl) : DbUniqueRecord(impl) {} 337 SSDbUniqueRecord(const SSDb &ssDb) 338 : DbUniqueRecord(ssDb->newDbUniqueRecord()) {} 339 340 Impl *operator ->() const { return &impl<Impl>(); } 341 Impl &operator *() const { return impl<Impl>(); } 342 }; 343 344 }; // end namespace CssmClient 345 346 } // end namespace Security 347 348 #endif //_H_CDSA_CLIENT_SECURESTORAGE