📄 cryptmis.c
字号:
0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, /* 20 - 27 */
0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, /* 28 - 2F */
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, /* 30 - 37 */
0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, /* 38 - 3F */
0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, /* 40 - 47 */
0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, /* 48 - 4F */
0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, /* 50 - 57 */
0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D, /* 58 - 5F */
0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60 - 67 */
0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* 68 - 6F */
0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, /* 70 - 77 */
0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, /* 78 - 7F */
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x06, 0x17, /* 80 - 87 */
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x09, 0x0A, 0x1B, /* 88 - 8F */
0x30, 0x31, 0x1A, 0x33, 0x34, 0x35, 0x36, 0x08, /* 90 - 97 */
0x38, 0x39, 0x3A, 0x3B, 0x04, 0x14, 0x3E, 0xFF, /* 98 - 9F */
0x41, 0xAA, 0x4A, 0xB1, 0x9F, 0xB2, 0x6A, 0xB5, /* A0 - A7 */
0xBB, 0xB4, 0x9A, 0x8A, 0xB0, 0xCA, 0xAF, 0xBC, /* A8 - AF */
0x90, 0x8F, 0xEA, 0xFA, 0xBE, 0xA0, 0xB6, 0xB3, /* B0 - B7 */
0x9D, 0xDA, 0x9B, 0x8B, 0xB7, 0xB8, 0xB9, 0xAB, /* B8 - BF */
0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9E, 0x68, /* C0 - C7 */
0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* C8 - CF */
0xAC, 0x69, 0xED, 0xEE, 0xEB, 0xEF, 0xEC, 0xBF, /* D0 - D7 */
0x80, 0xFD, 0xFE, 0xFB, 0xFC, 0xBA, 0xAE, 0x59, /* D8 - DF */
0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9C, 0x48, /* E0 - E7 */
0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* E8 - EF */
0x8C, 0x49, 0xCD, 0xCE, 0xCB, 0xCF, 0xCC, 0xE1, /* F0 - F7 */
0x70, 0xDD, 0xDE, 0xDB, 0xDC, 0x8D, 0x8E, 0xDF /* F8 - FF */
};
/* IBM Latin-1 Code Page 01047 (EBCDIC) to ISO 8859-1. */
static const BYTE ebcdicToAsciiTbl[] = {
0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, /* 00 - 07 */
0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */
0x10, 0x11, 0x12, 0x13, 0x9D, 0x0A, 0x08, 0x87, /* 10 - 17 */
0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1B, /* 20 - 27 */
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, /* 28 - 2F */
0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30 - 37 */
0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, /* 38 - 3F */
0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, /* 40 - 47 */
0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, /* 48 - 4F */
0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, /* 50 - 57 */
0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E, /* 58 - 5F */
0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, /* 60 - 67 */
0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, /* 68 - 6F */
0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, /* 70 - 77 */
0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, /* 78 - 7F */
0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80 - 87 */
0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, /* 88 - 8F */
0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, /* 90 - 97 */
0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4, /* 98 - 9F */
0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* A0 - A7 */
0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0x5B, 0xDE, 0xAE, /* A8 - AF */
0xAC, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, /* B0 - B7 */
0xBD, 0xBE, 0xDD, 0xA8, 0xAF, 0x5D, 0xB4, 0xD7, /* B8 - BF */
0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* C0 - C7 */
0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, /* C8 - CF */
0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, /* D0 - D7 */
0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF, /* D8 - DF */
0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* E0 - E7 */
0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, /* E8 - EF */
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* F0 - F7 */
0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F /* F8 - FF */
};
/* Convert a string to/from EBCDIC */
int asciiToEbcdic( char *string, int stringLen )
{
int i;
for( i = 0; i < stringLen; i++ )
string[ i ] = asciiToEbcdicTbl[ ( unsigned int ) string[ i ] ];
return( CRYPT_OK );
}
int ebcdicToAscii( char *string, int stringLen )
{
int i;
for( i = 0; i < stringLen; i++ )
string[ i ] = ebcdicToAsciiTbl[ ( unsigned int ) string[ i ] ];
return( CRYPT_OK );
}
#else
int asciiToEbcdic( char *string, int stringLen )
{
return( __atoe_l( string, stringLen ) < 0 ? \
CRYPT_ERROR_BADDATA : CRYPT_OK );
}
int ebcdicToAscii( char *string, int stringLen )
{
return( __etoa_l( string, stringLen ) < 0 ? \
CRYPT_ERROR_BADDATA : CRYPT_OK );
}
#endif /* USE_ETOA */
/* Convert a string to EBCDIC via a temporary buffer, used whem passing an
ASCII string to a system function */
char *bufferToEbcdic( char *buffer, const char *string )
{
strcpy( buffer, string );
asciiToEbcdic( buffer, strlen( string ) );
return( buffer );
}
/* Table for ctype functions that explicitly use the ASCII character set */
#define A ASCII_ALPHA
#define L ASCII_LOWER
#define N ASCII_NUMERIC
#define S ASCII_SPACE
#define U ASCII_UPPER
#define X ASCII_HEX
#define AL ( A | L )
#define AU ( A | U )
#define ANX ( A | N | X )
#define AUX ( A | U | X )
const BYTE asciiCtypeTbl[ 256 ] = {
/* 00 01 02 03 04 05 06 07 */
0, 0, 0, 0, 0, 0, 0, 0,
/* 08 09 0A 0B 0C 0D 0E 0F */
0, 0, 0, 0, 0, 0, 0, 0,
/* 10 11 12 13 14 15 16 17 */
0, 0, 0, 0, 0, 0, 0, 0,
/* 18 19 1A 1B 1C 1D 1E 1F */
0, 0, 0, 0, 0, 0, 0, 0,
/* ! " # $ % & ' */
A, A, A, A, A, A, A, A,
/* ( ) * + , - . / */
A, A, A, A, A, A, A, A,
/* 0 1 2 3 4 5 6 7 */
ANX, ANX, ANX, ANX, ANX, ANX, ANX, ANX,
/* 8 9 : ; < = > ? */
ANX, ANX, A, A, A, A, A, A,
/* @ A B C D E F G */
A, AUX, AUX, AUX, AUX, AUX, AUX, AU,
/* H I J K L M N O */
AU, AU, AU, AU, AU, AU, AU, AU,
/* P Q R S T U V W */
AU, AU, AU, AU, AU, AU, AU, AU,
/* X Y Z [ \ ] ^ _ */
AU, AU, AU, A, A, A, A, A,
/* ` a b c d e f g */
A, AL, AL, AL, AL, AL, AL, AL,
/* h i j k l m n o */
AL, AL, AL, AL, AL, AL, AL, AL,
/* p q r s t u v w */
AL, AL, AL, AL, AL, AL, AL, AL,
/* x y z { | } ~ DL */
AL, AL, AL, A, A, A, A, A,
/* High-bit-set characters */
0
};
/* stricmp()/strnicmp() versions that explicitly use the ASCII character
set. In order for collation to be handled properly, we have to convert
to EBCDIC and use the local stricmp()/strnicmp() */
int strCompare( const char *src, const char *dest, int length )
{
BYTE buffer1[ MAX_ATTRIBUTE_SIZE ], buffer2[ MAX_ATTRIBUTE_SIZE ];
if( length > MAX_ATTRIBUTE_SIZE )
return( 1 ); /* Invalid length */
/* Virtually all strings are 7-bit ASCII, the following optimisation
speeds up checking, particularly cases where we're walking down a
list of keywords looking for a match */
if( *src < 0x80 && *dest < 0x80 && \
toLower( *src ) != toLower( *dest ) )
return( 1 ); /* Not equal */
/* Convert the strings to EBCDIC and use a native compare */
src = bufferToEbcdic( buffer1, src );
dest = bufferToEbcdic( buffer2, dest );
return( strnicmp( src, dest, length ) );
}
int strCompareZ( const char *src, const char *dest )
{
const int length = strlen( src );
if( length != strlen( dest ) )
return( 1 ); /* Lengths differ */
return( strCompare( src, dest, length ) );
}
/* sprintf() that takes an ASCII format string */
int sPrintf( char *buffer, const char *format, ... )
{
BYTE formatBuffer[ MAX_ATTRIBUTE_SIZE ];
va_list argPtr;
#ifndef NDEBUG
int i;
#endif /* NDEBUG */
int status;
#ifndef NDEBUG
/* Make sure that we don't have any string args, which would require
their own conversion to EBCDIC */
for( i = 0; i < strlen( format ) - 1; i++ )
if( format[ i ] == '%' && format[ i + 1 ] == 's' )
assert( NOTREACHED );
#endif /* NDEBUG */
format = bufferToEbcdic( formatBuffer, format );
va_start( argPtr, format );
status = vsprintf( buffer, format, argPtr );
if( status > 0 )
ebcdicToAscii( buffer, status );
va_end( argPtr );
return( status );
}
/* atio() that takes an ASCII string */
int aToI( const char *str )
{
BYTE buffer[ 16 ];
/* The maximum length of a numeric string value that can be converted
to a 4-byte integer is considered as 10 characters (9,999,999,999) */
strncpy( buffer, str, 10 );
buffer[ 10 ] = '\0';
asciiToEbcdic( buffer, strlen( buffer ) );
return( atoi( buffer ) );
}
#endif /* EBCDIC_CHARS */
/****************************************************************************
* *
* Safe Text-line Read Functions *
* *
****************************************************************************/
/* Process a MIME header line. When we read data we're mostly looking for
the EOL marker. If we find more data than will fit in the input buffer,
we discard it until we find an EOL. As a secondary concern, we want to
strip leading, trailing, and repeated whitespace. We handle the former
by setting the seen-whitespace flag to true initially, this treats any
whitespace at the start of the line as superfluous and strips it. We also
handle continued lines, denoted by a semicolon as the last non-whitespace
character. Stripping of repeated whitespace is also handled by the
seenWhitespace flag, stripping of trailing whitespace is handled by
walking back through any final whitespace once we see the EOL, and
continued lines are handled by setting the seenSemicolon flag if we see a
semicolon as the last non-whitespace character.
Finally, we also need to handle generic DOS attacks. If we see more than
10K chars in a line, we bail out */
typedef struct {
BOOLEAN seenWhitespace, seenSemicolon;
int totalChars, maxSize, bufPos;
} MIME_STATE_INFO;
/* Initialise the MIME line buffer state. We set the seen-whitespace flag
initially to strip leading whitespace */
void initMIMEstate( MIME_STATE *mimeState, const int maxSize )
{
MIME_STATE_INFO *state = ( MIME_STATE_INFO * ) mimeState;
assert( isWritePtr( state, sizeof( MIME_STATE_INFO ) ) );
assert( sizeof( MIME_STATE_INFO ) <= sizeof( MIME_STATE ) );
memset( state, 0, sizeof( MIME_STATE_INFO ) );
state->seenWhitespace = TRUE; /* Catch leading whitespace */
state->maxSize = maxSize;
}
/* Add a character to the line buffer with special-case MIME-specific
processing */
int addMIMEchar( MIME_STATE *mimeState, char *buffer, int ch )
{
MIME_STATE_INFO *state = ( MIME_STATE_INFO * ) mimeState;
assert( isWritePtr( state, sizeof( MIME_STATE_INFO ) ) );
assert( buffer != NULL );
/* Don't try and process excessively long inputs, which are probably
DOSes */
if( state->totalChars++ > 10000 )
return( CRYPT_ERROR_OVERFLOW );
/* If we're over the maximum buffer size, the only character we recognise
is EOL */
if( ( state->bufPos > state->maxSize - 8 ) && ( ch != '\n' ) )
return( CRYPT_OK );
/* Process EOL */
if( ch == '\n' )
{
/* Strip trailing whitespace. At this point it's all been
canonicalised so we don't need to check for anything other than
spaces */
while( state->bufPos && buffer[ state->bufPos - 1 ] == ' ' )
state->bufPos--;
/* If we've seen a semicolon as the last non-whitespace char, the
line continues on the next one */
if( state->seenSemicolon )
{
state->seenSemicolon = FALSE;
return( CRYPT_OK );
}
/* We're done */
buffer[ state->bufPos ] = '\0';
return( OK_SPECIAL );
}
/* Process whitespace. We can't use isspace() for this because it
includes all sorts of extra control characters */
if( ch == ' ' || ch == '\t' )
{
if( state->seenWhitespace )
/* Ignore leading and repeated whitespace */
return( CRYPT_OK );
ch = ' '; /* Canonicalise whitespace */
}
/* Process any remaining chars */
if( ch != '\r' )
{
if( !( isPrint( ch ) ) )
return( CRYPT_ERROR_BADDATA );
buffer[ state->bufPos++ ] = ch;
state->seenWhitespace = ( ch == ' ' ) ? TRUE : FALSE;
state->seenSemicolon = \
( ch == ';' || ( state->seenSemicolon && \
state->seenWhitespace ) ) ? \
TRUE : FALSE;
}
return( CRYPT_OK );
}
/* Wrap up the MIME line processing */
int endMIMEstate( MIME_STATE *mimeState )
{
MIME_STATE_INFO *state = ( MIME_STATE_INFO * ) mimeState;
assert( isWritePtr( state, sizeof( MIME_STATE_INFO ) ) );
return( state->bufPos );
}
/****************************************************************************
* *
* Base64 En/Decoding Functions *
* *
****************************************************************************/
/* Encode/decode tables from RFC 1113 */
#define BPAD '=' /* Padding for odd-sized output */
#define BERR 0xFF /* Illegal char marker */
#define BEOF 0x7F /* EOF marker (padding char or EOL) */
static const FAR_BSS char binToAscii[] = \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -