📄 key_wr.c
字号:
assert( isReadPtr( g, gLength ) );
REQUIRES( pLength >= MIN_PKCSIZE && pLength <= CRYPT_MAX_PKCSIZE );
REQUIRES( qLength >= MIN_PKCSIZE && qLength <= CRYPT_MAX_PKCSIZE );
REQUIRES( gLength >= MIN_PKCSIZE && gLength <= CRYPT_MAX_PKCSIZE );
/* Write the parameters to a stream. The stream length is in case
KEA is at some point extended up to the max.allowed PKC size */
sMemOpen( &stream, dataBuffer, 16 + ( CRYPT_MAX_PKCSIZE * 3 ) );
writeSequence( &stream, pSize + qSize + gSize );
writeInteger( &stream, p, pLength, DEFAULT_TAG );
writeInteger( &stream, q, qLength, DEFAULT_TAG );
status = writeInteger( &stream, g, gLength, DEFAULT_TAG );
assert( cryptStatusOK( status ) );
dataSize = stell( &stream );
sMemDisconnect( &stream );
/* Hash the DSA/KEA parameters and reduce them down to get the domain
identifier */
getHashParameters( CRYPT_ALGO_SHA, &hashFunction, &hashSize );
hashFunction( NULL, hash, hashSize, dataBuffer, dataSize, HASH_ALL );
zeroise( dataBuffer, CRYPT_MAX_PKCSIZE * 3 );
hashSize /= 2; /* Output = hash result folded in half */
for( i = 0; i < hashSize; i++ )
domainParameters[ i ] = hash[ i ] ^ hash[ hashSize + i ];
return( hashSize );
}
#endif /* USE_KEA */
/* If the keys are stored in a crypto device rather than being held in the
context all that we'll have available are the public components in flat
format. The following code writes flat-format public components in the
X.509 SubjectPublicKeyInfo format. The parameters are:
Algo Comp1 Comp2 Comp3 Comp4
---- ----- ----- ----- -----
RSA n e - -
DLP p q g y */
CHECK_RETVAL STDC_NONNULL_ARG( ( 3, 5, 7 ) ) \
int writeFlatPublicKey( OUT_BUFFER_OPT( bufMaxSize, *bufSize ) void *buffer,
IN_LENGTH_SHORT_Z const int bufMaxSize,
OUT_LENGTH_SHORT_Z int *bufSize,
IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo,
IN_BUFFER( component1Length ) const void *component1,
IN_LENGTH_PKC const int component1Length,
IN_BUFFER( component2Length ) const void *component2,
IN_LENGTH_PKC const int component2Length,
IN_BUFFER_OPT( component3Length ) const void *component3,
IN_LENGTH_PKC_Z const int component3Length,
IN_BUFFER_OPT( component4Length ) const void *component4,
IN_LENGTH_PKC_Z 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 );
int parameterSize, componentSize, totalSize, status;
assert( ( buffer == NULL && bufMaxSize == 0 ) || \
isWritePtr( buffer, bufMaxSize ) );
assert( isWritePtr( bufSize, sizeof( int ) ) );
assert( isReadPtr( component1, component1Length ) );
assert( isReadPtr( component2, component2Length ) );
assert( component3 == NULL || \
isReadPtr( component3, component3Length ) );
assert( component4 == NULL || \
isReadPtr( component4, component4Length ) );
REQUIRES( ( buffer == NULL && bufMaxSize == 0 ) || \
( buffer != NULL && \
bufMaxSize > 64 && bufMaxSize < MAX_INTLENGTH_SHORT ) );
REQUIRES( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && \
cryptAlgo <= CRYPT_ALGO_LAST_PKC && !isEccAlgo( cryptAlgo ) );
REQUIRES( component1Length > 0 && component1Length <= CRYPT_MAX_PKCSIZE );
REQUIRES( component2Length > 0 && component2Length <= CRYPT_MAX_PKCSIZE );
REQUIRES( ( component3 == NULL && component3Length == 0 ) || \
( component3 != NULL && \
component3Length > 0 && component3Length <= CRYPT_MAX_PKCSIZE ) );
REQUIRES( ( component4 == NULL && component4Length == 0 ) || \
( component4 != NULL && \
component4Length > 0 && component4Length <= CRYPT_MAX_PKCSIZE ) );
/* Clear return values */
if( buffer != NULL )
memset( buffer, 0, min( 16, bufMaxSize ) );
*bufSize = 0;
/* Calculate the size of the algorithm parameters and the public key
components */
switch( cryptAlgo )
{
case CRYPT_ALGO_DH:
case CRYPT_ALGO_DSA:
case CRYPT_ALGO_ELGAMAL:
parameterSize = ( int ) sizeofObject( comp1Size + comp2Size + \
comp3Size );
componentSize = 0;
break;
#ifdef USE_KEA
case CRYPT_ALGO_KEA:
parameterSize = ( int) sizeofObject( 10 );
componentSize = component4Length;
break;
#endif /* USE_KEA */
case CRYPT_ALGO_RSA:
parameterSize = 0;
componentSize = ( int ) sizeofObject( comp1Size + comp2Size );
break;
default:
retIntError();
}
/* Determine the size of the AlgorithmIdentifier and the BITSTRING-
encapsulated public-key data (the +1 is for the bitstring) */
status = totalSize = sizeofAlgoIDex( cryptAlgo, CRYPT_ALGO_NONE, \
parameterSize );
if( cryptStatusError( status ) )
return( status );
totalSize += ( int ) sizeofObject( componentSize + 1 );
if( buffer == NULL )
{
/* It's a size-check call, return the overall size */
*bufSize = ( int ) sizeofObject( totalSize );
return( CRYPT_OK );
}
sMemOpen( &stream, buffer, bufMaxSize );
/* Write the SubjectPublicKeyInfo header field */
writeSequence( &stream, totalSize );
writeAlgoIDex( &stream, cryptAlgo, CRYPT_ALGO_NONE, parameterSize );
/* Write the parameter data if necessary */
if( isDlpAlgo( cryptAlgo ) && cryptAlgo != CRYPT_ALGO_KEA )
{
writeSequence( &stream, comp1Size + comp2Size + comp3Size );
writeInteger( &stream, component1, component1Length, DEFAULT_TAG );
if( hasReversedParams( cryptAlgo ) )
{
writeInteger( &stream, component3, component3Length, DEFAULT_TAG );
writeInteger( &stream, component2, component2Length, DEFAULT_TAG );
}
else
{
writeInteger( &stream, component2, component2Length, DEFAULT_TAG );
writeInteger( &stream, component3, component3Length, DEFAULT_TAG );
}
}
#ifdef USE_KEA
if( cryptAlgo == CRYPT_ALGO_KEA )
{
BYTE domainParameters[ 10 + 8 ];
const int domainParameterLength = \
generateDomainParameters( domainParameters,
component1, component1Length,
component2, component2Length,
component3, component3Length );
writeOctetString( &stream, domainParameters, domainParameterLength,
DEFAULT_TAG );
}
#endif /* USE_KEA */
/* Write the BITSTRING wrapper and the PKC information */
writeBitStringHole( &stream, componentSize, DEFAULT_TAG );
if( cryptAlgo == CRYPT_ALGO_RSA )
{
writeSequence( &stream, comp1Size + comp2Size );
writeInteger( &stream, component1, component1Length, DEFAULT_TAG );
status = writeInteger( &stream, component2, component2Length,
DEFAULT_TAG );
}
else
{
#ifdef USE_KEA
if( cryptAlgo == CRYPT_ALGO_KEA )
status = swrite( &stream, component4, component4Length );
else
#endif /* USE_KEA */
status = writeInteger( &stream, component4, component4Length,
DEFAULT_TAG );
}
if( cryptStatusOK( status ) )
*bufSize = stell( &stream );
/* Clean up */
sMemDisconnect( &stream );
return( status );
}
/****************************************************************************
* *
* Write DL Values *
* *
****************************************************************************/
/* Unlike the simpler RSA PKC, DL-based PKCs produce a pair of values that
need to be encoded as structured data. The following two functions
perform this en/decoding. SSH assumes that DLP values are two fixed-size
blocks of 20 bytes so we can't use the normal read/write routines to
handle these values */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4, 5 ) ) \
static int encodeDLValuesFunction( OUT_BUFFER( bufMaxSize, \
*bufSize ) BYTE *buffer,
IN_LENGTH_SHORT_MIN( 20 + 20 ) \
const int bufMaxSize,
OUT_LENGTH_SHORT_Z int *bufSize,
const BIGNUM *value1,
const BIGNUM *value2,
IN_ENUM( CRYPT_FORMAT ) \
const CRYPT_FORMAT_TYPE formatType )
{
STREAM stream;
int length = DUMMY_INIT, status;
assert( isWritePtr( buffer, bufMaxSize ) );
assert( isWritePtr( bufSize, sizeof( int ) ) );
assert( isReadPtr( value1, sizeof( BIGNUM ) ) );
assert( isReadPtr( value2, sizeof( BIGNUM ) ) );
REQUIRES( bufMaxSize >= 40 && bufMaxSize < MAX_INTLENGTH_SHORT );
REQUIRES( formatType > CRYPT_FORMAT_NONE && \
formatType < CRYPT_FORMAT_LAST );
/* Clear return values */
memset( buffer, 0, min( 16, bufMaxSize ) );
*bufSize = 0;
sMemOpen( &stream, buffer, bufMaxSize );
/* Write the DL components to the buffer */
switch( formatType )
{
case CRYPT_FORMAT_CRYPTLIB:
writeSequence( &stream, sizeofBignum( value1 ) + \
sizeofBignum( value2 ) );
writeBignum( &stream, value1 );
status = writeBignum( &stream, value2 );
break;
#ifdef USE_PGP
case CRYPT_FORMAT_PGP:
writeBignumInteger16Ubits( &stream, value1 );
status = writeBignumInteger16Ubits( &stream, value2 );
break;
#endif /* USE_PGP */
#ifdef USE_SSH
case CRYPT_IFORMAT_SSH:
{
int i;
/* SSH uses an awkward (and horribly inflexible) fixed format
with each of the nominally 160-bit DLP values at fixed
positions in a 2 x 20-byte buffer */
length = BN_num_bytes( value1 );
ENSURES( length > 15 && length <= 20 );
for( i = 0; i < 20 - length; i++ )
{
status = sputc( &stream, 0 );
ENSURES( !cryptStatusError( status ) );
}
status = writeBignum( &stream, value1 );
if( cryptStatusError( status ) )
break;
length = BN_num_bytes( value2 );
ENSURES( length > 15 && length <= 20 );
for( i = 0; i < 20 - length; i++ )
{
status = sputc( &stream, 0 );
ENSURES( !cryptStatusError( status ) );
}
status = writeBignum( &stream, value2 );
ENSURES( cryptStatusError( status ) || stell( &stream ) == 40 );
break;
}
#endif /* USE_SSH */
default:
retIntError();
}
if( cryptStatusOK( status ) )
length = stell( &stream );
sMemDisconnect( &stream );
if( cryptStatusError( status ) )
return( status );
*bufSize = length;
return( CRYPT_OK );
}
/****************************************************************************
* *
* Context Access Routines *
* *
****************************************************************************/
STDC_NONNULL_ARG( ( 1 ) ) \
void initKeyWrite( INOUT CONTEXT_INFO *contextInfoPtr )
{
const CRYPT_ALGO_TYPE cryptAlgo = contextInfoPtr->capabilityInfo->cryptAlgo;
PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;
assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) && \
contextInfoPtr->type == CONTEXT_PKC );
/* Set the access method pointers */
if( isDlpAlgo( cryptAlgo ) )
{
pkcInfo->writePublicKeyFunction = writePublicKeyDlpFunction;
pkcInfo->writePrivateKeyFunction = writePrivateKeyDlpFunction;
pkcInfo->encodeDLValuesFunction = encodeDLValuesFunction;
return;
}
#ifdef USE_ECC
if( isEccAlgo( cryptAlgo ) )
{
pkcInfo->writePublicKeyFunction = writePublicKeyEccFunction;
pkcInfo->writePrivateKeyFunction = writePrivateKeyEccFunction;
return;
}
#endif /* USE_ECC */
pkcInfo->writePublicKeyFunction = writePublicKeyRsaFunction;
pkcInfo->writePrivateKeyFunction = writePrivateKeyRsaFunction;
}
#else
STDC_NONNULL_ARG( ( 1 ) ) \
void initKeyWrite( INOUT CONTEXT_INFO *contextInfoPtr )
{
}
#endif /* USE_PKC */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -