📄 key_rd.c
字号:
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 + -