]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurityd/lib/ssblob.h
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / libsecurityd / lib / ssblob.h
1 /*
2 * Copyright (c) 2000-2006,2011-2012,2014 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 // ssblob - objects to represent persistent blobs used by SecurityServer
27 //
28 #ifndef _H_SSBLOB
29 #define _H_SSBLOB
30
31 #include <securityd_client/ssclient.h>
32 #include <Security/cssm.h>
33 #include <security_utilities/utilities.h>
34 #include <security_cdsa_utilities/cssmacl.h>
35 #include <security_utilities/memutils.h>
36 #include <security_utilities/endian.h>
37
38
39 namespace Security {
40 namespace SecurityServer {
41
42 using LowLevelMemoryUtilities::increment;
43
44
45 //
46 // A generic blob.
47 // Note that Blob and its subclasses are meant to be Byte Order Corrected.
48 // Make sure all non-byte fields are Endian<> qualified.
49 //
50 class Blob {
51 public:
52 typedef Endian<uint32> uint32e;
53 typedef Endian<sint32> sint32e;
54
55 protected:
56 template <class T>
57 T *at(off_t offset) { return LowLevelMemoryUtilities::increment<T>(this, offset); }
58 void *at(off_t offset) { return LowLevelMemoryUtilities::increment(this, (ptrdiff_t)offset); }
59
60 template <class T>
61 const T *at(off_t offset) const { return LowLevelMemoryUtilities::increment<T>(this, offset); }
62 const void *at(off_t offset) const { return LowLevelMemoryUtilities::increment(this, (ptrdiff_t)offset); }
63 };
64
65
66 //
67 // The common features of our blobs
68 //
69 class CommonBlob : public Blob {
70 public:
71 // initial fixed fields for versioning
72 uint32e magic; // magic number
73 uint32e blobVersion; // version code
74 uint32 version() const { return blobVersion; }
75
76 static const uint32 magicNumber = 0xfade0711;
77
78 static const uint32 version_none = 0x0; // dummy value for default parameters. Never set this as an actual version.
79 static const uint32 version_MacOS_10_0 = 0x00000100; // MacOS 10.0.x
80 static const uint32 version_MacOS_10_1 = 0x00000101; // MacOS 10.1.x and on
81 static const uint32 version_partition = 0x00000200; // MacOS 10.11.4 and on, supporting partitioning
82 static const uint32 currentVersion = version_partition;
83
84 static uint32 getCurrentVersion();
85
86 //Returns the version this database should be, given its filesystem location (as dbName)
87 static uint32 getCurrentVersionForDb(const char* dbName);
88
89 static bool pathInHomeLibraryKeychains(const string& path);
90 public:
91 void initialize();
92 void initialize(uint32 version);
93 bool isValid() const;
94 void validate(CSSM_RETURN failureCode) const;
95
96 void *data() { return at(0); }
97 const void *data() const { return at(0); }
98 };
99
100
101 //
102 // A Database blob
103 //
104 class DbBlob : public CommonBlob {
105 public:
106 struct Signature {
107 uint8 bytes[16];
108
109 bool operator < (const Signature &sig) const
110 { return memcmp(bytes, sig.bytes, sizeof(bytes)) < 0; }
111 bool operator == (const Signature &sig) const
112 { return memcmp(bytes, sig.bytes, sizeof(bytes)) == 0; }
113 };
114
115 struct PrivateBlob : public Blob {
116 typedef uint8 EncryptionKey[24];
117 typedef uint8 SigningKey[20];
118
119 EncryptionKey encryptionKey; // master encryption key
120 SigningKey signingKey; // master signing key
121
122 // private ACL blob follows, to the end
123 void *privateAclBlob() { return at(sizeof(PrivateBlob)); }
124 };
125
126 public:
127 // position separators between variable-length fields (see below)
128 uint32e startCryptoBlob; // end of public ACL; start of crypto blob
129 uint32e totalLength; // end of crypto blob; end of entire blob
130
131 Signature randomSignature; // randomizing database signature
132 uint32e sequence; // database sequence number
133 DBParameters params; // database settable parameters
134
135 uint8 salt[20]; // derivation salt
136 uint8 iv[8]; // encryption iv
137
138 uint8 blobSignature[20]; // HMAC/SHA1 of entire blob except itself
139
140 // variable length fields:
141 void *publicAclBlob() { return at(sizeof(DbBlob)); }
142 const void *publicAclBlob() const { return at(sizeof(DbBlob)); }
143 size_t publicAclBlobLength() const
144 { return startCryptoBlob - sizeof(DbBlob); }
145
146 void *cryptoBlob() { return at(startCryptoBlob); }
147 const void *cryptoBlob() const { return at(startCryptoBlob); }
148 size_t cryptoBlobLength() const { return totalLength - startCryptoBlob; }
149
150 uint32 length() const { return totalLength; }
151
152 DbBlob *copy(Allocator &alloc = Allocator::standard()) const
153 {
154 DbBlob *blob = alloc.malloc<DbBlob>(length());
155 memcpy(blob, this, length());
156 return blob;
157 }
158 };
159
160
161 //
162 // A key blob
163 //
164 class KeyBlob : public CommonBlob {
165 public:
166 uint32e startCryptoBlob; // end of public ACL; start of crypto blob
167 uint32e totalLength; // end of crypto blob; end of entire blob
168
169 uint8 iv[8]; // encryption iv
170
171 CssmKey::Header header; // key header as-is
172 struct WrappedFields {
173 Endian<CSSM_KEYBLOB_TYPE> blobType;
174 Endian<CSSM_KEYBLOB_FORMAT> blobFormat;
175 Endian<CSSM_ALGORITHMS> wrapAlgorithm;
176 Endian<CSSM_ENCRYPT_MODE> wrapMode;
177 } wrappedHeader;
178
179 uint8 blobSignature[20]; // HMAC/SHA1 of entire blob except itself
180
181 // variable length fields:
182 void *publicAclBlob() { return at(sizeof(KeyBlob)); }
183 size_t publicAclBlobLength() const
184 { return startCryptoBlob - sizeof(KeyBlob); }
185
186 void *cryptoBlob() { return at(startCryptoBlob); }
187 size_t cryptoBlobLength() const { return totalLength - startCryptoBlob; }
188
189 uint32 length() const { return totalLength; }
190
191 // these bits are managed internally by the SecurityServer (and not passed to the CSPs)
192 static const uint32 managedAttributes =
193 CSSM_KEYATTR_ALWAYS_SENSITIVE |
194 CSSM_KEYATTR_NEVER_EXTRACTABLE |
195 CSSM_KEYATTR_PERMANENT |
196 CSSM_KEYATTR_SENSITIVE |
197 CSSM_KEYATTR_EXTRACTABLE;
198 static const uint32 forcedAttributes =
199 CSSM_KEYATTR_EXTRACTABLE;
200
201 /*
202 * Public Key blobs can be stored unencrypted. A unique blobSignature
203 * is used to indicate this state.
204 */
205 bool isClearText();
206 void setClearTextSignature();
207
208 public:
209 KeyBlob *copy(Allocator &alloc) const
210 {
211 KeyBlob *blob = alloc.malloc<KeyBlob>(length());
212 memcpy(blob, this, length());
213 return blob;
214 }
215 };
216
217
218 //
219 // An auto-unlock record (database identity plus raw unlock key)
220 //
221 class UnlockBlob : public CommonBlob {
222 public:
223 typedef uint8 MasterKey[24];
224 MasterKey masterKey; // raw bits (triple-DES) - make your own CssmKey
225 DbBlob::Signature signature; // signature is index
226 };
227
228
229 //
230 // This class implements a "system keychain unlock record" store
231 //
232 class SystemKeychainKey {
233 public:
234 SystemKeychainKey(const char *path);
235 ~SystemKeychainKey();
236
237 bool matches(const DbBlob::Signature &signature);
238 CssmKey &key();
239
240 // returns true if we have actually retrieved the key
241 bool valid();
242
243 private:
244 std::string mPath; // path to file
245 CssmKey mKey; // proper CssmKey with data in mBlob
246
247 bool mValid; // mBlob was validly read from mPath
248 UnlockBlob mBlob; // contents of mPath as last read
249
250 Time::Absolute mCachedDate; // modify date of file when last read
251 Time::Absolute mUpdateThreshold; // cutoff threshold for checking again
252
253 static const int checkDelay = 1; // seconds minimum delay between update checks
254
255 bool update();
256 };
257
258
259 } // end namespace SecurityServer
260 } // end namespace Security
261
262
263 #endif //_H_SSBLOB