A simple Qt based browser with no bullshit that supports PKCS#11 tokens (such as the SuisseID).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

654 lines
18 KiB

//////////////////////////////////////////////////////////////////////////////////
// Name: actUtility.h
// Product: cv act library
// Purpose: useful global functions
//
// Copyright: (c) 2000-2001 cv cryptovision GmbH
// all rights reserved
// Licence: The conditions for the use of this software are regulated
// in the cv act library licence agreement.
//////////////////////////////////////////////////////////////////////////////////
#ifndef ACT_Utility_h
#define ACT_Utility_h
#include "actBlob.h"
#include "actBasics.h"
#include "actException.h"
#include <string>
#include <algorithm>
#include <cctype>
#include <cwctype>
#include <stdio.h>
#include <ctype.h>
#if defined(__GNUC__) && (__GNUC__ < 4)
namespace act { typedef std::basic_string<wchar_t> wstring; }
#else
namespace act { using std::wstring; }
#endif
namespace act
{
class IParam;
//
// Const Values
//
extern const size_t sizeof_uuid;
//
// Prototypes
//
const char* get_string_param(paramid_t id, IParam* owner);
// Converts an unsigned hexadecimal number (independent of prefix "0x")
// into a Blob and backwards.
// - for blob2hex: the user has to allocate hexnumber
Blob& hex2blob(const char* hexnumber, Blob& b);
inline Blob& hex2blob(const std::string& hexnumber, Blob& b)
{
return hex2blob(hexnumber.c_str(), b);
}
inline Blob hex2blob(const char* hexnumber)
{
Blob b;
return move(hex2blob(hexnumber, b));
}
void blob2hex(const Blob& b, char* hexnumber);
std::string blob2hex(const Blob& b);
// file i/o for act::Blob
bool file2blob(const char* filename, Blob &blob);
bool blob2file(const char* filename, const act::Blob &blob);
// Create an ISO 9834-8 / RFC 4122 version 4 (pseudo random) UUID.
// Output string format is "xxxxxxxx-xxxx-4xxx-vxxx-xxxxxxxxxxxx", where
// x is random hex char 0 <= x <= f and v an element of { 8, 9, a, b}.
void createPseudoRandomUUID(Blob& uuid, bool network_byte_order = true);
std::string createPseudoRandomUUID();
std::string uuid2string(const Blob& uuid, bool is_network_byte_order = true);
void swapTimeFields(Blob& uuid);
std::string serno2string(const act::Blob& serno);
std::string id2string(const act::Blob& id, bool is_network_byte_order = true);
// CBCMAC with ISO padding
void iCBCMAC(const char* cipher, const Blob& iv, const Blob& mac_key,
const Blob& mac_data, Blob& mac);
void SetDESKeyParity(Blob &key);
bool CheckDESKeyParity(const Blob &key);
void get_string_seq(const std::string& s, const std::string start, const std::string end,
std::string& result, bool case_sens);
bool wstr2utf8(const wchar_t* str, std::string& utf8);
bool utf82wstr(const char* utf8, act::wstring& wstr);
void ASN1ToSequenceOf(Blob& asn1_data);
Blob GetASN1SequenceOf(const Blob& asn1_data);
Blob GetASN1EncodedLength(size_t length);
size_t SkipTagLength(byte tag, const byte* tlv_data, size_t tlv_data_len);
size_t SkipTLVElement(byte tag, const byte* tlv_data, size_t tlv_data_len, bool skip_value = true);
int FindTlvTemplate(Blob& contentb, const Blob& inb, int intag, int counts);
//
// Implementation
//
//
// --------------------------------------------------------------------
template<typename ConverterT, typename RegistryT, typename TypeT>
const Blob SafeGetName(TypeT* instance)
{
Blob name;
if(instance != 0)
{
const char* cname = RegistryT::GetName(instance->GetCreatePointer());
if(cname != 0) ConverterT(cname).swap(name);
}
return move(name);
}
// ---------------------------------------------------------------------------
template<typename TypeT>
struct is_whitespace : is_whitespace<typename TypeT::value_type>
{
typedef typename TypeT::value_type argument_type;
using is_whitespace<typename TypeT::value_type>::operator();
};
template<>
struct is_whitespace<char>
{
typedef char argument_type;
bool operator()(unsigned char value) const { return std::isspace(value) != 0; }
};
template<>
struct is_whitespace<wchar_t>
{
typedef wchar_t argument_type;
bool operator()(wchar_t value) const { return std::iswspace(value) != 0; }
};
// ---------------------------------------------------------------------------
template<typename PredicateT, typename TypeT>
inline TypeT& erase_right(const PredicateT& predicate, TypeT& value)
{
value.erase(std::find_if(value.rbegin(), value.rend(), predicate).base(), value.end());
return value;
}
// ---------------------------------------------------------------------------
template<typename TypeT>
inline void fill(TypeT* begin, size_t length, byte value)
{
ACT_ASSERT(begin != 0);
std::fill(reinterpret_cast<act::byte*>(begin),
reinterpret_cast<act::byte*>(begin) + length, value);
}
//
// scoped_delete<PointerT>
// ---------------------------------------------------------------------------
template<typename PointerT>
struct scoped_delete<PointerT, void, 1>
{
PointerT _ptr;
explicit scoped_delete(PointerT ptr) : _ptr(ptr) { }
~scoped_delete() { delete _ptr; }
PointerT operator->() const
{
if(_ptr == 0) throw NullPointerException();
return _ptr;
}
};
// ---------------------------------------------------------------------------
template<typename PointerT>
scoped_delete<PointerT, void, 1> checked_delete(PointerT& ptr_ref)
{
PointerT ptr = ptr_ref; ptr_ref = 0;
return scoped_delete<PointerT, void, 1>(ptr);
}
//
// scoped_delete<AutoPtrT>
// ---------------------------------------------------------------------------
template
<
template<class> class AutoPtrT,
class TypeT
>
struct scoped_delete<AutoPtrT<TypeT>, void, 1>
{
AutoPtrT<TypeT> _ptr;
explicit scoped_delete(AutoPtrT<TypeT>& ptr) : _ptr(ptr) { }
~scoped_delete() { AutoPtrT<TypeT>(_ptr); }
TypeT* operator->() const
{
TypeT* ptr = _ptr.get();
if(ptr == 0) throw NullPointerException();
return ptr;
}
};
// ---------------------------------------------------------------------------
template
<
template<class> class AutoPtrT,
class TypeT
>
scoped_delete<AutoPtrT<TypeT>, void, 1> checked_delete(AutoPtrT<TypeT>& ptr_ref)
{
return scoped_delete<AutoPtrT<TypeT>, void, 1>(ptr_ref);
}
//
// scoped_delete<ArrayT<TypeT*> >
// ---------------------------------------------------------------------------
template
<
template<class, class> class ArrayT,
class TypeT, class AllocatorT,
typename DestructF
>
struct scoped_delete<ArrayT<TypeT, AllocatorT>, DestructF, 3>
{
typedef ArrayT<TypeT, AllocatorT> container_type;
typedef DestructF destruct_func;
explicit scoped_delete(container_type& _container, const destruct_func& _destruct)
: destruct(_destruct)
{ container.swap(_container); }
~scoped_delete()
{ release(container, destruct); }
static void release(container_type& container, const destruct_func& destruct)
{
if(container.empty() == true) return;
container_type failed;
typedef typename container_type::const_iterator const_iterator;
for(const_iterator i(container.begin()), end(container.end()); i != end; ++i)
try { destruct(*i); }
catch(Exception&) { failed.push_back(*i); }
container.swap(failed);
}
destruct_func destruct;
container_type container;
};
//
// checked_delete(array_of_ptr_to_type, std::mem_fun(&type::destruct));
// ---------------------------------------------------------------------------
template
<
template<class, class> class ArrayT,
class TypeT, class AllocatorT,
typename DestructF
>
scoped_delete<ArrayT<TypeT, AllocatorT>, DestructF, 3>
checked_delete(ArrayT<TypeT, AllocatorT>& container, const DestructF& destruct)
{
return scoped_delete<ArrayT<TypeT, AllocatorT>, DestructF, 3>(container, destruct);
}
//
// scoped_delete<MapT<TypeT*> >
// ---------------------------------------------------------------------------
template
<
template<class, class, class, class> class MapT,
class KeyT, class TypeT, class PredT, class AllocatorT,
typename DestructF
>
struct scoped_delete<MapT<KeyT, TypeT, PredT, AllocatorT>, DestructF, 4>
{
typedef MapT<KeyT, TypeT, PredT, AllocatorT> container_type;
typedef DestructF destruct_func;
explicit scoped_delete(container_type& _container, const destruct_func& _destruct)
: destruct(_destruct)
{ container.swap(_container); }
~scoped_delete()
{ release(container, destruct); }
static void release(container_type& container, const destruct_func& destruct)
{
if(container.empty() == true) return;
container_type failed;
typedef typename container_type::const_iterator const_iterator;
for(const_iterator i(container.begin()), end(container.end()); i != end; ++i)
try { destruct(i->second); }
catch(Exception&) { failed.insert(*i); }
container.swap(failed);
}
destruct_func destruct;
container_type container;
};
//
// checked_delete_map(map_of_ptr_to_type, std::mem_fun(&type::destruct));
// ---------------------------------------------------------------------------
template
<
template<class, class, class, class> class MapT,
class KeyT, class TypeT, class PredT, class AllocatorT,
typename DestructF
>
scoped_delete<MapT<KeyT, TypeT, PredT, AllocatorT>, DestructF, 4>
checked_delete_map(MapT<KeyT, TypeT, PredT, AllocatorT>& map_ref, const DestructF& destruct)
{
return scoped_delete<MapT<KeyT, TypeT, PredT, AllocatorT>, DestructF, 4>(map_ref, destruct);
}
//
// scoped_delete<>
// ---------------------------------------------------------------------------
template<typename TypeT, typename DestructF>
struct scoped_delete<TypeT, DestructF, 0>
{
scoped_delete(const DestructF& _destruct)
: destruct(_destruct)
{ }
~scoped_delete()
{ if(value.empty() == false) checked_delete(value, destruct); }
DestructF destruct;
TypeT value;
};
//
// checked_static_cast<>
// ---------------------------------------------------------------------------
template<class U, class V>
inline U checked_static_cast(V p)
{
ACT_ASSERT(p != 0);
ACT_ASSERT(dynamic_cast<U>(p) != 0);
return static_cast<U>(p);
}
// ---------------------------------------------------------------------------
template<typename TypeT>
inline TypeT& byref(const TypeT& e)
{
return const_cast<TypeT&>(e);
}
// ---------------------------------------------------------------------------
inline int max_int()
{
return int((unsigned(1) << (8 * sizeof(int) - 1)) - 1);
}
// ---------------------------------------------------------------------------
inline void OS2IP(Blob& number)
{
// octet string to integer presentation
if((number.at(0) & byte(0x80)) != 0)
number.insert(number.begin(), 0);
}
// ---------------------------------------------------------------------------
inline void I2OSP(Blob& number)
{
// integer to octet string presentation
if(number.at(0) == byte(0))
number.erase(number.begin());
}
// ---------------------------------------------------------------------------
inline void byte2long(const byte *in, size_t input_len, uint32 *out)
{
size_t i, output_len = input_len / 4;
for(i = 0; i < output_len; i++)
out[i]= in[i*4] | (in[i*4+1] << 8) | (in[i*4+2] << 16) | (in[i*4+3] << 24);
}
// ---------------------------------------------------------------------------
inline void long2byte(const uint32 *in, size_t input_len, byte *out)
{
size_t i, output_len = input_len * 4;
for(i = 0; i < output_len; i++)
out[i] = byte(in[i/4] >> (8*(i%4)));
}
// ---------------------------------------------------------------------------
inline void sweep(void* Mem,size_t l)
{
std::fill_n(reinterpret_cast<byte*>(Mem), l, byte(0));
}
// ---------------------------------------------------------------------------
template<class TypeT>
inline const TypeT Min(const TypeT& a, const TypeT& b)
{
return (a < b) ? a : b;
}
// ---------------------------------------------------------------------------
template<class TypeT>
inline const TypeT& Max(const TypeT& a, const TypeT& b)
{
return (a<b)? b : a;
}
// ---------------------------------------------------------------------------
template<class T1, class T2, class T3>
inline void xor_n(T1 a, T2 len, T3 b)
{
for(T2 i = 0; i < len; i++) b[i] ^= a[i];
}
// ---------------------------------------------------------------------------
template<class T1, class T3> inline void Xor (T1 a, T1 a_end, T3 b)
{
while(a < a_end)
*b++ ^= *a++;
}
// ---------------------------------------------------------------------------
inline const char* blob2char(Blob& b)
{
b.push_back(byte(0));
return reinterpret_cast<const char*>(&b[0]);
}
// ---------------------------------------------------------------------------
inline std::string blob2string(const Blob& value)
{
return value.empty() == false ?
std::string(reinterpret_cast<const std::string::value_type*>(&value.at(0)),
reinterpret_cast<const std::string::value_type*>(&value[0] + value.size())) :
std::string();
}
// ---------------------------------------------------------------------------
inline std::string byte2hex(const byte i)
{
char tmp[3];
sprintf(tmp, "%02x", i);
return tmp;
}
// ---------------------------------------------------------------------------
inline bool isHex(const byte c)
{
if((c < byte('0') || c > byte('9'))
&& (c < byte('a') || c > byte('f'))
&& (c < byte('A') || c > byte('F')))
return false;
return true;
}
// ---------------------------------------------------------------------------
inline bool isHex(const Blob& b)
{
size_t i, b_len = b.size();
for(i = 0; i < b_len; ++i)
if(!isHex(b[i]))
return false;
return true;
}
// ---------------------------------------------------------------------------
inline bool isAlphanumeric(const byte c)
{
if((c < byte('0') || c > byte('9'))
&& (c < byte('a') || c > byte('z'))
&& (c < byte('A') || c > byte('Z')))
return false;
return true;
}
// ---------------------------------------------------------------------------
inline bool isAlphanumeric(const Blob& b)
{
size_t i, b_len = b.size();
for(i = 0; i < b_len; ++i)
if(!isAlphanumeric(b[i]))
return false;
return true;
}
// ---------------------------------------------------------------------------
inline bool isPrintable(const Blob& b)
{
size_t i, b_len = b.size();
for(i = 0; i < b_len; ++i)
if(isprint(int(b[i])) == 0)
return false;
return true;
}
// ---------------------------------------------------------------------------
inline bool isUUIDFormat(const Blob& b)
{
size_t b_len = b.size();
if(b_len != sizeof_uuid)
return false;
// check if the Blob contains only hexadecimal characters,
// separated by '-' (UUID string representation)
for(size_t i = 0; i < b_len; ++i)
if(!isHex(b[i]) && (b[i] != byte('-')))
return false;
return true;
}
// ---------------------------------------------------------------------------
inline std::string short2hex(const unsigned short i)
{
char tmp[5];
sprintf(tmp,"%04x",i);
return tmp;
}
// ---------------------------------------------------------------------------
inline std::string long2hex(const unsigned long i)
{
char tmp[9];
sprintf(tmp,"%08lx",i);
return tmp;
}
// ---------------------------------------------------------------------------
inline unsigned long blob2long(const Blob& b)
{
if(b.size() == 0)
throw LogicalException("bad size","blob2long");
Blob tmp(b);
while(tmp[0] == 0 && tmp.size() > sizeof(long))
tmp.erase(tmp.begin());
if(tmp.size() > sizeof(long))
throw LogicalException("bad size", "blob2long");
unsigned long n = tmp[0];
for(unsigned int i = 1; i < tmp.size(); ++i)
{
n <<= 8;
n |= tmp[i];
}
return n;
}
// ---------------------------------------------------------------------------
inline Blob& long2blob(unsigned long n, Blob& value)
{
value.resize(sizeof(long));
for(size_t i = sizeof(long) - 1, j = 0; j < sizeof(long); --i, ++j)
value[j] = byte((n >> (8 * i)) & 0xff);
return value;
}
// ---------------------------------------------------------------------------
inline Blob long2blob(unsigned long n)
{
Blob value;
return move(long2blob(n, value));
}
// ---------------------------------------------------------------------------
inline Blob size2blob(size_t size)
{
Blob tmp;
tmp.reserve(8);
if(size == 0)
{
tmp.resize(1);
return move(tmp);
}
size_t remaining = size;
while(remaining > 0)
{
tmp.insert(tmp.begin(), byte(remaining & 0xFF));
remaining >>= 8;
}
return move(tmp);
}
// ---------------------------------------------------------------------------
inline unsigned short blob2short(const Blob& b)
{
if(b.size() != sizeof(short))
throw LogicalException("bad size", "blob2short");
unsigned short n = b[1];
n += (b[0] << 8);
return n;
}
// ---------------------------------------------------------------------------
// Input: a (big endian byte arrays)
// Output: ++a (increment with carry)
inline byte memincr(byte* a, int len)
{
int i = len-1;
byte carry;
do {
carry = ++a[i] == 0 ? 1 : 0;
} while( --i >= 0 && carry != 0);
return carry;
}
// ---------------------------------------------------------------------------
// Input: a, b (big endian byte arrays)
// Output: a += b (add with carry)
inline byte memadd(byte* a, const byte* b, int len, byte carry = 0)
{
int i = len - 1;
unsigned long tmp;
for(; i >= 0; --i)
{
tmp = a[i] + b[i] + carry;
a[i] = byte(tmp & 0xff);
carry = byte(tmp >> 8);
}
return carry;
}
// ---------------------------------------------------------------------------
inline void convert_to_upper(std::string& s)
{
for(std::string::iterator it = s.begin(); it != s.end() ; ++it)
*it = toupper(*it);
}
} //namespace act
#endif // ACT_Utility_h