示例#1
0
static int readAVABitstring( INOUT STREAM *stream, 
							 OUT_LENGTH_SHORT_Z int *length, 
							 OUT_TAG_ENCODED_Z int *stringTag )
	{
	long streamPos;
	int bitStringLength, innerTag, innerLength = DUMMY_INIT, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( length, sizeof( int ) ) );
	assert( isWritePtr( stringTag, sizeof( int ) ) );

	/* Bitstrings are used for uniqueIdentifiers, however these usually 
	   encapsulate something else:

		BIT STRING {
			IA5String 'xxxxx'
			}

	   so we try and dig one level deeper to find the encapsulated string if 
	   there is one.  This gets a bit complicated because we have to 
	   speculatively try and decode the inner content and if that fails 
	   assume that it's raw bitstring data.  First we read the bitstring 
	   wrapper and remember where the bitstring data starts */
	status = readBitStringHole( stream, &bitStringLength, 2, DEFAULT_TAG );
	if( cryptStatusError( status ) )
		return( status );
	streamPos = stell( stream );

	/* Then we try and read any inner content */
	status = innerTag = peekTag( stream );
	if( !cryptStatusError( status ) )
		status = readGenericHole( stream, &innerLength, 1, innerTag );
	if( !cryptStatusError( status ) && \
		bitStringLength == sizeofObject( innerLength ) )
		{
		/* There was inner content present, treat it as the actual type and 
		   value of the bitstring.  This assumes that the inner content is
		   a string data type, which always seems to be the case (in any 
		   event it's not certain what we should be returning to the user if
		   we find, for example, a SEQUENCE with further encapsulated 
		   content at this point) */
		*stringTag = innerTag;
		*length = innerLength;

		return( CRYPT_OK );
		}

	/* We couldn't identify any (obvious) inner content, it must be raw
	   bitstring data.  Unfortunately we have no idea what format this is
	   in, it could in fact really be raw binary data but never actually 
	   seems to be this, it's usually ASCII text so we mark it as such and 
	   let the string-read routines sort it out */
	sClearError( stream );
	sseek( stream, streamPos );
	*stringTag = BER_STRING_IA5;
	*length = bitStringLength;

	return( CRYPT_OK );
	}
示例#2
0
static int readAVA( INOUT STREAM *stream, 
					OUT_INT_Z int *type, 
					OUT_LENGTH_SHORT_Z int *length, 
					OUT_TAG_ENCODED_Z int *stringTag )
	{
	const DN_COMPONENT_INFO *dnComponentInfo;
	BYTE oid[ MAX_OID_SIZE + 8 ];
	int oidLength, tag, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( type, sizeof( int ) ) );
	assert( isWritePtr( length, sizeof( int ) ) );
	assert( isWritePtr( stringTag, sizeof( int ) ) );

	/* Clear return values */
	*type = 0;
	*length = 0;
	*stringTag = 0;

	/* Read the start of the AVA and determine the type from the 
	   AttributeType field.  If we find something that we don't recognise we 
	   indicate it as a non-component type that can be read or written but 
	   not directly accessed by the user (although it can still be accessed 
	   using the cursor functions) */
	readSequence( stream, NULL );
	status = readEncodedOID( stream, oid, MAX_OID_SIZE, &oidLength, 
							 BER_OBJECT_IDENTIFIER );
	if( cryptStatusError( status ) )
		return( status );
	dnComponentInfo = findDNInfoByOID( oid, oidLength );
	if( dnComponentInfo == NULL )
		{
		/* If we don't recognise the component type at all, skip it */
		status = readUniversal( stream );
		return( cryptStatusError( status ) ? status : OK_SPECIAL );
		}
	*type = dnComponentInfo->type;

	/* We've reached the data value, make sure that it's in order.  When we
	   read the wrapper around the string type with readGenericHole() we have 
	   to allow a minimum length of zero instead of one because of broken 
	   AVAs with zero-length strings */
	tag = peekTag( stream );
	if( cryptStatusError( tag ) )
		return( tag );
	if( tag == BER_BITSTRING )
		return( readAVABitstring( stream, length, stringTag ) );
	*stringTag = tag;
	return( readGenericHole( stream, length, 0, tag ) );
	}
示例#3
0
static int readConfigOption( INOUT STREAM *stream, 
							 IN_HANDLE CRYPT_USER iCryptUser )
	{
	CRYPT_ATTRIBUTE_TYPE attributeType;
	const BUILTIN_OPTION_INFO *builtinOptionInfoPtr;
	MESSAGE_DATA msgData;
	void *dataPtr DUMMY_INIT_PTR;
	long optionCode;
	int value, tag, length, status;

	/* Read the wrapper and option index and map it to the actual option.  
	   If we find an unknown index or one that shouldn't be writeable to 
	   persistent storage, we skip it and continue.  This is done to handle 
	   new options that may have been added after this version of cryptlib 
	   was built (for unknown indices) and because the stored configuration 
	   options are an untrusted source so we have to check for attempts to 
	   feed in bogus values (for non-writeable options) */
	readSequence( stream, NULL );
	status = readShortInteger( stream, &optionCode );
	if( cryptStatusError( status ) )
		return( status );
	if( optionCode < 0 || optionCode > LAST_OPTION_INDEX )
		{
		/* Unknown option, ignore it */
		return( readUniversal( stream ) );
		}
	builtinOptionInfoPtr = getBuiltinOptionInfoByCode( optionCode );
	if( builtinOptionInfoPtr == NULL || \
		builtinOptionInfoPtr->index < 0 || \
		builtinOptionInfoPtr->index > LAST_OPTION_INDEX || \
		builtinOptionInfoPtr->index == CRYPT_UNUSED )
		{
		/* Unknown option, ignore it */
		return( readUniversal( stream ) );
		}
	attributeType = builtinOptionInfoPtr->option;

	/* Read the option value and set the option.  We don't treat a failure 
	   to set the option as a problem since the user probably doesn't want 
	   the entire system to fail because of a bad configuration option, and 
	   in any case we'll fall back to a safe default value */
	status = tag = peekTag( stream );
	if( cryptStatusError( status ) )
		return( status );
	if( tag == BER_BOOLEAN || tag == BER_INTEGER )
		{
		/* It's a numeric value, read the appropriate type and try and set 
		   the option */
		if( tag == BER_BOOLEAN )
			status = readBoolean( stream, &value );
		else
			{
			long integer;

			status = readShortInteger( stream, &integer );
			if( cryptStatusOK( status ) )
				value = ( int ) integer;
			}
		if( cryptStatusError( status ) )
			return( status );
		( void ) krnlSendMessage( iCryptUser, IMESSAGE_SETATTRIBUTE, 
								  &value, attributeType );
		return( CRYPT_OK );
		}

	/* It's a string value, set the option straight from the encoded data */
	status = readGenericHole( stream, &length, 1, BER_STRING_UTF8 );
	if( cryptStatusOK( status ) )
		status = sMemGetDataBlock( stream, &dataPtr, length );
	if( cryptStatusOK( status ) )
		status = sSkip( stream, length, SSKIP_MAX );
	if( cryptStatusError( status ) )
		return( status );
	setMessageData( &msgData, dataPtr, length );
	( void ) krnlSendMessage( iCryptUser, IMESSAGE_SETATTRIBUTE_S, 
							  &msgData, attributeType );

	return( CRYPT_OK );
	}
示例#4
0
文件: obj_qry.c 项目: TellarHK/wwiv
static int getObjectInfo( INOUT STREAM *stream, 
						  OUT QUERY_INFO *queryInfo )
	{
	const long startPos = stell( stream );
	long value;
	int tag, length, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( queryInfo, sizeof( QUERY_INFO ) ) );

	/* Clear return value */
	memset( queryInfo, 0, sizeof( QUERY_INFO ) );

	/* We always need at least MIN_CRYPT_OBJECTSIZE more bytes to do
	   anything */
	if( sMemDataLeft( stream ) < MIN_CRYPT_OBJECTSIZE )
		return( CRYPT_ERROR_UNDERFLOW );

	/* Get the type, length, and version information */
	status = getStreamObjectLength( stream, &length );
	if( cryptStatusError( status ) )
		return( status );
	queryInfo->formatType = CRYPT_FORMAT_CRYPTLIB;
	queryInfo->size = length;
	tag = peekTag( stream );
	if( cryptStatusError( tag ) )
		return( tag );
	readGenericHole( stream, NULL, 16, tag );
	status = readShortInteger( stream, &value );
	if( cryptStatusError( status ) )
		return( status );
	queryInfo->version = value;
	switch( tag )
		{
		case BER_SEQUENCE:
			/* This could be a signature or a PKC-encrypted key, see what
			   follows */
			switch( value )
				{
				case KEYTRANS_VERSION:
				case KEYTRANS_EX_VERSION:
					queryInfo->type = CRYPT_OBJECT_PKCENCRYPTED_KEY;
					break;

				case SIGNATURE_VERSION:
				case SIGNATURE_EX_VERSION:
					queryInfo->type = CRYPT_OBJECT_SIGNATURE;
					break;

				default:
					return( CRYPT_ERROR_BADDATA );
				}
			if( value == KEYTRANS_VERSION || value == SIGNATURE_VERSION )
				queryInfo->formatType = CRYPT_FORMAT_CMS;
			break;

		case MAKE_CTAG( CTAG_RI_KEYAGREE ):
			/* It's CMS' wierd X9.42-inspired key agreement mechanism, we
			   can't do much with this (mind you neither can anyone else)
			   so we should probably really treat it as a 
			   CRYPT_ERROR_BADDATA if we encounter it rather than just 
			   ignoring it */
			queryInfo->type = CRYPT_OBJECT_NONE;
			DEBUG_DIAG(( "Found keyAgreeRecipientInfo" ));
			assert( DEBUG_WARN );
			break;

		case MAKE_CTAG( CTAG_RI_PWRI ):
			queryInfo->type = CRYPT_OBJECT_ENCRYPTED_KEY;
			break;

		default:
			queryInfo->type = CRYPT_OBJECT_NONE;
			if( tag > MAKE_CTAG( CTAG_RI_PWRI ) && \
				tag <= MAKE_CTAG( CTAG_RI_MAX ) )
				{
				/* This is probably a new RecipientInfo type, skip it */
				DEBUG_DIAG(( "Found unknown RecipientInfo %X", tag ));
				assert( DEBUG_WARN );
				break;
				}
			return( CRYPT_ERROR_BADDATA );
		}

	/* Reset the stream and make sure that all of the data is present */
	sseek( stream, startPos );
	return( sMemDataLeft( stream ) < queryInfo->size ? \
			CRYPT_ERROR_UNDERFLOW : CRYPT_OK );
	}
示例#5
0
文件: key_rdpub.c 项目: TRI0N/wwiv
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
	assert( isWritePtr( actionFlags, sizeof( int ) ) );

	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );

	/* Clear return value */
	*actionFlags = ACTION_PERM_NONE;

	/* Read the SubjectPublicKeyInfo header field and parameter data if
	   there's any present.  We read the outer wrapper in generic form since
	   it may be context-specific-tagged if it's coming from a keyset (RSA
	   public keys is the one place where PKCS #15 keys differ from X.509
	   ones) or something odd from CRMF */
	status = readGenericHole( stream, NULL, 8 + MIN_PKCSIZE_THRESHOLD + \
											RSAPARAM_MIN_E, DEFAULT_TAG );
	if( cryptStatusOK( status ) )
		status = readAlgoID( stream, &cryptAlgo, ALGOID_CLASS_PKC );
	if( cryptStatusError( status ) )
		return( status );
	if( cryptAlgo != CRYPT_ALGO_RSA )
		return( CRYPT_ERROR_BADDATA );

	/* Set the maximum permitted actions.  More restrictive permissions may 
	   be set by higher-level code if required and in particular if the key 
	   is a pure public key rather than merely the public portions of a 
	   private key then the actions will be restricted at that point to 
	   encrypt and signature-check only */
	*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, ACTION_PERM_ALL ) | \
				   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, ACTION_PERM_ALL ) | \
				   MK_ACTION_PERM( MESSAGE_CTX_SIGN, ACTION_PERM_ALL ) | \