diff options
Diffstat (limited to 'base/native-tools/src/tkstool/util.c')
-rw-r--r-- | base/native-tools/src/tkstool/util.c | 640 |
1 files changed, 640 insertions, 0 deletions
diff --git a/base/native-tools/src/tkstool/util.c b/base/native-tools/src/tkstool/util.c new file mode 100644 index 000000000..5fda75f8e --- /dev/null +++ b/base/native-tools/src/tkstool/util.c @@ -0,0 +1,640 @@ +/* --- BEGIN COPYRIGHT BLOCK --- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2007 Red Hat, Inc. + * All rights reserved. + * --- END COPYRIGHT BLOCK --- + */ + +#include "tkstool.h" + +static PRBool +IsValidHexCharacter( char byte ) +{ + switch( byte ) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'C': + case 'd': + case 'D': + case 'e': + case 'E': + case 'f': + case 'F': + { + /* Character may be converted into a hexadecimal number. */ + return PR_TRUE; + } + default: + { + return PR_FALSE; + } + } +} + + +static void +InsertUpperFourBits( char* byte, char bits ) +{ + switch( bits ) + { + case '0': + { + *byte &= ~( 1 << 7 ); + *byte &= ~( 1 << 6 ); + *byte &= ~( 1 << 5 ); + *byte &= ~( 1 << 4 ); + break; + } + case '1': + { + *byte &= ~( 1 << 7 ); + *byte &= ~( 1 << 6 ); + *byte &= ~( 1 << 5 ); + *byte |= ( 1 << 4 ); + break; + } + case '2': + { + *byte &= ~( 1 << 7 ); + *byte &= ~( 1 << 6 ); + *byte |= ( 1 << 5 ); + *byte &= ~( 1 << 4 ); + break; + } + case '3': + { + *byte &= ~( 1 << 7 ); + *byte &= ~( 1 << 6 ); + *byte |= ( 1 << 5 ); + *byte |= ( 1 << 4 ); + break; + } + case '4': + { + *byte &= ~( 1 << 7 ); + *byte |= ( 1 << 6 ); + *byte &= ~( 1 << 5 ); + *byte &= ~( 1 << 4 ); + break; + } + case '5': + { + *byte &= ~( 1 << 7 ); + *byte |= ( 1 << 6 ); + *byte &= ~( 1 << 5 ); + *byte |= ( 1 << 4 ); + break; + } + case '6': + { + *byte &= ~( 1 << 7 ); + *byte |= ( 1 << 6 ); + *byte |= ( 1 << 5 ); + *byte &= ~( 1 << 4 ); + break; + } + case '7': + { + *byte &= ~( 1 << 7 ); + *byte |= ( 1 << 6 ); + *byte |= ( 1 << 5 ); + *byte |= ( 1 << 4 ); + break; + } + case '8': + { + *byte |= ( 1 << 7 ); + *byte &= ~( 1 << 6 ); + *byte &= ~( 1 << 5 ); + *byte &= ~( 1 << 4 ); + break; + } + case '9': + { + *byte |= ( 1 << 7 ); + *byte &= ~( 1 << 6 ); + *byte &= ~( 1 << 5 ); + *byte |= ( 1 << 4 ); + break; + } + case 'a': + case 'A': + { + *byte |= ( 1 << 7 ); + *byte &= ~( 1 << 6 ); + *byte |= ( 1 << 5 ); + *byte &= ~( 1 << 4 ); + break; + } + case 'b': + case 'B': + { + *byte |= ( 1 << 7 ); + *byte &= ~( 1 << 6 ); + *byte |= ( 1 << 5 ); + *byte |= ( 1 << 4 ); + break; + } + case 'c': + case 'C': + { + *byte |= ( 1 << 7 ); + *byte |= ( 1 << 6 ); + *byte &= ~( 1 << 5 ); + *byte &= ~( 1 << 4 ); + break; + } + case 'd': + case 'D': + { + *byte |= ( 1 << 7 ); + *byte |= ( 1 << 6 ); + *byte &= ~( 1 << 5 ); + *byte |= ( 1 << 4 ); + break; + } + case 'e': + case 'E': + { + *byte |= ( 1 << 7 ); + *byte |= ( 1 << 6 ); + *byte |= ( 1 << 5 ); + *byte &= ~( 1 << 4 ); + break; + } + case 'f': + case 'F': + { + *byte |= ( 1 << 7 ); + *byte |= ( 1 << 6 ); + *byte |= ( 1 << 5 ); + *byte |= ( 1 << 4 ); + break; + } + } +} + + +static void +InsertLowerFourBits( char* byte, char bits ) +{ + switch( bits ) + { + case '0': + { + *byte &= ~( 1 << 3 ); + *byte &= ~( 1 << 2 ); + *byte &= ~( 1 << 1 ); + *byte &= ~( 1 << 0 ); + break; + } + case '1': + { + *byte &= ~( 1 << 3 ); + *byte &= ~( 1 << 2 ); + *byte &= ~( 1 << 1 ); + *byte |= ( 1 << 0 ); + break; + } + case '2': + { + *byte &= ~( 1 << 3 ); + *byte &= ~( 1 << 2 ); + *byte |= ( 1 << 1 ); + *byte &= ~( 1 << 0 ); + break; + } + case '3': + { + *byte &= ~( 1 << 3 ); + *byte &= ~( 1 << 2 ); + *byte |= ( 1 << 1 ); + *byte |= ( 1 << 0 ); + break; + } + case '4': + { + *byte &= ~( 1 << 3 ); + *byte |= ( 1 << 2 ); + *byte &= ~( 1 << 1 ); + *byte &= ~( 1 << 0 ); + break; + } + case '5': + { + *byte &= ~( 1 << 3 ); + *byte |= ( 1 << 2 ); + *byte &= ~( 1 << 1 ); + *byte |= ( 1 << 0 ); + break; + } + case '6': + { + *byte &= ~( 1 << 3 ); + *byte |= ( 1 << 2 ); + *byte |= ( 1 << 1 ); + *byte &= ~( 1 << 0 ); + break; + } + case '7': + { + *byte &= ~( 1 << 3 ); + *byte |= ( 1 << 2 ); + *byte |= ( 1 << 1 ); + *byte |= ( 1 << 0 ); + break; + } + case '8': + { + *byte |= ( 1 << 3 ); + *byte &= ~( 1 << 2 ); + *byte &= ~( 1 << 1 ); + *byte &= ~( 1 << 0 ); + break; + } + case '9': + { + *byte |= ( 1 << 3 ); + *byte &= ~( 1 << 2 ); + *byte &= ~( 1 << 1 ); + *byte |= ( 1 << 0 ); + break; + } + case 'a': + case 'A': + { + *byte |= ( 1 << 3 ); + *byte &= ~( 1 << 2 ); + *byte |= ( 1 << 1 ); + *byte &= ~( 1 << 0 ); + break; + } + case 'b': + case 'B': + { + *byte |= ( 1 << 3 ); + *byte &= ~( 1 << 2 ); + *byte |= ( 1 << 1 ); + *byte |= ( 1 << 0 ); + break; + } + case 'c': + case 'C': + { + *byte |= ( 1 << 3 ); + *byte |= ( 1 << 2 ); + *byte &= ~( 1 << 1 ); + *byte &= ~( 1 << 0 ); + break; + } + case 'd': + case 'D': + { + *byte |= ( 1 << 3 ); + *byte |= ( 1 << 2 ); + *byte &= ~( 1 << 1 ); + *byte |= ( 1 << 0 ); + break; + } + case 'e': + case 'E': + { + *byte |= ( 1 << 3 ); + *byte |= ( 1 << 2 ); + *byte |= ( 1 << 1 ); + *byte &= ~( 1 << 0 ); + break; + } + case 'f': + case 'F': + { + *byte |= ( 1 << 3 ); + *byte |= ( 1 << 2 ); + *byte |= ( 1 << 1 ); + *byte |= ( 1 << 0 ); + break; + } + } +} + + +PR_IMPLEMENT( void ) +TKS_ClearScreen() +{ +#if defined(XP_UNIX) && !defined(VMS) + system( "tput clear" ); +#else + system( "cls" ); +#endif +} + + +PR_IMPLEMENT( void ) +TKS_WaitForUser() +{ + int c; + + PR_fprintf( PR_STDOUT, "\n\n" ); + PR_fprintf( PR_STDOUT, "%s", CONTINUATION_MESSAGE ); +#if defined(VMS) + while((c = GENERIC_GETCHAR_NO_ECHO()) != '\r' && c != EOF && c != CTRL_C ) + ; +#else + while ((c = getc(stdin)) != '\n' && c != EOF && c != CTRL_C ) + ; +#endif + PR_fprintf( PR_STDOUT, "\n" ); +} + + +PR_IMPLEMENT( void ) +TKS_TypeProceedToContinue() +{ + int fd; + int i; + int count; + int c; + int rv = 0; +#ifdef XP_UNIX + cc_t orig_cc_min; + cc_t orig_cc_time; + tcflag_t orig_lflag; + struct termios tio; +#endif + char keystrokes[KEYSTROKES_TO_PROCEED + 1] = "\0\0\0\0\0\0\0\0\0"; + + /* display the continuation message */ + PR_fprintf( PR_STDOUT, "\n\n" ); + PR_fprintf( PR_STDOUT, "%s", PROCEED_MESSAGE ); + + /* turn off echo on stdin & return on 1 char instead of NL */ + fd = fileno( stdin ); + +#if defined( XP_UNIX ) && !defined( VMS ) + tcgetattr( fd, &tio ); + orig_lflag = tio.c_lflag; + orig_cc_min = tio.c_cc[VMIN]; + orig_cc_time = tio.c_cc[VTIME]; + tio.c_lflag &= ~ECHO; + tio.c_lflag &= ~ICANON; + tio.c_cc[VMIN] = 1; + tio.c_cc[VTIME] = 0; + tcsetattr( fd, TCSAFLUSH, &tio ); +#endif + + /* Get user input from keyboard strokes */ + count = 0; + while( count < KEYSTROKES_TO_PROCEED ) { +#ifdef VMS + c = GENERIC_GETCHAR_NOECHO(); +#elif XP_UNIX + c = getc( stdin ); +#else + c = getch(); +#endif + /* break on EOF */ + if( c == EOF ) { + rv = -1; + break; + } + + /* break on ^C */ + if( c == CTRL_C ) { + rv = -1; + break; + } + + /* save acceptable characters; silently throw anything else away */ + switch( count ) { + case 0: + switch( c ) { + case 'P': + case 'p': + /* acceptable character; save lowercase version */ + keystrokes[count] = 'p'; + break; + default: + /* unacceptable character; don't save it */ + continue; + } + break; + case 1: + switch( c ) { + case 'R': + case 'r': + /* acceptable character; save lowercase version */ + keystrokes[count] = 'r'; + break; + default: + /* unacceptable character; don't save it */ + continue; + } + break; + case 2: + switch( c ) { + case 'O': + case 'o': + /* acceptable character; save lowercase version */ + keystrokes[count] = 'o'; + break; + default: + /* unacceptable character; don't save it */ + continue; + } + break; + case 3: + switch( c ) { + case 'C': + case 'c': + /* acceptable character; save lowercase version */ + keystrokes[count] = 'c'; + break; + default: + /* unacceptable character; don't save it */ + continue; + } + break; + case 4: + switch( c ) { + case 'E': + case 'e': + /* acceptable character; save lowercase version */ + keystrokes[count] = 'e'; + break; + default: + /* unacceptable character; don't save it */ + continue; + } + break; + case 5: + switch( c ) { + case 'E': + case 'e': + /* acceptable character; save lowercase version */ + keystrokes[count] = 'e'; + break; + default: + /* unacceptable character; don't save it */ + continue; + } + break; + case 6: + switch( c ) { + case 'D': + case 'd': + /* acceptable character; save lowercase version */ + keystrokes[count] = 'd'; + break; + default: + /* unacceptable character; don't save it */ + continue; + } + break; + case 7: + switch( c ) { + case '\n': + case '\r': + /* acceptable character; save lowercase version */ + keystrokes[count] = '\n'; + break; + default: + /* unacceptable character; don't save it */ + continue; + } + break; + default: + /* unacceptable character; don't save it */ + continue; + } + + /* adjust the character count appropriately */ + count++; + + /* redisplay the message */ + PR_fprintf( PR_STDOUT, "\r%s", PROCEED_MESSAGE ); + + /* display the characters input so far */ + for( i = 0 ; i < count ; i++ ) { + PR_fprintf( PR_STDOUT, + "%c", + keystrokes[i] ); + } + } +} + + +PR_IMPLEMENT( void ) +TKS_AdjustOddParity( PRUint8 *key ) +{ + PRIntn i; + PRIntn j; + PRIntn one; + + /* this must be performed for each DES-sized (8-byte) chunk */ + for( j = 0 ; j < DES_LENGTH ; j++ ) { + for( one = 0, i = key[j] ; i ; i >>= 1 ) { + if( i & 1 ) { + one++; + } + } + + key[j] ^= !( one & 1 ); + } +} + + +PR_IMPLEMENT( void ) +TKS_StringToHex( PRUint8 *key, + PRIntn len, + PRUint8 *hex_key, + PRIntn hex_len ) +{ + PRIntn i; + + for( i = 0 ; i < len ; i++ ) { + ( void ) PR_snprintf( ( char * ) &( hex_key[ ( 2 * i ) ] ), + hex_len, + "%X", + ( key[i] >> 4 ) & 0x0F ); + ( void ) PR_snprintf( ( char * ) &( hex_key[ ( 2 * i ) + 1 ] ), + hex_len, + "%X", + key[i] & 0x0F ); + } + + hex_key[ ( hex_len - 1 ) ] = '\0'; + + return; +} + + +/* Convert a signed character string such as "de43a58f. . ." into an */ +/* unsigned character string which is one/half the size of the input */ +PR_IMPLEMENT( PRBool ) +TKS_ConvertStringOfHexCharactersIntoBitStream( char* input, + PRIntn input_bytes, + PRUint8* output ) +{ + PRIntn i; + PRIntn output_bytes; + + /* Check to be sure that the input string contains an */ + /* "even" number of bytes so that it may be converted. */ + if( input_bytes % 2 ) { + ( void ) PR_fprintf( PR_STDERR, + "ERROR: " + "ConvertStringOfHexCharactersIntoBitStream() " + "contained an illegal " + "input byte length of %d bytes!\r\n", + input_bytes ); + return PR_FALSE; + } + + output_bytes = ( input_bytes / 2 ); + + for( i = 0; i < output_bytes; i++ ) { + if( IsValidHexCharacter( input[ ( 2 * i ) ] ) && + IsValidHexCharacter( input[ ( 2 * i ) + 1 ] ) ) { + InsertUpperFourBits( ( char* ) &( output[i] ), input[ ( 2 * i ) ] ); + InsertLowerFourBits( ( char* ) &( output[i] ), input[ ( 2 * i ) + 1 ] ); + } else { + ( void ) PR_fprintf( PR_STDERR, + "ERROR: " + "ConvertStringOfHexCharactersIntoBitStream() " + "contained a " + "byte in the input string which can not be " + "converted!\r\n" ); + return PR_FALSE; + } + } + + return PR_TRUE; +} + + |