summaryrefslogtreecommitdiffstats
path: root/pki/base/native-tools/src/tkstool/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/native-tools/src/tkstool/util.c')
-rw-r--r--pki/base/native-tools/src/tkstool/util.c640
1 files changed, 640 insertions, 0 deletions
diff --git a/pki/base/native-tools/src/tkstool/util.c b/pki/base/native-tools/src/tkstool/util.c
new file mode 100644
index 000000000..5fda75f8e
--- /dev/null
+++ b/pki/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;
+}
+
+