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

📄 key_rd.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:

	uint32		keysize_bits
	mpint		exponent
	mpint		modulus */

int readSsh1RsaPublicKey( STREAM *stream, CONTEXT_INFO *contextInfoPtr,
						  int *actionFlags )
	{
	PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
	const int length = readUint32( stream );
	int status;

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

	/* Make sure that the nominal keysize value is valid */
	if( length < MIN_PKCSIZE_BITS || \
		length > bytesToBits( CRYPT_MAX_PKCSIZE ) )
		return( CRYPT_ERROR_BADDATA );

	/* Set the maximum permitted actions.  SSH keys are only used internally,
	   so we restrict the usage to internal-only */
	*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
								   ACTION_PERM_NONE_EXTERNAL );

	/* Read the SSH public key information */
	status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_e, 2, 256 );
	if( cryptStatusOK( status ) )
		status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_n,
										   MIN_PKCSIZE_BITS, 
										   bytesToBits( CRYPT_MAX_PKCSIZE ) );
	return( status );
	}
#endif /* USE_SSH1 */

/* Read SSHv2 public keys:

	string	certificate
		string	"ssh-rsa"	"ssh-dss"
		mpint	e			p
		mpint	n			q
		mpint				g
		mpint				y */

int readSsh2RsaPublicKey( STREAM *stream, CONTEXT_INFO *contextInfoPtr,
						  int *actionFlags )
	{
	PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
	char buffer[ 16 ];
	int length, status;

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

	/* Read the wrapper and make sure that it's OK */
	readUint32( stream );
	status = readString32( stream, buffer, &length, 7 );
	if( cryptStatusError( status ) )
		return( status );
	if( length != 7 || memcmp( buffer, "ssh-rsa", 7 ) )
		return( CRYPT_ERROR_BADDATA );

	/* Set the maximum permitted actions.  SSH keys are only used internally,
	   so we restrict the usage to internal-only */
	*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
								   ACTION_PERM_NONE_EXTERNAL );

	/* Read the SSH public key information */
	status = readBignumInteger32( stream, &rsaKey->rsaParam_e, 1, 16 );
	if( cryptStatusOK( status ) )
		status = readBignumInteger32( stream, &rsaKey->rsaParam_n,
									  bitsToBytes( MIN_PKCSIZE_BITS ), 
									  CRYPT_MAX_PKCSIZE );
	return( status );
	}

int readSsh2DlpPublicKey( STREAM *stream, CONTEXT_INFO *contextInfoPtr,
						  int *actionFlags )
	{
	PKC_INFO *dsaKey = contextInfoPtr->ctxPKC;
	const BOOLEAN isDH = \
			( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH );
	char buffer[ 16 ];
	int length, status;

	assert( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
			contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH );

	/* Read the wrapper and make sure that it's OK.  SSHv2 uses PKCS #3 
	   rather than X9.42-style DH keys, so we have to treat this algorithm 
	   type specially */
	readUint32( stream );
	if( isDH )
		{
		status = readString32( stream, buffer, &length, 6 );
		if( cryptStatusError( status ) )
			return( status );
		if( length != 6 || memcmp( buffer, "ssh-dh", 6 ) )
			return( CRYPT_ERROR_BADDATA );

		/* Set the maximum permitted actions.  SSH keys are only used 
		   internally, so we restrict the usage to internal-only.  Since DH 
		   keys can be both public and private keys, we allow both usage 
		   types even though technically it's a public key */
		*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
									   ACTION_PERM_NONE_EXTERNAL ) | \
					   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
									   ACTION_PERM_NONE_EXTERNAL );

		/* Read the SSH public key information.  Since SSH uses PKCS #3 DH 
		   values we can end up with very small values for g, so we have to
		   handle this specially */
		status = readBignumInteger32( stream, &dsaKey->dlpParam_p,
									  bitsToBytes( MIN_PKCSIZE_BITS ), 
									  CRYPT_MAX_PKCSIZE );
		if( cryptStatusOK( status ) )
			status = readBignumInteger32( stream, &dsaKey->dlpParam_g,
										  1, CRYPT_MAX_PKCSIZE );
		return( status );
		}

	/* It's a standard DLP key, read the wrapper and make sure that it's 
	   OK */
	status = readString32( stream, buffer, &length, 7 );
	if( cryptStatusError( status ) )
		return( status );
	if( length != 7 || memcmp( buffer, "ssh-dss", 7 ) )
		return( CRYPT_ERROR_BADDATA );

	/* Set the maximum permitted actions.  SSH keys are only used internally,
	   so we restrict the usage to internal-only */
	*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
								   ACTION_PERM_NONE_EXTERNAL );

	/* Read the SSH public key information */
	status = readBignumInteger32( stream, &dsaKey->dlpParam_p,
								  bitsToBytes( MIN_PKCSIZE_BITS ), 
								  CRYPT_MAX_PKCSIZE );
	if( cryptStatusOK( status ) )
		status = readBignumInteger32( stream, &dsaKey->dlpParam_q,
									  bitsToBytes( 128 ), 
									  CRYPT_MAX_PKCSIZE );
	if( cryptStatusOK( status ) )
		status = readBignumInteger32( stream, &dsaKey->dlpParam_g,
									  bitsToBytes( MIN_PKCSIZE_BITS ), 
									  CRYPT_MAX_PKCSIZE );
	if( cryptStatusOK( status ) && !isDH )
		status = readBignumInteger32( stream, &dsaKey->dlpParam_y,
									  bitsToBytes( 128 ), 
									  CRYPT_MAX_PKCSIZE );
	return( status );
	}

