#ifdef BSAFE_CSP_ENABLE
#ifndef _H_BSAFECSPI
#define _H_BSAFECSPI
#include <security_cdsa_plugin/CSPsession.h>
#include "bsobjects.h"
#include "AppleCSPContext.h"
#include "AppleCSPSession.h"
#include <aglobal.h>
#include <bsafe.h>
class BSafe {
class BSafeContext; friend class BSafeContext;
class BSafeFactory; friend class BSafeFactory;
public:
static void setNormAllocator(Allocator *alloc)
{ assert(!normAllocator); normAllocator = alloc; }
static void setPrivAllocator(Allocator *alloc)
{ assert(!privAllocator); privAllocator = alloc; }
static bool setup(
AppleCSPSession &session,
CSPFullPluginSession::CSPContext * &cspCtx,
const Context &context);
private:
static Allocator *normAllocator;
static Allocator *privAllocator;
friend POINTER T_malloc(unsigned int);
friend void T_free(POINTER);
friend POINTER T_realloc(POINTER, unsigned int);
static const B_ALGORITHM_METHOD * const bsChooser[];
private:
class BSafeBinaryKey : public BinaryKey {
public:
BSafeBinaryKey(
bool isPub,
uint32 alg); ~BSafeBinaryKey();
void generateKeyBlob(
Allocator &allocator,
CssmData &blob,
CSSM_KEYBLOB_FORMAT &format,
AppleCSPSession &session,
const CssmKey *paramKey,
CSSM_KEYATTR_FLAGS &attrFlags);
bool isPublic() { return mIsPublic; }
uint32 alg() { return mAlg; }
B_KEY_OBJ bsKey() { return mBsKey; }
private:
bool mIsPublic;
uint32 mAlg; B_KEY_OBJ mBsKey;
};
private:
class BSafeContext : public AppleCSPContext {
friend class BSafe;
public:
BSafeContext(AppleCSPSession &session);
virtual ~BSafeContext();
void init(const Context &context, bool encoding = true);
void update(const CssmData &data);
void update(void *inp, size_t &inSize, void *outp, size_t &outSize);
void final(CssmData &out);
void final(const CssmData &in);
size_t outputSize(bool final, size_t inSize);
protected:
void setAlgorithm(B_INFO_TYPE bAlgType, const void *info = NULL);
void createBsKey();
void setKeyAtom(B_INFO_TYPE bKeyInfo, const void *info);
void setKeyFromItem(B_INFO_TYPE bKeyInfo, const BSafeItem &item)
{ setKeyAtom(bKeyInfo, &item); }
void setKeyFromCssmKey(B_INFO_TYPE bKeyInfo, const CssmKey &key)
{ BSafeItem item(key.KeyData); setKeyAtom(bKeyInfo, &item); }
void setKeyFromCssmData(B_INFO_TYPE bKeyInfo, const CssmData &keyData)
{ BSafeItem item(keyData); setKeyAtom(bKeyInfo, &item); }
void setKeyFromContext(const Context &context, bool required = true);
void setRefKey(CssmKey &key);
void setRsaOutSize(bool isPubKey);
void setRandom();
virtual void trackUpdate(size_t in, size_t out);
void reset();
void destroyBsKey();
bool reusing(bool encode = true)
{
if (initialized && !opStarted &&
(encode == encoding)) return true;
encoding = encode;
return false;
}
public:
int (*inUpdate)(B_ALGORITHM_OBJ, POINTER, unsigned int, A_SURRENDER_CTX *);
int (*inOutUpdate)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int,
POINTER, unsigned int, B_ALGORITHM_OBJ, A_SURRENDER_CTX *);
int (*inFinal)(B_ALGORITHM_OBJ, POINTER, unsigned int, A_SURRENDER_CTX *);
int (*inFinalR)(B_ALGORITHM_OBJ, POINTER, unsigned int,
B_ALGORITHM_OBJ, A_SURRENDER_CTX *);
int (*outFinalR)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int,
B_ALGORITHM_OBJ, A_SURRENDER_CTX *);
int (*outFinal)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int,
A_SURRENDER_CTX *);
protected:
static B_ALGORITHM_METHOD **chooser()
{ return const_cast<B_ALGORITHM_METHOD **>(bsChooser); }
static A_SURRENDER_CTX * const bsSurrender;
protected:
B_ALGORITHM_OBJ bsAlgorithm; B_ALGORITHM_OBJ bsRandom; bool encoding; bool initialized; bool opStarted; BSafeBinaryKey *bsBinKey;
B_KEY_OBJ bsKey;
size_t mOutSize; };
class DigestContext : public BSafeContext {
public:
DigestContext(
AppleCSPSession &session,
const Context &,
B_INFO_TYPE bAlgInfo,
size_t sz);
};
class CipherContext : public BSafeContext {
public:
CipherContext(
AppleCSPSession &session) :
BSafeContext(session),
pending(0) {}
protected:
size_t pending; public:
void cipherInit(); };
class BlockCipherContext : public CipherContext {
size_t blockSize;
uint32 cssmAlg;
uint32 cssmMode;
bool padEnable;
public:
BlockCipherContext(
AppleCSPSession &session,
const Context &,
size_t sz) :
CipherContext(session),
blockSize(sz) { }
void init(const Context &context, bool encrypting);
size_t inputSize(size_t outSize);
size_t outputSize(bool final, size_t inSize);
void minimumProgress(size_t &in, size_t &out);
void trackUpdate(size_t in, size_t out);
private:
void RC4init(const Context &context);
};
class BSafeKeyPairGenContext : public BSafeContext,
private AppleKeyPairGenContext {
public:
BSafeKeyPairGenContext(
AppleCSPSession &session,
const Context &) :
BSafeContext(session) {}
void generate(
const Context &context,
uint32 bitSize,
CssmData ¶ms,
uint32 &attrCount,
Context::Attr * &attrs);
void generate(
const Context &context,
CssmKey &pubKey,
CssmKey &privKey);
void generate(
const Context &context,
BinaryKey &pubBinKey,
BinaryKey &privBinKey,
uint32 &keySize);
private:
void setupAlgorithm(
const Context &context,
uint32 &keySize);
};
class PublicKeyCipherContext : public CipherContext {
public:
PublicKeyCipherContext(
AppleCSPSession &session,
const Context &) :
CipherContext(session) { }
void init(const Context &context, bool encrypting);
size_t inputSize(size_t outSize); };
class SigningContext : public BSafeContext {
B_INFO_TYPE algorithm;
public:
SigningContext(
AppleCSPSession &session,
const Context &,
B_INFO_TYPE bAlg,
size_t sz) :
BSafeContext(session),
algorithm(bAlg) { mOutSize = sz; }
void init(const Context &context, bool signing);
};
class MacContext : public BSafeContext {
B_INFO_TYPE algorithm;
public:
MacContext(
AppleCSPSession &session,
const Context &,
B_INFO_TYPE bAlg,
size_t sz) :
BSafeContext(session),
algorithm(bAlg) { mOutSize = sz; }
void init(const Context &context, bool signing);
void final(const CssmData &in);
};
class RandomContext : public BSafeContext {
B_INFO_TYPE algorithm;
public:
RandomContext(
AppleCSPSession &session,
const Context &,
B_INFO_TYPE alg) :
BSafeContext(session),
algorithm(alg) { }
void init(const Context &context, bool);
void final(CssmData &data);
};
class SymmetricKeyGenContext : public BSafeContext,
private AppleSymmKeyGenContext {
public:
SymmetricKeyGenContext(
AppleCSPSession &session,
const Context &ctx,
uint32 minSizeInBits,
uint32 maxSizeInBits,
bool mustBeByteSized) :
BSafeContext(session),
AppleSymmKeyGenContext(
minSizeInBits,
maxSizeInBits,
mustBeByteSized) { }
void generate(
const Context &context,
CssmKey &symKey,
CssmKey &dummyKey);
};
public:
static bool bsafeAlgToInfoType(
CSSM_ALGORITHMS alg,
bool isPublic,
B_INFO_TYPE &infoType, CSSM_KEYBLOB_FORMAT &format);
static void check(int status, bool isKeyOp = false);
template <class KI_Type>
static KI_Type *getKey(B_KEY_OBJ bKey, B_INFO_TYPE type)
{
POINTER p;
check(B_GetKeyInfo(&p, bKey, type), true);
return reinterpret_cast<KI_Type *>(p);
}
public:
class MakerBase {
public:
virtual ~MakerBase() { }
virtual BSafeContext *make(
AppleCSPSession &session,
const Context &context) const = 0;
};
struct MakerTable {
CSSM_ALGORITHMS algorithmId;
CSSM_CONTEXT_TYPE algClass;
const MakerBase *maker;
~MakerTable() { delete maker; }
};
private:
static bug_const MakerTable algorithms[];
static const unsigned int algorithmCount;
class BSafeKeyInfoProvider : public CSPKeyInfoProvider
{
private:
BSafeKeyInfoProvider(
const CssmKey &cssmKey,
AppleCSPSession &session);
public:
static CSPKeyInfoProvider *provider(
const CssmKey &cssmKey,
AppleCSPSession &session);
~BSafeKeyInfoProvider() { }
void CssmKeyToBinary(
CssmKey *paramKey, CSSM_KEYATTR_FLAGS &attrFlags, BinaryKey **binKey); void QueryKeySizeInBits(
CSSM_KEY_SIZE &keySize); };
};
#define BLOB_IS_PUB_KEY_INFO 0
#if BLOB_IS_PUB_KEY_INFO
#define RSA_PUB_KEYINFO_TYPE KI_RSAPublicBER
#define RSA_PRIV_KEYINFO_TYPE KI_PKCS_RSAPrivateBER
#define DSA_PUB_KEYINFO_TYPE KI_DSAPublicBER
#define DSA_PRIV_KEYINFO_TYPE KI_DSAPrivateBER
#else
#define RSA_PUB_KEYINFO_TYPE KI_RSAPublic
#define RSA_PRIV_KEYINFO_TYPE KI_PKCS_RSAPrivateBER
#define DSA_PUB_KEYINFO_TYPE KI_DSAPublicBER
#define DSA_PRIV_KEYINFO_TYPE KI_DSAPrivateBER
#endif
#endif //_H_BSAFECSP
#endif