blob: 560466f3a0de2797c1051720d180af896b91172e [file] [log] [blame]
#include <libzrtpcpp/crypto/aesCFB.h>
#include <libzrtpcpp/crypto/twoCFB.h>
#include <libzrtpcpp/ZrtpConfigure.h>
#include <libzrtpcpp/ZrtpTextData.h>
AlgorithmEnum::AlgorithmEnum(const AlgoTypes type, const char* name,
int32_t klen, const char* ra, encrypt_t en,
decrypt_t de, SrtpAlgorithms alId):
algoType(type) , algoName(name), keyLen(klen), readable(ra), encrypt(en),
decrypt(de), algoId(alId) {
}
AlgorithmEnum::~AlgorithmEnum()
{
}
const char* AlgorithmEnum::getName() {
return algoName.c_str();
}
const char* AlgorithmEnum::getReadable() {
return readable.c_str();
}
int AlgorithmEnum::getKeylen() {
return keyLen;
}
SrtpAlgorithms AlgorithmEnum::getAlgoId() {
return algoId;
}
encrypt_t AlgorithmEnum::getEncrypt() {
return encrypt;
}
decrypt_t AlgorithmEnum::getDecrypt() {
return decrypt;
}
AlgoTypes AlgorithmEnum::getAlgoType() {
return algoType;
}
bool AlgorithmEnum::isValid() {
return (algoType != Invalid);
}
static AlgorithmEnum invalidAlgo(Invalid, "", 0, "", NULL, NULL, None);
EnumBase::EnumBase(AlgoTypes a) : algoType(a) {
}
EnumBase::~EnumBase() {}
void EnumBase::insert(const char* name) {
if (!name)
return;
AlgorithmEnum* e = new AlgorithmEnum(algoType, name, 0, "", NULL, NULL, None);
algos.push_back(e);
}
void EnumBase::insert(const char* name, int32_t klen, const char* ra,
encrypt_t enc, decrypt_t dec, SrtpAlgorithms alId) {
if (!name)
return;
AlgorithmEnum* e = new AlgorithmEnum(algoType, name, klen, ra, enc, dec, alId);
algos.push_back(e);
}
int EnumBase::getSize() {
return algos.size();
}
AlgoTypes EnumBase::getAlgoType() {
return algoType;
}
AlgorithmEnum& EnumBase::getByName(const char* name) {
std::vector<AlgorithmEnum* >::iterator b = algos.begin();
std::vector<AlgorithmEnum* >::iterator e = algos.end();
for (; b != e; b++) {
if (strncmp((*b)->getName(), name, 4) == 0) {
return *(*b);
}
}
return invalidAlgo;
}
AlgorithmEnum& EnumBase::getByOrdinal(int ord) {
std::vector<AlgorithmEnum* >::iterator b = algos.begin();
std::vector<AlgorithmEnum* >::iterator e = algos.end();
for (int i = 0; b != e; ++b) {
if (i == ord) {
return *(*b);
}
i++;
}
return invalidAlgo;
}
int EnumBase::getOrdinal(AlgorithmEnum& algo) {
std::vector<AlgorithmEnum* >::iterator b = algos.begin();
std::vector<AlgorithmEnum* >::iterator e = algos.end();
for (int i = 0; b != e; ++b) {
if (strncmp((*b)->getName(), algo.getName(), 4) == 0) {
return i;
}
i++;
}
return -1;
}
std::list<std::string>* EnumBase::getAllNames() {
std::vector<AlgorithmEnum* >::iterator b = algos.begin();
std::vector<AlgorithmEnum* >::iterator e = algos.end();
std::list<std::string>* strg = new std::list<std::string>();
for (; b != e; b++) {
std::string s((*b)->getName());
strg->push_back(s);
}
return strg;
}
/**
* Set up the enumeration list for available hash algorithms
*/
HashEnum::HashEnum() : EnumBase(HashAlgorithm) {
insert(s256);
insert(s384);
}
HashEnum::~HashEnum() {}
/**
* Set up the enumeration list for available symmetric cipher algorithms
*/
SymCipherEnum::SymCipherEnum() : EnumBase(CipherAlgorithm) {
insert(aes3, 32, "AES-CM-256", aesCfbEncrypt, aesCfbDecrypt, Aes);
insert(aes1, 16, "AES-CM-128", aesCfbEncrypt, aesCfbDecrypt, Aes);
insert(two3, 32, "TWO-CM-256", twoCfbEncrypt, twoCfbDecrypt, TwoFish);
insert(two1, 16, "TWO-CM-128", twoCfbEncrypt, twoCfbDecrypt, TwoFish);
}
SymCipherEnum::~SymCipherEnum() {}
/**
* Set up the enumeration list for available public key algorithms
*/
PubKeyEnum::PubKeyEnum() : EnumBase(PubKeyAlgorithm) {
insert(dh2k);
insert(dh3k);
insert(mult);
insert(ec25);
insert(ec38);
}
PubKeyEnum::~PubKeyEnum() {}
/**
* Set up the enumeration list for available SAS algorithms
*/
SasTypeEnum::SasTypeEnum() : EnumBase(SasType) {
insert(b32);
}
SasTypeEnum::~SasTypeEnum() {}
/**
* Set up the enumeration list for available SRTP authentications
*/
AuthLengthEnum::AuthLengthEnum() : EnumBase(AuthLength) {
insert(hs32, 32, "", NULL, NULL, Sha1);
insert(hs80, 80, "", NULL, NULL, Sha1);
insert(sk32, 32, "", NULL, NULL, Skein);
insert(sk64, 64, "", NULL, NULL, Skein);
}
AuthLengthEnum::~AuthLengthEnum() {}
/*
* Here the global accessible enumerations for all implemented algorithms.
*/
HashEnum zrtpHashes;
SymCipherEnum zrtpSymCiphers;
PubKeyEnum zrtpPubKeys;
SasTypeEnum zrtpSasTypes;
AuthLengthEnum zrtpAuthLengths;
/*
* The public methods are mainly a facade to the private methods.
*/
ZrtpConfigure::ZrtpConfigure() : enableTrustedMitM(false), enableSasSignature(false), enableParanoidMode(false) {}
ZrtpConfigure::~ZrtpConfigure() {}
void ZrtpConfigure::setStandardConfig() {
clear();
addAlgo(HashAlgorithm, zrtpHashes.getByName(s384));
addAlgo(HashAlgorithm, zrtpHashes.getByName(s256));
addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(two3));
addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(aes3));
addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(two1));
addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(aes1));
addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(ec25));
addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(dh3k));
addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(ec38));
addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(dh2k));
addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(mult));
addAlgo(SasType, zrtpSasTypes.getByName(b32));
addAlgo(AuthLength, zrtpAuthLengths.getByName(sk32));
addAlgo(AuthLength, zrtpAuthLengths.getByName(sk64));
addAlgo(AuthLength, zrtpAuthLengths.getByName(hs32));
addAlgo(AuthLength, zrtpAuthLengths.getByName(hs80));
}
void ZrtpConfigure::setMandatoryOnly() {
clear();
addAlgo(HashAlgorithm, zrtpHashes.getByName(s256));
addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(aes1));
addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(dh3k));
addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(mult));
addAlgo(SasType, zrtpSasTypes.getByName(b32));
addAlgo(AuthLength, zrtpAuthLengths.getByName(hs32));
addAlgo(AuthLength, zrtpAuthLengths.getByName(hs80));
}
void ZrtpConfigure::clear() {
hashes.clear();
symCiphers.clear();
publicKeyAlgos.clear();
sasTypes.clear();
authLengths.clear();
}
int32_t ZrtpConfigure::addAlgo(AlgoTypes algoType, AlgorithmEnum& algo) {
return addAlgo(getEnum(algoType), algo);
}
int32_t ZrtpConfigure::addAlgoAt(AlgoTypes algoType, AlgorithmEnum& algo, int32_t index) {
return addAlgoAt(getEnum(algoType), algo, index);
}
AlgorithmEnum& ZrtpConfigure::getAlgoAt(AlgoTypes algoType, int32_t index) {
return getAlgoAt(getEnum(algoType), index);
}
int32_t ZrtpConfigure::removeAlgo(AlgoTypes algoType, AlgorithmEnum& algo) {
return removeAlgo(getEnum(algoType), algo);
}
int32_t ZrtpConfigure::getNumConfiguredAlgos(AlgoTypes algoType) {
return getNumConfiguredAlgos(getEnum(algoType));
}
bool ZrtpConfigure::containsAlgo(AlgoTypes algoType, AlgorithmEnum& algo) {
return containsAlgo(getEnum(algoType), algo);
}
void ZrtpConfigure::printConfiguredAlgos(AlgoTypes algoType) {
printConfiguredAlgos(getEnum(algoType));
}
/*
* The next methods are the private methods that implement the real
* details.
*/
AlgorithmEnum& ZrtpConfigure::getAlgoAt(std::vector<AlgorithmEnum* >& a, int32_t index) {
if (index >= (int)a.size())
return invalidAlgo;
std::vector<AlgorithmEnum* >::iterator b = a.begin();
std::vector<AlgorithmEnum* >::iterator e = a.end();
for (int i = 0; b != e; ++b) {
if (i == index) {
return *(*b);
}
i++;
}
return invalidAlgo;
}
int32_t ZrtpConfigure::addAlgo(std::vector<AlgorithmEnum* >& a, AlgorithmEnum& algo) {
int size = (int)a.size();
if (size >= maxNoOfAlgos)
return -1;
if (!algo.isValid())
return -1;
if (containsAlgo(a, algo))
return (maxNoOfAlgos - size);
a.push_back(&algo);
return (maxNoOfAlgos - (int)a.size());
}
int32_t ZrtpConfigure::addAlgoAt(std::vector<AlgorithmEnum* >& a, AlgorithmEnum& algo, int32_t index) {
if (index >= maxNoOfAlgos)
return -1;
int size = (int)a.size();
if (!algo.isValid())
return -1;
// a[index] = &algo;
if (index >= size) {
a.push_back(&algo);
return maxNoOfAlgos - (int)a.size();
}
std::vector<AlgorithmEnum* >::iterator b = a.begin();
std::vector<AlgorithmEnum* >::iterator e = a.end();
for (int i = 0; b != e; ++b) {
if (i == index) {
a.insert(b, &algo);
break;
}
i++;
}
return (maxNoOfAlgos - (int)a.size());
}
int32_t ZrtpConfigure::removeAlgo(std::vector<AlgorithmEnum* >& a, AlgorithmEnum& algo) {
if ((int)a.size() == 0 || !algo.isValid())
return maxNoOfAlgos;
std::vector<AlgorithmEnum* >::iterator b = a.begin();
std::vector<AlgorithmEnum* >::iterator e = a.end();
for (; b != e; ++b) {
if (strcmp((*b)->getName(), algo.getName()) == 0) {
a.erase(b);
break;
}
}
return (maxNoOfAlgos - (int)a.size());
}
int32_t ZrtpConfigure::getNumConfiguredAlgos(std::vector<AlgorithmEnum* >& a) {
return (int32_t)a.size();
}
bool ZrtpConfigure::containsAlgo(std::vector<AlgorithmEnum* >& a, AlgorithmEnum& algo) {
if ((int)a.size() == 0 || !algo.isValid())
return false;
std::vector<AlgorithmEnum* >::iterator b = a.begin();
std::vector<AlgorithmEnum* >::iterator e = a.end();
for (; b != e; ++b) {
if (strcmp((*b)->getName(), algo.getName()) == 0) {
return true;
}
}
return false;
}
void ZrtpConfigure::printConfiguredAlgos(std::vector<AlgorithmEnum* >& a) {
std::vector<AlgorithmEnum* >::iterator b = a.begin();
std::vector<AlgorithmEnum* >::iterator e = a.end();
for (; b != e; ++b) {
printf("print configured: name: %s\n", (*b)->getName());
}
}
std::vector<AlgorithmEnum* >& ZrtpConfigure::getEnum(AlgoTypes algoType) {
switch(algoType) {
case HashAlgorithm:
return hashes;
break;
case CipherAlgorithm:
return symCiphers;
break;
case PubKeyAlgorithm:
return publicKeyAlgos;
break;
case SasType:
return sasTypes;
break;
case AuthLength:
return authLengths;
break;
default:
break;
}
return hashes;
}
void ZrtpConfigure::setTrustedMitM(bool yesNo) {
enableTrustedMitM = yesNo;
}
bool ZrtpConfigure::isTrustedMitM() {
return enableTrustedMitM;
}
void ZrtpConfigure::setSasSignature(bool yesNo) {
enableSasSignature = yesNo;
}
bool ZrtpConfigure::isSasSignature() {
return enableSasSignature;
}
void ZrtpConfigure::setParanoidMode(bool yesNo) {
enableParanoidMode = yesNo;
}
bool ZrtpConfigure::isParanoidMode() {
return enableParanoidMode;
}
#if 0
ZrtpConfigure config;
main() {
printf("Start\n");
printf("size: %d\n", zrtpHashes.getSize());
AlgorithmEnum e = zrtpHashes.getByName("S256");
printf("algo name: %s\n", e.getName());
printf("algo type: %d\n", e.getAlgoType());
std::list<std::string>* names = zrtpHashes.getAllNames();
printf("size of name list: %d\n", names->size());
printf("first name: %s\n", names->front().c_str());
printf("last name: %s\n", names->back().c_str());
printf("free slots: %d (expected 6)\n", config.addAlgo(HashAlgorithm, e));
AlgorithmEnum e1(HashAlgorithm, "SHA384");
printf("free slots: %d (expected 5)\n", config.addAlgoAt(HashAlgorithm, e1, 0));
AlgorithmEnum e2 = config.getAlgoAt(HashAlgorithm, 0);
printf("algo name: %s (expected SHA384)\n", e2.getName());
printf("Num of configured algos: %d (expected 2)\n", config.getNumConfiguredAlgos(HashAlgorithm));
config.printConfiguredAlgos(HashAlgorithm);
printf("free slots: %d (expected 6)\n", config.removeAlgo(HashAlgorithm, e2));
e2 = config.getAlgoAt(HashAlgorithm, 0);
printf("algo name: %s (expected SHA256)\n", e2.getName());
printf("clearing config\n");
config.clear();
printf("size: %d\n", zrtpHashes.getSize());
e = zrtpHashes.getByName("S256");
printf("algo name: %s\n", e.getName());
printf("algo type: %d\n", e.getAlgoType());
}
#endif
/** EMACS **
* Local variables:
* mode: c++
* c-default-style: ellemtel
* c-basic-offset: 4
* End:
*/