/* Read SSL public keys:

	uint16		dh_pLen
	byte[]		dh_p
	uint16		dh_gLen
	byte[]		dh_g
  [	uint16		dh_YsLen ]
  [	byte[]		dh_Ys	 ]

   The DH y value is nominally attached to the DH p and g values, but 
   isn't processed at this level since this is a pure PKCS #3 DH key
   and not a generic DLP key */

int readSslDlpPublicKey( STREAM *stream, CONTEXT_INFO *contextInfoPtr,
						 int *actionFlags )
	{
	PKC_INFO *dhKey = contextInfoPtr->ctxPKC;
	int status;

	assert( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH );

	/* Set the maximum permitted actions.  SSL keys are only used 
	   internally, so we restrict the usage to internal-only.  Since DH 
	   keys can be both public and private keys, we allow both usage 
	   types even though technically it's a public key */
	*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
								   ACTION_PERM_NONE_EXTERNAL ) | \
				   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
								   ACTION_PERM_NONE_EXTERNAL );

	/* Read the SSL public key information.  Since SSL uses PKCS #3 DH 
	   values we can end up with very small values for g, so we have to
	   handle this specially */
	status = readBignumInteger16U( stream, &dhKey->dlpParam_p,
								   bitsToBytes( MIN_PKCSIZE_BITS ), 
								   CRYPT_MAX_PKCSIZE );
	if( cryptStatusOK( status ) )
		status = readBignumInteger16U( stream, &dhKey->dlpParam_g, 1, 
									   CRYPT_MAX_PKCSIZE );
	return( status );
	}

/* Read PGP public keys:

	byte		version
	uint32		creationTime
	[ uint16	validity - version 3 only ]
	byte		RSA		DSA		Elgamal
	mpi			n		p		p
	mpi			e		q		g
	mpi					g		y
	mpi					y */

