📄 sign_rw.c
字号:
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( queryInfo, sizeof( QUERY_INFO ) ) );
/* Make sure that the packet header is in order and check the packet
version. For this packet type a version number of 3 denotes PGP 2.x
whereas for key transport it denotes OpenPGP */
status = getPgpPacketInfo( stream, queryInfo );
if( cryptStatusError( status ) )
return( status );
value = sgetc( stream );
if( value != PGP_VERSION_2 && value != PGP_VERSION_3 && \
value != PGP_VERSION_OPENPGP )
return( CRYPT_ERROR_BADDATA );
queryInfo->type = CRYPT_OBJECT_SIGNATURE;
queryInfo->version = ( value == PGP_VERSION_OPENPGP ) ? \
PGP_VERSION_OPENPGP : PGP_VERSION_2;
/* Read the signing attributes and skip the hash check */
if( value != PGP_VERSION_OPENPGP )
status = readPgp2SigInfo( stream, queryInfo, startPos );
else
status = readOpenPgpSigInfo( stream, queryInfo, startPos );
if( cryptStatusOK( status ) )
status = sSkip( stream, 2 );
if( cryptStatusError( status ) )
return( status );
/* Read the signature, recording the position and length of the raw RSA
signature data. We have to be careful how we handle this because
readInteger16Ubits() returns the canonicalised form of the values
(with leading zeroes truncated) so an stell() before the read doesn't
necessarily represent the start of the payload:
startPos dataStart stell()
| | |
v v <-- length -->v
+---+-----------+---------------+
| | |///////////////| Stream
+---+-----------+---------------+ */
if( queryInfo->cryptAlgo == CRYPT_ALGO_RSA )
{
status = readInteger16Ubits( stream, NULL, &queryInfo->dataLength,
MIN_PKCSIZE, CRYPT_MAX_PKCSIZE );
if( cryptStatusError( status ) )
return( status );
queryInfo->dataStart = stell( stream ) - queryInfo->dataLength;
}
else
{
const int dataStartPos = stell( stream );
int dummy;
REQUIRES( queryInfo->cryptAlgo == CRYPT_ALGO_DSA );
/* Read the DSA signature, recording the position and combined
lengths of the MPI pair. Again, we can't use the length returned
by readInteger16Ubits() to determine the overall size but have to
calculate it from the position in the stream */
status = readInteger16Ubits( stream, NULL, &dummy, 16, 20 );
if( cryptStatusOK( status ) )
status = readInteger16Ubits( stream, NULL, &dummy, 16, 20 );
if( cryptStatusError( status ) )
return( status );
queryInfo->dataStart = dataStartPos - startPos;
queryInfo->dataLength = stell( stream ) - dataStartPos;
}
return( CRYPT_OK );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int writePgpSignature( INOUT STREAM *stream,
STDC_UNUSED const CRYPT_CONTEXT iSignContext,
STDC_UNUSED const CRYPT_ALGO_TYPE hashAlgo,
IN_ALGO const CRYPT_ALGO_TYPE signAlgo,
IN_BUFFER( signatureLength ) const BYTE *signature,
IN_LENGTH_SHORT_MIN( 18 + 18 + 1 ) \
const int signatureLength )
{
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isReadPtr( signature, signatureLength ) );
/* Other parameters aren't used for this format */
REQUIRES( signAlgo >= CRYPT_ALGO_FIRST_PKC && \
signAlgo <= CRYPT_ALGO_LAST_PKC );
REQUIRES( signatureLength > ( 18 + 18 ) && \
signatureLength < MAX_INTLENGTH_SHORT );
/* If it's a DLP algorithm we've already specified the DLP output format
as PGP so there's no need for further processing. The handling of
PGP signatures is non-orthogonal to readPgpSignature() because
creating a PGP signature involves adding assorted additional data
like key IDs and authenticated attributes, which present too much
information to pass into a basic writeSignature() call */
if( isDlpAlgo( signAlgo ) || isEccAlgo( signAlgo ) )
return( swrite( stream, signature, signatureLength ) );
/* Write the signature as a PGP MPI */
return( writeInteger16Ubits( stream, signature, signatureLength ) );
}
#endif /* USE_PGP */
/****************************************************************************
* *
* Miscellaneous Signature Routines *
* *
****************************************************************************/
#ifdef USE_SSH
/* Read/write SSH signatures. SSH signature data is treated as a blob
encoded as an SSH string rather than properly-formatted data so we don't
encode/decode it as SSH MPIs */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readSshSignature( INOUT STREAM *stream,
INOUT QUERY_INFO *queryInfo )
{
const int startPos = stell( stream );
BYTE buffer[ CRYPT_MAX_TEXTSIZE + 8 ];
int length, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( queryInfo, sizeof( QUERY_INFO ) ) );
/* Read the signature record size and algorithm information */
readUint32( stream );
status = readString32( stream, buffer, CRYPT_MAX_TEXTSIZE, &length );
if( cryptStatusError( status ) )
return( status );
if( length != 7 )
return( CRYPT_ERROR_BADDATA );
if( !memcmp( buffer, "ssh-rsa", 7 ) )
queryInfo->cryptAlgo = CRYPT_ALGO_RSA;
else
{
if( !memcmp( buffer, "ssh-dss", 7 ) )
queryInfo->cryptAlgo = CRYPT_ALGO_DSA;
else
return( CRYPT_ERROR_BADDATA );
}
/* Read the start of the signature */
length = readUint32( stream );
if( cryptStatusError( length ) )
return( length );
if( queryInfo->cryptAlgo == CRYPT_ALGO_DSA )
{
if( length != ( 20 + 20 ) )
return( CRYPT_ERROR_BADDATA );
}
else
{
if( length < MIN_PKCSIZE || length > CRYPT_MAX_PKCSIZE )
return( CRYPT_ERROR_BADDATA );
}
queryInfo->dataStart = stell( stream ) - startPos;
queryInfo->dataLength = length;
/* Make sure that the remaining signature data is present */
return( sSkip( stream, length ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int writeSshSignature( INOUT STREAM *stream,
STDC_UNUSED const CRYPT_CONTEXT iSignContext,
STDC_UNUSED const CRYPT_ALGO_TYPE hashAlgo,
IN_ALGO const CRYPT_ALGO_TYPE signAlgo,
IN_BUFFER( signatureLength ) const BYTE *signature,
IN_LENGTH_SHORT_MIN( 40 ) const int signatureLength )
{
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isReadPtr( signature, signatureLength ) );
/* Other parameters aren't used for this format */
REQUIRES( signAlgo == CRYPT_ALGO_RSA || signAlgo == CRYPT_ALGO_DSA );
REQUIRES( signatureLength >= ( 20 + 20 ) && \
signatureLength < MAX_INTLENGTH_SHORT );
writeUint32( stream, sizeofString32( "ssh-Xsa", 7 ) + \
sizeofString32( "", signatureLength ) );
writeString32( stream, ( signAlgo == CRYPT_ALGO_RSA ) ? \
"ssh-rsa" : "ssh-dss", 7 );
return( writeString32( stream, signature, signatureLength ) );
}
#endif /* USE_SSH */
#ifdef USE_SSL
/* Read/write SSL signatures. This is just a raw signature without any
encapsulation */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readSslSignature( INOUT STREAM *stream,
INOUT QUERY_INFO *queryInfo )
{
const int startPos = stell( stream );
int length;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( queryInfo, sizeof( QUERY_INFO ) ) );
/* Read the start of the signature */
length = readUint16( stream );
if( length < MIN_PKCSIZE || length > CRYPT_MAX_PKCSIZE )
return( CRYPT_ERROR_BADDATA );
queryInfo->dataStart = stell( stream ) - startPos;
queryInfo->dataLength = length;
/* Make sure that the remaining signature data is present */
return( sSkip( stream, length ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int writeSslSignature( INOUT STREAM *stream,
STDC_UNUSED const CRYPT_CONTEXT iSignContext,
STDC_UNUSED const CRYPT_ALGO_TYPE hashAlgo,
STDC_UNUSED const CRYPT_ALGO_TYPE signAlgo,
IN_BUFFER( signatureLength ) const BYTE *signature,
IN_LENGTH_SHORT_MIN( 18 + 18 + 1 ) \
const int signatureLength )
{
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isReadPtr( signature, signatureLength ) );
/* Other parameters aren't used for this format */
REQUIRES( signatureLength > ( 18 + 18 ) && \
signatureLength < MAX_INTLENGTH_SHORT );
writeUint16( stream, signatureLength );
return( swrite( stream, signature, signatureLength ) );
}
#endif /* USE_SSL */
/****************************************************************************
* *
* Signature Read/Write Access Functions *
* *
****************************************************************************/
typedef struct {
const SIGNATURE_TYPE type;
const READSIG_FUNCTION function;
} SIG_READ_INFO;
static const SIG_READ_INFO sigReadTable[] = {
{ SIGNATURE_RAW, readRawSignature },
{ SIGNATURE_X509, readX509Signature },
{ SIGNATURE_CMS, readCmsSignature },
{ SIGNATURE_CRYPTLIB, readCryptlibSignature },
#ifdef USE_PGP
{ SIGNATURE_PGP, readPgpSignature },
#endif /* USE_PGP */
#ifdef USE_SSH
{ SIGNATURE_SSH, readSshSignature },
#endif /* USE_SSH */
#ifdef USE_SSL
{ SIGNATURE_SSL, readSslSignature },
#endif /* USE_SSL */
{ SIGNATURE_NONE, NULL }, { SIGNATURE_NONE, NULL }
};
typedef struct {
const SIGNATURE_TYPE type;
const WRITESIG_FUNCTION function;
} SIG_WRITE_INFO;
static const SIG_WRITE_INFO sigWriteTable[] = {
{ SIGNATURE_RAW, writeRawSignature },
{ SIGNATURE_X509, writeX509Signature },
{ SIGNATURE_CMS, writeCmsSignature },
{ SIGNATURE_CRYPTLIB, writeCryptlibSignature },
#ifdef USE_PGP
{ SIGNATURE_PGP, writePgpSignature },
#endif /* USE_PGP */
#ifdef USE_SSH
{ SIGNATURE_SSH, writeSshSignature },
#endif /* USE_SSH */
#ifdef USE_SSL
{ SIGNATURE_SSL, writeSslSignature },
#endif /* USE_SSH */
{ SIGNATURE_NONE, NULL }, { SIGNATURE_NONE, NULL }
};
CHECK_RETVAL_PTR \
READSIG_FUNCTION getReadSigFunction( IN_ENUM( SIGNATURE ) \
const SIGNATURE_TYPE sigType )
{
int i;
REQUIRES_N( sigType > SIGNATURE_NONE && sigType < SIGNATURE_LAST );
for( i = 0;
sigReadTable[ i ].type != SIGNATURE_NONE && \
i < FAILSAFE_ARRAYSIZE( sigReadTable, SIG_READ_INFO );
i++ )
{
if( sigReadTable[ i ].type == sigType )
return( sigReadTable[ i ].function );
}
ENSURES_N( i < FAILSAFE_ARRAYSIZE( sigReadTable, SIG_READ_INFO ) );
return( NULL );
}
CHECK_RETVAL_PTR \
WRITESIG_FUNCTION getWriteSigFunction( IN_ENUM( SIGNATURE ) \
const SIGNATURE_TYPE sigType )
{
int i;
REQUIRES_N( sigType > SIGNATURE_NONE && sigType < SIGNATURE_LAST );
for( i = 0;
sigWriteTable[ i ].type != SIGNATURE_NONE && \
i < FAILSAFE_ARRAYSIZE( sigWriteTable, SIG_WRITE_INFO );
i++ )
{
if( sigWriteTable[ i ].type == sigType )
return( sigWriteTable[ i ].function );
}
ENSURES_N( i < FAILSAFE_ARRAYSIZE( sigWriteTable, SIG_WRITE_INFO ) );
return( NULL );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -