⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asn1keys.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 3 页
字号:
						const void *component4, const int component4Length )
	{
	STREAM stream;
	const int comp1Size = sizeofInteger( component1, component1Length );
	const int comp2Size = sizeofInteger( component2, component2Length );
	const int comp3Size = ( component3 == NULL ) ? 0 : \
						  sizeofInteger( component3, component3Length );
	const int comp4Size = ( component4 == NULL ) ? 0 : \
						  sizeofInteger( component4, component4Length );
	const int parameterSize = ( cryptAlgo == CRYPT_ALGO_DSA ) ? \
				( int ) sizeofObject( comp1Size + comp2Size + comp3Size ) : \
							  ( cryptAlgo == CRYPT_ALGO_KEA ) ? \
				( int) sizeofObject( 10 ) : 0;
	const int componentSize = ( cryptAlgo == CRYPT_ALGO_RSA ) ? \
				( int ) sizeofObject( comp1Size + comp2Size ) : \
							  ( cryptAlgo == CRYPT_ALGO_KEA ) ? \
				component4Length : comp4Size;
	int totalSize, status;

	sMemOpen( &stream, buffer, ( buffer == NULL ) ? 0 : STREAMSIZE_UNKNOWN );

	/* Determine the size of the AlgorithmIdentifier record and the
	   BITSTRING-encapsulated public-key data (the +1 is for the bitstring) */
	totalSize = sizeofAlgoIDex( cryptAlgo, CRYPT_ALGO_NONE, parameterSize ) +
				( int ) sizeofObject( componentSize + 1 );

	/* Write the SubjectPublicKeyInfo header field */
	writeSequence( &stream, totalSize );
	writeAlgoIDex( &stream, cryptAlgo, CRYPT_ALGO_NONE, parameterSize );

	/* Write the parameter data if necessary */
	if( cryptAlgo == CRYPT_ALGO_DSA )
		{
		writeSequence( &stream, comp1Size + comp2Size + comp3Size );
		writeInteger( &stream, component1, component1Length, DEFAULT_TAG );
		writeInteger( &stream, component2, component2Length, DEFAULT_TAG );
		writeInteger( &stream, component3, component3Length, DEFAULT_TAG );
		}
	if( cryptAlgo == CRYPT_ALGO_KEA )
		{
		BYTE domainParameters[ 10 ];
		const int domainParameterLength = \
					generateDomainParameters( domainParameters,
											  component1, component1Length,
											  component2, component2Length,
											  component3, component3Length );

		writeOctetString( &stream, domainParameters, domainParameterLength,
						  DEFAULT_TAG );
		}

	/* Write the BITSTRING wrapper and the PKC information */
	writeTag( &stream, BER_BITSTRING );
	writeLength( &stream, componentSize + 1 );	/* +1 for bitstring */
	sputc( &stream, 0 );
	if( cryptAlgo == CRYPT_ALGO_RSA )
		{
		writeSequence( &stream, comp1Size + comp2Size );
		writeInteger( &stream, component1, component1Length, DEFAULT_TAG );
		writeInteger( &stream, component2, component2Length, DEFAULT_TAG );
		}
	else
		if( cryptAlgo == CRYPT_ALGO_DSA )
			writeInteger( &stream, component4, component4Length, DEFAULT_TAG );
		else
			swrite( &stream, component4, component4Length );

	/* Clean up */
	status = sGetStatus( &stream );
	sMemDisconnect( &stream );
	return( status );
	}

/****************************************************************************
*																			*
*							Read/Write DL Value Record						*
*																			*
****************************************************************************/

/* Prototypes for functions in pgp_misc.c */

int pgpReadMPI( STREAM *stream, BYTE *data );
int pgpWriteMPI( STREAM *stream, const BYTE *data, const int length );

/* Unlike the simpler RSA PKC, DL-based PKC's produce a pair of values which
   need to be encoded as ASN.1 records.  The following two functions perform
   this en/decoding */

int encodeDLValues( BYTE *buffer, const int bufSize, BIGNUM *value1,
					BIGNUM *value2, const CRYPT_FORMAT_TYPE formatType )
	{
	STREAM stream;
	BYTE dataBuffer[ CRYPT_MAX_PKCSIZE ];
	int length, status;

	sMemOpen( &stream, buffer, bufSize );

	/* Write the DL components to the buffer */
	if( formatType == CRYPT_FORMAT_CRYPTLIB )
		{
		writeTag( &stream, BER_SEQUENCE );
		writeLength( &stream, sizeofEncodedBignum( value1 ) +
							  sizeofEncodedBignum( value2 ) );
		length = BN_bn2bin( value1, dataBuffer );
		writeInteger( &stream, dataBuffer, length, DEFAULT_TAG );
		length = BN_bn2bin( value2, dataBuffer );
		writeInteger( &stream, dataBuffer, length, DEFAULT_TAG );
		}
	else
		{
		assert( formatType == CRYPT_FORMAT_PGP );

		length = BN_bn2bin( value1, dataBuffer );
		pgpWriteMPI( &stream, dataBuffer, length );
		length = BN_bn2bin( value2, dataBuffer );
		pgpWriteMPI( &stream, dataBuffer, length );
		}

	/* Clean up */
	status = ( int ) stell( &stream );
	sMemDisconnect( &stream );
	zeroise( dataBuffer, CRYPT_MAX_PKCSIZE );
	return( status );
	}

int decodeDLValues( const BYTE *buffer, const int bufSize, BIGNUM **value1,
					BIGNUM **value2, const CRYPT_FORMAT_TYPE formatType )
	{
	STREAM stream;
	BYTE dataBuffer[ CRYPT_MAX_PKCSIZE ];
	int length, status;

	sMemConnect( &stream, buffer, bufSize );

	/* Read the DL components from the buffer */
	if( formatType == CRYPT_FORMAT_CRYPTLIB )
		{
		readSequence( &stream, NULL );
		status = readInteger( &stream, dataBuffer, &length, 
							  CRYPT_MAX_PKCSIZE );
		if( cryptStatusError( status ) )
			return( status );
		*value1 = BN_new();
		BN_bin2bn( dataBuffer, length, *value1 );
		status = readInteger( &stream, dataBuffer, &length, 
							  CRYPT_MAX_PKCSIZE );
		if( cryptStatusError( status ) )
			{
			BN_clear_free( *value1 );
			return( CRYPT_ERROR_BADDATA );
			}
		*value2 = BN_new();
		BN_bin2bn( dataBuffer, length, *value2 );
		}
	else
		{
		assert( formatType == CRYPT_FORMAT_PGP );

		status = length = pgpReadMPI( &stream, dataBuffer );
		if( cryptStatusError( status ) )
			return( status );
		*value1 = BN_new();
		BN_bin2bn( dataBuffer, bitsToBytes( length ), *value1 );
		status = length = pgpReadMPI( &stream, dataBuffer );
		if( cryptStatusError( status ) )
			{
			BN_clear_free( *value1 );
			return( CRYPT_ERROR_BADDATA );
			}
		*value2 = BN_new();
		BN_bin2bn( dataBuffer, bitsToBytes( length ), *value2 );
		}

	/* Clean up */
	sMemDisconnect( &stream );
	zeroise( dataBuffer, CRYPT_MAX_PKCSIZE );
	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*						Read/Write Ad Hoc-format Key Records				*
*																			*
****************************************************************************/

/* Read/write an SSHv1 public key */

static int readSsh1Bignum( STREAM *stream, BIGNUM *value,
						  const int minBits, const int maxBits )
	{
	int length;

	/* Read the length and make sure it's within acceptable limits */
	length = ( sgetc( stream ) << 8 ) | sgetc( stream );
	if( length < minBits || length > maxBits )
		return( CRYPT_ERROR_BADDATA );

	/* Read the bignum */
	length = bitsToBytes( length );
	BN_bin2bn( sMemBufPtr( stream ), length, value );
	return( sSkip( stream, length ) );
	}

static int writeSsh1Bignum( STREAM *stream, BIGNUM *bignum )
	{
	BYTE buffer[ CRYPT_MAX_PKCSIZE ];
	int bnLength;

	bnLength = BN_num_bits( bignum );
	sputc( stream, bnLength >> 8 );
	sputc( stream, bnLength & 0xFF );
	bnLength = BN_bn2bin( bignum, buffer );
	return( swrite( stream, buffer, bnLength ) );
	}

int readSsh1PublicKey( STREAM *stream, CRYPT_INFO *cryptInfoPtr )
	{
	PKC_INFO *rsaKey = &cryptInfoPtr->ctxPKC;
	PKCINFO_LOADINTERNAL dummy;
	RESOURCE_DATA msgData;
	int status;

	assert( cryptInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );

	/* Read the SSH public key information */
	rsaKey->isPublicKey = TRUE;
	status = readSsh1Bignum( stream, rsaKey->rsaParam_e, 2, 256 );
	if( cryptStatusOK( status ) )
		status = readSsh1Bignum( stream, rsaKey->rsaParam_n,
								 504, bytesToBits( CRYPT_MAX_PKCSIZE ) );
	if( cryptStatusError( status ) )
		return( status );

	/* If everything went OK, perform an internal load which uses the values
	   already present in the context */
	setResourceData( &msgData, &dummy, sizeof( PKCINFO_LOADINTERNAL ) );
	status = krnlSendMessage( cryptInfoPtr->objectHandle,
							  RESOURCE_IMESSAGE_SETATTRIBUTE_S,
							  &msgData, CRYPT_CTXINFO_KEY_COMPONENTS );
	return( cryptArgError( status ) ? CRYPT_ERROR_BADDATA : status );
	}

int writeSsh1PublicKey( STREAM *stream, const CRYPT_INFO *cryptInfoPtr )
	{
	const PKC_INFO *rsaKey = &cryptInfoPtr->ctxPKC;
	long length;

	assert( cryptInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );

	/* Write the nominal keysize, which is the length of the modulus in
	   bits */
	length = BN_num_bits( rsaKey->rsaParam_n );
	sputc( stream, 0 );
	sputc( stream, 0 );
	sputc( stream, length >> 8 );
	sputc( stream, length & 0xFF );

	/* Write the exponent and modulus */
	writeSsh1Bignum( stream, rsaKey->rsaParam_e );
	return( writeSsh1Bignum( stream, rsaKey->rsaParam_n ) );
	}

/* Read/write an SSHv2 public key */

static int readSsh2Bignum( STREAM *stream, BIGNUM *value,
						   const int minBytes, const int maxBytes )
	{
	int length;

	/* Read the length and make sure it's within acceptable limits */
	if( sgetc( stream ) || sgetc( stream ) )
		return( CRYPT_ERROR_BADDATA );
	length = ( sgetc( stream ) << 8 ) | sgetc( stream );
	if( length < minBytes || length > maxBytes )
		return( CRYPT_ERROR_BADDATA );

	/* Read the bignum */
	BN_bin2bn( sMemBufPtr( stream ), length, value );
	return( sSkip( stream, length ) );
	}

static int writeSsh2Bignum( STREAM *stream, BIGNUM *bignum )
	{
	BYTE buffer[ CRYPT_MAX_PKCSIZE ];
	int bnLength;

	bnLength = BN_num_bytes( bignum );
	sputc( stream, 0 );
	sputc( stream, 0 );
	sputc( stream, bnLength >> 8 );
	sputc( stream, bnLength & 0xFF );
	bnLength = BN_bn2bin( bignum, buffer );
	return( swrite( stream, buffer, bnLength ) );
	}

int readSsh2PublicKey( STREAM *stream, CRYPT_INFO *cryptInfoPtr )
	{
	PKCINFO_LOADINTERNAL dummy;
	RESOURCE_DATA msgData;
	int status;

	assert( cryptInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA || \
			cryptInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA );

	/* Read the SSH public key information */
	if( cryptInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA )
		{
		PKC_INFO *rsaKey = &cryptInfoPtr->ctxPKC;

		rsaKey->isPublicKey = TRUE;
		status = readSsh2Bignum( stream, rsaKey->rsaParam_e, 1, 16 );
		if( cryptStatusOK( status ) )
			status = readSsh2Bignum( stream, rsaKey->rsaParam_n,
									 bitsToBytes( 504 ), CRYPT_MAX_PKCSIZE );
		}
	else
		{
		PKC_INFO *dsaKey = &cryptInfoPtr->ctxPKC;

		dsaKey->isPublicKey = TRUE;
		status = readSsh2Bignum( stream, dsaKey->dlpParam_p,
								 bitsToBytes( 504 ), CRYPT_MAX_PKCSIZE );
		if( cryptStatusOK( status ) )
			status = readSsh2Bignum( stream, dsaKey->dlpParam_q,
									 bitsToBytes( 128 ), CRYPT_MAX_PKCSIZE );
		if( cryptStatusOK( status ) )
			status = readSsh2Bignum( stream, dsaKey->dlpParam_g,
									 bitsToBytes( 504 ), CRYPT_MAX_PKCSIZE );
		if( cryptStatusOK( status ) )
			status = readSsh2Bignum( stream, dsaKey->dlpParam_y,
									 bitsToBytes( 128 ), CRYPT_MAX_PKCSIZE );
		}
	if( cryptStatusError( status ) )
		return( status );

	/* If everything went OK, perform an internal load which uses the values
	   already present in the context */
	setResourceData( &msgData, &dummy, sizeof( PKCINFO_LOADINTERNAL ) );
	status = krnlSendMessage( cryptInfoPtr->objectHandle,
							  RESOURCE_IMESSAGE_SETATTRIBUTE_S,
							  &msgData, CRYPT_CTXINFO_KEY_COMPONENTS );
	return( cryptArgError( status ) ? CRYPT_ERROR_BADDATA : status );
	}

int writeSsh2PublicKey( STREAM *stream, const CRYPT_INFO *cryptInfoPtr )
	{
	/* Write the SSH public key information */
	if( cryptInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA )
		{
		const PKC_INFO *rsaKey = &cryptInfoPtr->ctxPKC;

		writeSsh2Bignum( stream, rsaKey->rsaParam_e );
		return( writeSsh2Bignum( stream, rsaKey->rsaParam_n ) );
		}
	else
		{
		const PKC_INFO *dsaKey = &cryptInfoPtr->ctxPKC;

		writeSsh2Bignum( stream, dsaKey->dlpParam_p );
		writeSsh2Bignum( stream, dsaKey->dlpParam_q );
		writeSsh2Bignum( stream, dsaKey->dlpParam_g );
		return( writeSsh2Bignum( stream, dsaKey->dlpParam_y ) );
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -