#ifndef _H_SSBLOB
#define _H_SSBLOB
#include <securityd_client/ssclient.h>
#include <Security/cssm.h>
#include <security_utilities/utilities.h>
#include <security_cdsa_utilities/cssmacl.h>
#include <security_utilities/memutils.h>
#include <security_utilities/endian.h>
namespace Security {
namespace SecurityServer {
using LowLevelMemoryUtilities::increment;
class Blob {
public:
typedef Endian<uint32> uint32e;
typedef Endian<sint32> sint32e;
protected:
template <class T>
T *at(off_t offset) { return LowLevelMemoryUtilities::increment<T>(this, offset); }
void *at(off_t offset) { return LowLevelMemoryUtilities::increment(this, (ptrdiff_t)offset); }
template <class T>
const T *at(off_t offset) const { return LowLevelMemoryUtilities::increment<T>(this, offset); }
const void *at(off_t offset) const { return LowLevelMemoryUtilities::increment(this, (ptrdiff_t)offset); }
};
class CommonBlob : public Blob {
public:
uint32e magic; uint32e blobVersion; uint32 version() const { return blobVersion; }
static const uint32 magicNumber = 0xfade0711;
static const uint32 version_MacOS_10_0 = 0x00000100; static const uint32 version_MacOS_10_1 = 0x00000101; static const uint32 currentVersion = version_MacOS_10_0;
public:
void initialize(uint32 version = currentVersion);
bool isValid() const;
void validate(CSSM_RETURN failureCode) const;
void *data() { return at(0); }
const void *data() const { return at(0); }
};
class DbBlob : public CommonBlob {
public:
struct Signature {
uint8 bytes[16];
bool operator < (const Signature &sig) const
{ return memcmp(bytes, sig.bytes, sizeof(bytes)) < 0; }
bool operator == (const Signature &sig) const
{ return memcmp(bytes, sig.bytes, sizeof(bytes)) == 0; }
};
struct PrivateBlob : public Blob {
typedef uint8 EncryptionKey[24];
typedef uint8 SigningKey[20];
EncryptionKey encryptionKey; SigningKey signingKey;
void *privateAclBlob() { return at(sizeof(PrivateBlob)); }
};
public:
uint32e startCryptoBlob; uint32e totalLength;
Signature randomSignature; uint32e sequence; DBParameters params;
uint8 salt[20]; uint8 iv[8];
uint8 blobSignature[20];
void *publicAclBlob() { return at(sizeof(DbBlob)); }
const void *publicAclBlob() const { return at(sizeof(DbBlob)); }
size_t publicAclBlobLength() const
{ return startCryptoBlob - sizeof(DbBlob); }
void *cryptoBlob() { return at(startCryptoBlob); }
const void *cryptoBlob() const { return at(startCryptoBlob); }
size_t cryptoBlobLength() const { return totalLength - startCryptoBlob; }
uint32 length() const { return totalLength; }
DbBlob *copy(Allocator &alloc = Allocator::standard()) const
{
DbBlob *blob = alloc.malloc<DbBlob>(length());
memcpy(blob, this, length());
return blob;
}
};
class KeyBlob : public CommonBlob {
public:
uint32e startCryptoBlob; uint32e totalLength;
uint8 iv[8];
CssmKey::Header header; struct WrappedFields {
Endian<CSSM_KEYBLOB_TYPE> blobType;
Endian<CSSM_KEYBLOB_FORMAT> blobFormat;
Endian<CSSM_ALGORITHMS> wrapAlgorithm;
Endian<CSSM_ENCRYPT_MODE> wrapMode;
} wrappedHeader;
uint8 blobSignature[20];
void *publicAclBlob() { return at(sizeof(KeyBlob)); }
size_t publicAclBlobLength() const
{ return startCryptoBlob - sizeof(KeyBlob); }
void *cryptoBlob() { return at(startCryptoBlob); }
size_t cryptoBlobLength() const { return totalLength - startCryptoBlob; }
uint32 length() const { return totalLength; }
static const uint32 managedAttributes =
CSSM_KEYATTR_ALWAYS_SENSITIVE |
CSSM_KEYATTR_NEVER_EXTRACTABLE |
CSSM_KEYATTR_PERMANENT |
CSSM_KEYATTR_SENSITIVE |
CSSM_KEYATTR_EXTRACTABLE;
static const uint32 forcedAttributes =
CSSM_KEYATTR_EXTRACTABLE;
bool isClearText();
void setClearTextSignature();
public:
KeyBlob *copy(Allocator &alloc) const
{
KeyBlob *blob = alloc.malloc<KeyBlob>(length());
memcpy(blob, this, length());
return blob;
}
};
class UnlockBlob : public CommonBlob {
public:
typedef uint8 MasterKey[24];
MasterKey masterKey; DbBlob::Signature signature; };
} }
#endif //_H_SSBLOB