00001
00045 #include "hexfile.h"
00046 #include <sstream>
00047 #include <iomanip>
00048 #include <string>
00049 #include <stdexcept>
00050 #include <vector>
00051 #include <fstream>
00052
00053
00054
00056 class ParameterParser
00057 {
00058 private:
00059 std::string m_filename;
00060 size_t m_keySize;
00061 size_t m_serialNoSize;
00062 size_t m_counterSize;
00063 std::vector< byte > m_sharedKey;
00064 size_t m_maxTransmitters;
00065
00067 std::vector< byte > ParseHexString( const std::string & hexString ) const;
00069 std::string CreateHexString( const std::vector< byte > & byteVector ) const;
00070
00071 public:
00073 ParameterParser( size_t argc, const char * * argv );
00074 ~ParameterParser() {}
00075
00076
00077
00078
00079 const std::string & GetFilename() const { return m_filename; }
00080 size_t GetKeySize() const { return m_keySize; }
00081 size_t GetSerialNoSize() const { return m_serialNoSize; }
00082 size_t GetCounterSize() const { return m_counterSize; }
00083 const std::vector< byte > & GetSharedKey() const { return m_sharedKey; }
00084 size_t GetMaxTransmitters() const { return m_maxTransmitters; }
00085
00086 std::string GetSharedKeyString() const { return CreateHexString( GetSharedKey() ); }
00087 };
00088
00089
00090
00091 std::vector< byte > ParameterParser::ParseHexString( const std::string & hexString ) const
00092 {
00093
00094 if( hexString.size() % 2 != 0 ) {
00095 throw std::runtime_error( "Hex string does not have even character count" );
00096 }
00097
00098
00099
00100
00101 std::vector< byte > bytes;
00102 for( size_t idx = 0; idx < hexString.size(); idx += 2 ) {
00103 std::istringstream iss( hexString.substr( idx, 2 ) );
00104 byte data;
00105 iss >> std::hex >> data;
00106 if( !iss ) {
00107 throw std::runtime_error( "Error parsing hex string \"" + hexString + "\"" );
00108 }
00109 bytes.push_back( data );
00110 }
00111 return bytes;
00112 }
00113
00114
00115
00116 std::string ParameterParser::CreateHexString( const std::vector< byte > & byteVector ) const
00117 {
00118 std::ostringstream oss;
00119 oss << std::setfill('0') << std::hex;
00120
00121
00122 for( size_t idx = 0; idx < byteVector.size() - 1; ++idx ) {
00123 oss << std::setw(2) << byteVector.at( idx ) << ' ';
00124 }
00125
00126
00127 if( byteVector.size() > 0 ) {
00128 oss << std::setw(2) << byteVector.at( byteVector.size()-1 );
00129 }
00130
00131 return oss.str();
00132 }
00133
00134
00135
00136 ParameterParser::ParameterParser( size_t argc, const char * * argv )
00137 {
00138
00139 if( argc != 7 ) {
00140 std::cout << "Parameters:\n"
00141 " filename - Filename for resulting Intel HEX file\n"
00142 " keysize - Size in bits of the AES secret and shared keys (128, 192 or 256)\n"
00143 " serialnosize - Size in bytes of the serial number (1, 2 or 4)\n"
00144 " countersize - Size in bytes of the sequential counter (1, 2 or 4)\n"
00145 " sharedkey - Hex representation of the shared key (32, 48 or 64 digits)\n"
00146 " maxtransmitters - Maximum number of associated transmitters\n"
00147 << std::endl;
00148 throw std::runtime_error( "Not exactly 6 parameters" );
00149 }
00150
00151
00152
00153
00154 std::string arg1( argv[1] );
00155 std::istringstream arg2( argv[2] );
00156 std::istringstream arg3( argv[3] );
00157 std::istringstream arg4( argv[4] );
00158 std::string arg5( argv[5] );
00159 std::istringstream arg6( argv[6] );
00160
00161
00162
00163
00164 m_filename = arg1;
00165
00166 arg2 >> m_keySize;
00167 if( !arg2 ) {
00168 throw std::runtime_error( "Error parsing key size argument" );
00169 }
00170
00171 arg3 >> m_serialNoSize;
00172 if( !arg3 ) {
00173 throw std::runtime_error( "Error parsing serial no size argument" );
00174 }
00175
00176 arg4 >> m_counterSize;
00177 if( !arg4 ) {
00178 throw std::runtime_error( "Error parsing counter size argument" );
00179 }
00180
00181 m_sharedKey = ParseHexString( arg5 );
00182
00183 arg6 >> m_maxTransmitters;
00184 if( !arg6 ) {
00185 throw std::runtime_error( "Error parsing max transmitters argument" );
00186 }
00187
00188
00189
00190
00191 if( m_keySize != 128 && m_keySize != 192 && m_keySize != 256 ) {
00192 throw std::runtime_error( "Key size is not 128, 192 or 256 bits" );
00193 }
00194
00195 if( m_serialNoSize != 1 && m_serialNoSize != 2 && m_serialNoSize != 4 ) {
00196 throw std::runtime_error( "Serial no is not 1, 2 or 4 bytes" );
00197 }
00198
00199 if( m_counterSize != 1 && m_counterSize != 2 && m_counterSize != 4 ) {
00200 throw std::runtime_error( "Counter is not 1, 2 or 4 bytes" );
00201 }
00202
00203 if( m_sharedKey.size() != m_keySize / 8 ) {
00204 throw std::runtime_error( "Shared key has invalid length" );
00205 }
00206 }
00207
00208
00209
00211 void CreateHEXFile( const ParameterParser & parser )
00212 {
00213 HEXFile hexData;
00214 std::ofstream outFile( parser.GetFilename().c_str() );
00215
00216
00217 HEXRecord sharedKey;
00218 sharedKey << parser.GetSharedKey();
00219
00220
00221 HEXRecord transmitterCount;
00222 transmitterCount << ((byte) 0x00);
00223
00224
00225 HEXRecord transmitterTableEntry;
00226 const size_t entrySize =
00227 (parser.GetKeySize() / 8) +
00228 parser.GetSerialNoSize() +
00229 parser.GetCounterSize();
00230 for( size_t idx = 0; idx < entrySize; ++idx ) {
00231 transmitterTableEntry << ((byte) 0xff);
00232 }
00233
00234
00235 hexData << sharedKey << transmitterCount;
00236 for( size_t idx = 0; idx < parser.GetMaxTransmitters(); ++idx ) {
00237 hexData << transmitterTableEntry;
00238 }
00239
00240
00241 outFile << hexData;
00242 }
00243
00244
00245
00246 int main( size_t argc, const char * * argv )
00247 {
00248 try {
00249 ParameterParser parser( argc, argv );
00250 std::cout << "Filename : " << parser.GetFilename() << std::endl
00251 << "Key size : " << parser.GetKeySize() << std::endl
00252 << "Serial no size : " << parser.GetSerialNoSize() << std::endl
00253 << "Counter size : " << parser.GetCounterSize() << std::endl
00254 << "Shared key : " << parser.GetSharedKeyString() << std::endl
00255 << "Max transmitters: " << parser.GetMaxTransmitters() << std::endl;
00256
00257 CreateHEXFile( parser );
00258 std::cout << std::endl << parser.GetFilename() << " created!" << std::endl;
00259
00260 } catch( const std::exception & e ) {
00261 std::cout << "Error: " << e.what() << std::endl;
00262 } catch(...) {
00263 std::cout << "Unknown error" << std::endl;
00264 }
00265 }
00266