📄 keyex_rw.c
字号:
mpi(s) encrypted session key */
static int readPgpKeytrans( STREAM *stream, QUERY_INFO *queryInfo )
{
int value, status;
/* Make sure that the packet header is in order and check the packet
version. For this packet type, a version number of 3 denotes OpenPGP,
whereas for signatures it denotes PGP 2.x, so we translate the value
that we return to the caller */
status = getPacketInfo( stream, queryInfo );
if( cryptStatusError( status ) )
return( status );
value = sgetc( stream );
if( value != PGP_VERSION_2 && value != PGP_VERSION_3 )
return( CRYPT_ERROR_BADDATA );
queryInfo->version = ( value == PGP_VERSION_2 ) ? \
PGP_VERSION_2 : PGP_VERSION_OPENPGP;
/* Get the PGP key ID and algorithm */
status = sread( stream, queryInfo->keyID, PGP_KEYID_SIZE );
if( cryptStatusError( status ) )
return( status );
queryInfo->keyIDlength = PGP_KEYID_SIZE;
if( ( queryInfo->cryptAlgo = \
pgpToCryptlibAlgo( sgetc( stream ),
PGP_ALGOCLASS_PKCCRYPT ) ) == CRYPT_ALGO_NONE )
return( CRYPT_ERROR_NOTAVAIL );
/* Read the encrypted key */
if( queryInfo->cryptAlgo == CRYPT_ALGO_RSA )
{
queryInfo->dataStart = sMemBufPtr( stream ) + 2;
status = pgpReadMPI( stream, NULL );
if( cryptStatusError( status ) )
return( status );
queryInfo->dataLength = bitsToBytes( status );
return( CRYPT_OK );
}
queryInfo->dataStart = sMemBufPtr( stream );
status = pgpReadMPI( stream, NULL );
if( cryptStatusError( status ) )
return( status );
queryInfo->dataLength = bitsToBytes( status ) + 2;
if( queryInfo->dataLength < 56 || \
queryInfo->dataLength > CRYPT_MAX_PKCSIZE + 2 )
return( CRYPT_ERROR_BADDATA );
status = pgpReadMPI( stream, NULL );
if( cryptStatusError( status ) )
return( status );
queryInfo->dataLength += bitsToBytes( status ) + 2;
if( queryInfo->dataLength < ( 56 * 2 ) || \
queryInfo->dataLength > ( ( CRYPT_MAX_PKCSIZE + 2 ) * 2 ) )
return( CRYPT_ERROR_BADDATA );
return( CRYPT_OK );
}
static int writePgpKeytrans( STREAM *stream,
const CRYPT_CONTEXT iCryptContext,
const BYTE *buffer, const int length,
const void *auxInfo, const int auxInfoLength )
{
CRYPT_ALGO_TYPE cryptAlgo;
BYTE keyID[ PGP_KEYID_SIZE ];
int status;
/* Get the key information */
status = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE,
&cryptAlgo, CRYPT_CTXINFO_ALGO );
if( cryptStatusOK( status ) )
{
RESOURCE_DATA msgData;
setMessageData( &msgData, keyID, PGP_KEYID_SIZE );
status = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_IATTRIBUTE_KEYID_OPENPGP );
}
if( cryptStatusError( status ) )
return( status );
/* Write the PKE packet */
pgpWritePacketHeader( stream, PGP_PACKET_PKE,
1 + PGP_KEYID_SIZE + 1 + \
( ( cryptAlgo == CRYPT_ALGO_RSA ) ? \
sizeofMPI( length ) : length ) );
sputc( stream, 3 ); /* Version = 3 (OpenPGP) */
swrite( stream, keyID, PGP_KEYID_SIZE );
sputc( stream, cryptlibToPgpAlgo( cryptAlgo ) );
return( ( cryptAlgo == CRYPT_ALGO_RSA ) ? \
pgpWriteMPI( stream, buffer, length ) :
swrite( stream, buffer, length ) );
}
#endif /* USE_PGP */
/****************************************************************************
* *
* Key Agreement Routines *
* *
****************************************************************************/
#if 0 /* 24/11/02 Removed since Fortezza is effectively dead */
/* Read/write a KeyAgreeRecipientInfo (= FortezzaRecipientInfo) record */
int readKeyAgreeInfo( STREAM *stream, QUERY_INFO *queryInfo,
CRYPT_CONTEXT *iKeyAgreeContext )
{
CRYPT_CONTEXT iLocalKeyAgreeContext;
long value;
int status;
/* Clear return value */
if( iKeyAgreeContext != NULL )
*iKeyAgreeContext = CRYPT_ERROR;
/* Read the header and version number */
readConstructed( stream, NULL, CTAG_RI_KEYAGREE );
status = readShortInteger( stream, &value );
if( cryptStatusError( status ) )
return( status );
if( value != 3 )
return( CRYPT_ERROR_BADDATA );
/* Read the public key information and encryption algorithm information */
status = iCryptReadSubjectPublicKey( stream, &iLocalKeyAgreeContext,
FALSE );
if( cryptStatusError( status ) )
return( status );
/* If we're doing a query we're not interested in the key agreement
context so we just copy out the information we need and destroy it */
if( iKeyAgreeContext == NULL )
{
RESOURCE_DATA msgData;
setMessageData( &msgData, queryInfo->keyID,
queryInfo->keyIDlength );
status = krnlSendMessage( iLocalKeyAgreeContext,
IMESSAGE_GETATTRIBUTE_S, &msgData,
CRYPT_IATTRIBUTE_KEYID );
if( cryptStatusOK( status ) )
status = krnlSendMessage( iLocalKeyAgreeContext,
IMESSAGE_GETATTRIBUTE,
&queryInfo->cryptAlgo,
CRYPT_CTXINFO_ALGO );
krnlSendNotifier( iLocalKeyAgreeContext, IMESSAGE_DECREFCOUNT );
return( status );
}
/* Make the key agreement context externally visible */
*iKeyAgreeContext = iLocalKeyAgreeContext;
return( CRYPT_OK );
}
int writeKeyAgreeInfo( STREAM *stream, const CRYPT_CONTEXT iCryptContext,
const void *wrappedKey, const int wrappedKeyLength,
const void *ukm, const int ukmLength,
const void *auxInfo, const int auxInfoLength )
{
RESOURCE_DATA msgData;
BYTE rKeyID[ 1024 ];
int rKeyIDlength, recipientKeyInfoSize, status;
/* Get the recipients key ID and determine how large the recipient key
info will be */
setMessageData( &msgData, rKeyID, 1024 );
status = krnlSendMessage( iCryptContext, MESSAGE_GETATTRIBUTE_S, &msgData,
CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER );
if( cryptStatusError( status ) )
return( status );
rKeyIDlength = msgData.length;
recipientKeyInfoSize = ( int ) ( \
sizeofObject( sizeofObject( rKeyIDlength ) ) + \
sizeofObject( wrappedKeyLength ) );
/* Write the FortezzaRecipientInfo header and version number */
writeConstructed( stream, ( int ) sizeofShortInteger( 3 ) + \
sizeofObject( sizeofObject( auxInfoLength ) ) + \
sizeofObject( sizeofObject( ukmLength ) ) + \
sizeofOID( ALGOID_FORTEZZA_KEYWRAP ) + \
sizeofObject( sizeofObject( recipientKeyInfoSize ) ),
CTAG_RI_KEYAGREE );
writeShortInteger( stream, 3, DEFAULT_TAG );
/* Write the originator's keyIdentifier, UKM, and Fortezza key wrap OID */
writeConstructed( stream, ( int ) sizeofObject( auxInfoLength ),
CTAG_KA_ORIG );
writeOctetString( stream, auxInfo, auxInfoLength, 0 );
writeConstructed( stream, ( int ) sizeofObject( ukmLength ),
CTAG_KA_UKM );
writeOctetString( stream, ukm, ukmLength, DEFAULT_TAG );
swrite( stream, ALGOID_FORTEZZA_KEYWRAP,
sizeofOID( ALGOID_FORTEZZA_KEYWRAP ) );
/* Write the recipient keying info */
writeSequence( stream, ( int ) sizeofObject( recipientKeyInfoSize ) );
writeSequence( stream, recipientKeyInfoSize );
writeConstructed( stream, ( int ) sizeofObject( rKeyIDlength ), 0 );
writeOctetString( stream, rKeyID, rKeyIDlength, DEFAULT_TAG );
return( writeOctetString( stream, wrappedKey, wrappedKeyLength,
DEFAULT_TAG ) );
}
#endif /* 0 */
/****************************************************************************
* *
* Key Exchange Read/Write Function Access Information *
* *
****************************************************************************/
const READKEYTRANS_FUNCTION keytransReadTable[] = {
NULL, /* KEYEX_NONE */
readCmsKeytrans, /* KEYEX_CMS */
readCryptlibKeytrans, /* KEYEX_CRYPTLIB */
#ifdef USE_PGP
readPgpKeytrans, /* KEYEX_PGP */
#else
NULL, /* KEYEX_PGP */
#endif /* USE_PGP */
NULL, NULL, NULL
};
const WRITEKEYTRANS_FUNCTION keytransWriteTable[] = {
NULL, /* KEYEX_NONE */
writeCmsKeytrans, /* KEYEX_CMS */
writeCryptlibKeytrans, /* KEYEX_CRYPTLIB */
#ifdef USE_PGP
writePgpKeytrans, /* KEYEX_PGP */
#else
NULL, /* KEYEX_PGP */
#endif /* USE_PGP */
NULL, NULL, NULL
};
const READKEK_FUNCTION kekReadTable[] = {
NULL, /* KEYEX_NONE */
readCryptlibKek, /* KEYEX_CMS */
readCryptlibKek, /* KEYEX_CRYPTLIB */
#ifdef USE_PGP
readPgpKek, /* KEYEX_PGP */
#else
NULL, /* KEYEX_PGP */
#endif /* USE_PGP */
NULL, NULL, NULL
};
const WRITEKEK_FUNCTION kekWriteTable[] = {
NULL, /* KEYEX_NONE */
writeCryptlibKek, /* KEYEX_CMS */
writeCryptlibKek, /* KEYEX_CRYPTLIB */
#ifdef USE_PGP
writePgpKek, /* KEYEX_PGP */
#else
NULL, /* KEYEX_PGP */
#endif /* USE_PGP */
NULL, NULL, NULL
};
/****************************************************************************
* *
* Object Query Routines *
* *
****************************************************************************/
/* Low-level object query functions */
int queryAsn1Object( STREAM *stream, QUERY_INFO *queryInfo )
{
const long startPos = stell( stream );
int status;
/* Clear the return value and determine basic object information */
memset( queryInfo, 0, sizeof( QUERY_INFO ) );
status = getObjectInfo( stream, queryInfo );
if( cryptStatusError( status ) )
return( status );
/* Call the appropriate routine to find out more about the object */
switch( queryInfo->type )
{
case CRYPT_OBJECT_ENCRYPTED_KEY:
status = kekReadTable[ KEYEX_CMS ]( stream, queryInfo );
break;
case CRYPT_OBJECT_PKCENCRYPTED_KEY:
if( queryInfo->formatType == CRYPT_FORMAT_CMS )
status = keytransReadTable[ KEYEX_CMS ]( stream, queryInfo );
else
status = keytransReadTable[ KEYEX_CRYPTLIB ]( stream, queryInfo );
break;
#if 0 /* 24/11/02 Removed since it was only used for Fortezza */
case CRYPT_OBJECT_KEYAGREEMENT:
status = readKeyAgreeInfo( stream, queryInfo, NULL );
break;
#endif /* 0 */
case CRYPT_OBJECT_SIGNATURE:
if( queryInfo->formatType == CRYPT_FORMAT_CMS )
status = sigReadTable[ SIGNATURE_CMS ]( stream, queryInfo );
else
status = sigReadTable[ SIGNATURE_CRYPTLIB ]( stream,
queryInfo );
break;
case CRYPT_OBJECT_NONE:
/* New, unrecognised RecipientInfo type */
status = readUniversal( stream );
break;
default:
assert( NOTREACHED );
status = CRYPT_ERROR_BADDATA;
}
sseek( stream, startPos );
if( cryptStatusError( status ) )
zeroise( queryInfo, sizeof( QUERY_INFO ) );
return( status );
}
#ifdef USE_PGP
int queryPgpObject( STREAM *stream, QUERY_INFO *queryInfo )
{
const long startPos = stell( stream );
int status;
/* Clear the return value and determine basic object information */
memset( queryInfo, 0, sizeof( QUERY_INFO ) );
status = getPacketInfo( stream, queryInfo );
sseek( stream, startPos );
if( cryptStatusError( status ) )
return( status );
/* Call the appropriate routine to find out more about the object */
switch( queryInfo->type )
{
case CRYPT_OBJECT_ENCRYPTED_KEY:
status = kekReadTable[ KEYEX_PGP ]( stream, queryInfo );
break;
case CRYPT_OBJECT_PKCENCRYPTED_KEY:
status = keytransReadTable[ KEYEX_PGP ]( stream, queryInfo );
break;
case CRYPT_OBJECT_SIGNATURE:
status = sigReadTable[ SIGNATURE_PGP ]( stream, queryInfo );
break;
case CRYPT_OBJECT_NONE:
/* First half of a one-pass signature */
status = readOnepassSigPacket( stream, queryInfo );
break;
default:
assert( NOTREACHED );
status = CRYPT_ERROR_BADDATA;
}
sseek( stream, startPos );
if( cryptStatusError( status ) )
zeroise( queryInfo, sizeof( QUERY_INFO ) );
return( status );
}
#endif /* USE_PGP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -