| Remote Access Control |

# createtxhex.cpp

Go to the documentation of this file.

    00001 // This file has been prepared for Doxygen automatic documentation generation.
    00045 #include "hexfile.h"
    00046 #include <sstream>
    00047 #include <iomanip>
    00048 #include <string>
    00049 #include <stdexcept>
    00050 #include <vector>
    00051 #include <fstream>
    00052 #include <algorithm>
    00053
    00054
    00055
    00057 class ParameterParser
    00058 {
    00059 private:
    00060         std::string m_filename;
    00061         size_t m_keySize;
    00062         size_t m_serialNoSize;
    00063         size_t m_counterSize;
    00064         std::vector< byte > m_sharedKey;
    00065         std::vector< byte > m_secretKey;
    00066         std::vector< byte > m_serialNo;
    00067         std::vector< byte > m_counterValue;
    00068
    00070         std::vector< byte > ParseHexString( const std::string & hexString ) const;
    00072         std::string CreateHexString( const std::vector< byte > & byteVector ) const;
    00073
    00074 public:
    00076         ParameterParser( size_t argc, const char * * argv );
    00077         ~ParameterParser() {}
    00078
    00079         //
    00080         // Query methods.
    00081         //
    00082         const std::string & GetFilename() const { return m_filename; }
    00083         size_t GetKeySize() const { return m_keySize; }
    00084         size_t GetSerialNoSize() const { return m_serialNoSize; }
    00085         size_t GetCounterSize() const { return m_counterSize; }
    00086         const std::vector< byte > & GetSharedKey() const { return m_sharedKey; }
    00087         const std::vector< byte > & GetSecretKey() const { return m_secretKey; }
    00088         const std::vector< byte > & GetSerialNo() const { return m_serialNo; }
    00089         const std::vector< byte > & GetCounterValue() const { return m_counterValue; }
    00090
    00091         std::string GetSharedKeyString() const { return CreateHexString( GetSharedKey() ); }
    00092         std::string GetSecretKeyString() const { return CreateHexString( GetSecretKey() ); }
    00093         std::string GetSerialNoString() const { return CreateHexString( GetSerialNo() ); }
    00094         std::string GetCounterValueString() const { return CreateHexString( GetCounterValue() ); }
    00095 };
    00096
    00097
    00098
    00099 std::vector< byte > ParameterParser::ParseHexString( const std::string & hexString ) const
    00100 {
    00101         // String must be even number of hex digits.
    00102         if( hexString.size() % 2 != 0 ) {
    00103                 throw std::runtime_error( "Hex string does not have even character count" );
    00104         }
    00105
    00106         //
    00107         // Parse hex digit pairs and insert into byte vector.
    00108         //
    00109         std::vector< byte > bytes;
    00110         for( size_t idx = 0; idx < hexString.size(); idx += 2 ) {
    00111                 std::istringstream iss( hexString.substr( idx, 2 ) );
    00112                 byte data;
    00113                 iss >> std::hex >> data;
    00114                 if( !iss ) {
    00115                         throw std::runtime_error( "Error parsing hex string \"" + hexString + "\"" );
    00116                 }
    00117                 bytes.push_back( data );
    00118         }
    00119         return bytes;
    00120 }
    00121
    00122
    00123
    00124 std::string ParameterParser::CreateHexString( const std::vector< byte > & byteVector ) const
    00125 {
    00126         std::ostringstream oss;
    00127         oss << std::setfill('0') << std::hex;
    00128
    00129         // Add all byte last byte with spaces in between.
    00130         for( size_t idx = 0; idx < byteVector.size() - 1; ++idx ) {
    00131                 oss << std::setw(2) << byteVector.at( idx ) << ' ';
    00132         }
    00133
    00134         // Add last byte.
    00135         if( byteVector.size() > 0 ) {
    00136                 oss << std::setw(2) << byteVector.at( byteVector.size()-1 );
    00137         }
    00138
    00139         return oss.str();
    00140 }
    00141
    00142
    00143
    00144 ParameterParser::ParameterParser( size_t argc, const char * * argv )
    00145 {
    00146         // Check that argument count is valid.
    00147         if( argc != 9 ) {
    00148                 std::cout << "Parameters:\n"
    00149                         "  filename     - Filename for resulting Intel HEX file\n"
    00150                         "  keysize      - Size in bits of the AES secret and shared keys (128, 192 or 256)\n"
    00151                         "  serialnosize - Size in bytes of the serial number (1, 2 or 4)\n"
    00152                         "  countersize  - Size in bytes of the sequential counter (1, 2 or 4)\n"
    00153                         "  sharedkey    - Hex representation of the shared key (32, 48 or 64 digits)\n"
    00154                         "  secretkey    - Hex representation of the secret key (32, 48 or 64 digits)\n"
    00155                         "  serialno     - Hex representation of the serial number (2, 4 or 8 digits)\n"
    00156                         "  countervalue - Hex representation of the current counter value (2, 4 or 8 digits)\n"
    00157                         << std::endl;
    00158                 throw std::runtime_error( "Not exactly 8 parameters" );
    00159         }
    00160
    00161         //
    00162         // Create strings or string streams from argument character arrays.
    00163         //
    00164         std::string arg1( argv[1] ); // Filename
    00165         std::istringstream arg2( argv[2] ); // Key size
    00166         std::istringstream arg3( argv[3] ); // Serial no size
    00167         std::istringstream arg4( argv[4] ); // Counter size
    00168         std::string arg5( argv[5] ); // Shared key
    00169         std::string arg6( argv[6] ); // Secret key
    00170         std::string arg7( argv[7] ); // Serial number
    00171         std::string arg8( argv[8] ); // Counter Value
    00172
    00173         //
    00174         // Copy string arguments and parse non-string arguments.
    00175         //
    00176         m_filename = arg1;
    00177
    00178         arg2 >> m_keySize;
    00179         if( !arg2 ) {
    00180                 throw std::runtime_error( "Error parsing key size argument" );
    00181         }
    00182
    00183         arg3 >> m_serialNoSize;
    00184         if( !arg3 ) {
    00185                 throw std::runtime_error( "Error parsing serial no size argument" );
    00186         }
    00187
    00188         arg4 >> m_counterSize;
    00189         if( !arg4 ) {
    00190                 throw std::runtime_error( "Error parsing counter size argument" );
    00191         }
    00192
    00193         m_sharedKey = ParseHexString( arg5 );
    00194         m_secretKey = ParseHexString( arg6 );
    00195         m_serialNo = ParseHexString( arg7 );
    00196         m_counterValue = ParseHexString( arg8 );
    00197
    00198         //
    00199         // Check argument validity.
    00200         //
    00201         if( m_keySize != 128 && m_keySize != 192 && m_keySize != 256 ) {
    00202                 throw std::runtime_error( "Key size is not 128, 192 or 256 bits" );
    00203         }
    00204
    00205         if( m_serialNoSize != 1 && m_serialNoSize != 2 && m_serialNoSize != 4 ) {
    00206                 throw std::runtime_error( "Serial no is not 1, 2 or 4 bytes" );
    00207         }
    00208
    00209         if( m_counterSize != 1 && m_counterSize != 2 && m_counterSize != 4 ) {
    00210                 throw std::runtime_error( "Counter is not 1, 2 or 4 bytes" );
    00211         }
    00212
    00213         if( m_sharedKey.size() != m_keySize / 8 ) {
    00214                 throw std::runtime_error( "Shared key has invalid length" );
    00215         }
    00216
    00217         if( m_secretKey.size() != m_keySize / 8 ) {
    00218                 throw std::runtime_error( "Secret key has invalid length" );
    00219         }
    00220
    00221         if( m_serialNo.size() != m_serialNoSize ) {
    00222                 throw std::runtime_error( "Serial number has invalid length" );
    00223         }
    00224
    00225         if( m_counterValue.size() != m_counterSize ) {
    00226                 throw std::runtime_error( "Counter value has invalid length" );
    00227         }
    00228 }
    00229
    00230
    00231
    00233 void CreateHEXFile( const ParameterParser & parser )
    00234 {
    00235         HEXFile hexData;
    00236         std::ofstream outFile( parser.GetFilename().c_str() );
    00237
    00238         // Prepare serial number bytes.
    00239         HEXRecord serialNo;
    00240         std::vector< byte > serialNoReversed = parser.GetSerialNo();
    00241         std::reverse( serialNoReversed.begin(), serialNoReversed.end() );
    00242         serialNo << serialNoReversed;
    00243
    00244         // Prepare counter value bytes.
    00245         HEXRecord counterValue;
    00246         std::vector< byte > counterValueReversed = parser.GetCounterValue();
    00247         std::reverse( counterValueReversed.begin(), counterValueReversed.end() );
    00248         counterValue << counterValueReversed;
    00249
    00250         // Prepare secret key bytes.
    00251         HEXRecord secretKey;
    00252         secretKey << parser.GetSecretKey();
    00253
    00254         // Prepare shared key bytes.
    00255         HEXRecord sharedKey;
    00256         sharedKey << parser.GetSharedKey();
    00257
    00258         // Add records to HEX file.
    00259         hexData << serialNo << counterValue << secretKey << sharedKey;
    00260
    00261         // Write to disk.
    00262         outFile << hexData;
    00263 }
    00264
    00265
    00266
    00267 int main( size_t argc, const char * * argv )
    00268 {
    00269         try {
    00270                 const std::string endian( " (Byte order reversed in HEX file)" );
    00271                 ParameterParser parser( argc, argv );
    00272                 std::cout << "Filename      : " << parser.GetFilename() << std::endl
    00273                         << "Key size      : " << parser.GetKeySize() << std::endl
    00274                         << "Serial no size: " << parser.GetSerialNoSize() << std::endl
    00275                         << "Counter size  : " << parser.GetCounterSize() << std::endl
    00276                         << "Shared key    : " << parser.GetSharedKeyString() << std::endl
    00277                         << "Secret key    : " << parser.GetSecretKeyString() << std::endl
    00278                         << "Serial no     : " << parser.GetSerialNoString() << endian << std::endl
    00279                         << "Counter value : " << parser.GetCounterValueString() << endian << std::endl;
    00280
    00281                 CreateHEXFile( parser );
    00282                 std::cout << std::endl << parser.GetFilename() << " created!" << std::endl;
    00283
    00284         } catch( const std::exception & e ) {
    00285                 std::cout << "Error: " << e.what() << std::endl;
    00286         } catch(...) {
    00287                 std::cout << "Unknown error" << std::endl;
    00288         }
    00289 }
    00290

@DOC_TITLE@