int readPgpRsaPublicKey( STREAM *stream, CONTEXT_INFO *contextInfoPtr,
						 int *actionFlags )
	{
	PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
	time_t creationTime;
	int value, status;

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

	/* Read the header info */
	value = sgetc( stream );
	if( value != PGP_VERSION_2 && value != PGP_VERSION_3 && \
		value != PGP_VERSION_OPENPGP )
		return( CRYPT_ERROR_BADDATA );
	status = readUint32Time( stream, &creationTime );
	if( cryptStatusError( status ) )
		return( status );
	rsaKey->pgpCreationTime = creationTime;
	if( value == PGP_VERSION_2 || value == PGP_VERSION_3 )
		/* Skip validity period */
		sSkip( stream, 2 );

	/* Set the maximum permitted actions.  If there are no restrictions we
	   allow external usage, if the keys are encryption-only or sig-only we
	   make the usage internal-only because of RSA's signature/encryption
	   duality.  If the key is a pure public key (rather than merely the 
	   public portions of a  private key), the actions will be restricted by 
	   higher-level code to sig-check only  */
	value = sgetc( stream );
	if( value != PGP_ALGO_RSA && value != PGP_ALGO_RSA_ENCRYPT && \
		value != PGP_ALGO_RSA_SIGN )
		return( CRYPT_ERROR_BADDATA );
	*actionFlags = 0;
	if( value != PGP_ALGO_RSA_SIGN )
		*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, ACTION_PERM_ALL ) | \
					   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, ACTION_PERM_ALL );
	if( value != PGP_ALGO_RSA_ENCRYPT )
		*actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, ACTION_PERM_ALL ) | \
						MK_ACTION_PERM( MESSAGE_CTX_SIGN, ACTION_PERM_ALL );
	if( value != PGP_ALGO_RSA )
		*actionFlags = MK_ACTION_PERM_NONE_EXTERNAL( *actionFlags );

	/* Read the PGP public key information */
	status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_n, 
									   MIN_PKCSIZE_BITS, 
									   bytesToBits( PGP_MAX_MPISIZE ) );
	if( cryptStatusOK( status ) )
		status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_e, 2, 
										   bytesToBits( PGP_MAX_MPISIZE ) );
	return( status );
	}

int readPgpDlpPublicKey( STREAM *stream, CONTEXT_INFO *contextInfoPtr,
						 int *actionFlags )
	{
	PKC_INFO *dlpKey = contextInfoPtr->ctxPKC;
	time_t creationTime;
	int value, status;

	assert( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
			contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL );

	/* Read the header info */
	value = sgetc( stream );
	if( value != PGP_VERSION_OPENPGP )
		return( CRYPT_ERROR_BADDATA );
	status = readUint32Time( stream, &creationTime );
	if( cryptStatusError( status ) )
		return( status );
	dlpKey->pgpCreationTime = creationTime;

	/* Set the maximum permitted actions.  Because of the special-case data 
	   formatting requirements for DLP algorithms, we make the usage 
	   internal-only.  If the key is a pure public key (rather than merely 
	   the public portions of a  private key), the actions will be 
	   restricted by higher-level code to sig-check only  */
	value = sgetc( stream );
	if( value != PGP_ALGO_DSA && value != PGP_ALGO_ELGAMAL )
		return( CRYPT_ERROR_BADDATA );
	if( value == PGP_ALGO_DSA )
		*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
									   ACTION_PERM_NONE_EXTERNAL ) | \
					   MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
									   ACTION_PERM_NONE_EXTERNAL );
	else
		*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
									   ACTION_PERM_NONE_EXTERNAL ) | \
					   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
									   ACTION_PERM_NONE_EXTERNAL );

	/* Read the PGP public key information */
	status = readBignumInteger16Ubits( stream, &dlpKey->dlpParam_p, 
									   MIN_PKCSIZE_BITS, 
									   bytesToBits( PGP_MAX_MPISIZE ) );
	if( cryptStatusOK( status ) && value == PGP_ALGO_DSA )
		status = readBignumInteger16Ubits( stream, &dlpKey->dlpParam_q, 155, 
										   bytesToBits( PGP_MAX_MPISIZE ) );
	if( cryptStatusOK( status ) )
		status = readBignumInteger16Ubits( stream, &dlpKey->dlpParam_g, 2, 
										   bytesToBits( PGP_MAX_MPISIZE ) );
	if( cryptStatusOK( status ) )
		status = readBignumInteger16Ubits( stream, &dlpKey->dlpParam_y, 
										   MIN_PKCSIZE_BITS, 
										   bytesToBits( PGP_MAX_MPISIZE ) );
	return( status );
	}

/* Umbrella public-key read functions */

static int readPublicKeyRsaFunction( STREAM *stream, CONTEXT_INFO *contextInfoPtr,
									 const KEYFORMAT_TYPE formatType )
	{
	int actionFlags, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );

⌨️ 快捷键说明

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