static int writeRequestBody( INOUT STREAM *stream, const SESSION_INFO *sessionInfoPtr, const CMP_PROTOCOL_INFO *protocolInfo ) { const CRYPT_CERTFORMAT_TYPE certType = \ ( protocolInfo->operation == CTAG_PB_RR ) ? \ CRYPT_ICERTFORMAT_DATA : CRYPT_CERTFORMAT_CERTIFICATE; MESSAGE_DATA msgData; int status; assert( isWritePtr( stream, sizeof( STREAM ) ) ); assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) ); assert( isReadPtr( protocolInfo, sizeof( CMP_PROTOCOL_INFO ) ) ); /* Find out how big the payload will be. Since revocation requests are unsigned entities we have to vary the attribute type that we're reading (via the certType specifier) based on whether we're submitting a signed or unsigned object in the request */ setMessageData( &msgData, NULL, 0 ); status = krnlSendMessage( sessionInfoPtr->iCertRequest, IMESSAGE_CRT_EXPORT, &msgData, certType ); if( cryptStatusError( status ) ) return( status ); /* Write the request body */ writeConstructed( stream, objSize( msgData.length ), protocolInfo->operation ); writeSequence( stream, msgData.length ); return( exportCertToStream( stream, sessionInfoPtr->iCertRequest, certType ) ); }
static int checkMemoryStreamParams( INOUT STREAM *stream, IN const void *buffer, /* May be unintialised for sMemOpen() so we can't use IN_BUFFER */ IN_LENGTH_Z const int length ) { /* We don't use a REQUIRES() predicate here for the reasons given in the comments above */ assert( isWritePtr( stream, sizeof( STREAM ) ) ); assert( length > 0 && length < MAX_BUFFER_SIZE ); assert( isReadPtr( buffer, length ) ); /* If there's a problem with the parameters, return an error code but also make it a (non-readable, non-writeable) null stream with the error state set via retIntError_Stream() so that it can be safely used */ if( length < 1 || length >= MAX_BUFFER_SIZE || \ !isReadPtr( buffer, length ) ) { stream->type = STREAM_TYPE_NULL; stream->flags = STREAM_FLAG_READONLY; retIntError_Stream( stream ); } return( CRYPT_OK ); }
static int generateKeyComponents( CONTEXT_INFO *staticContextInfo, PKC_INFO *contextData, const CAPABILITY_INFO *capabilityInfoPtr, const int keySizeBits ) { int status; assert( isWritePtr( staticContextInfo, sizeof( CONTEXT_INFO ) ) ); assert( isWritePtr( contextData, sizeof( PKC_INFO ) ) ); assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) ); REQUIRES( keySizeBits >= bytesToBits( MIN_PKCSIZE ) && \ keySizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) ); /* Initialise a static context to generate the key into */ status = staticInitContext( staticContextInfo, CONTEXT_PKC, capabilityInfoPtr, contextData, sizeof( PKC_INFO ), NULL ); if( cryptStatusError( status ) ) return( status ); /* Generate a key into the static context */ status = capabilityInfoPtr->generateKeyFunction( staticContextInfo, keySizeBits ); if( cryptStatusError( status ) ) { staticDestroyContext( staticContextInfo ); return( status ); } return( CRYPT_OK ); }
static int getFirstItemFunction( DEVICE_INFO *deviceInfo, CRYPT_CERTIFICATE *iCertificate, int *stateInfo, const CRYPT_KEYID_TYPE keyIDtype, const void *keyID, const int keyIDlength, const KEYMGMT_ITEM_TYPE itemType, const int options ) { HARDWARE_INFO *hardwareInfo = deviceInfo->deviceHardware; MESSAGE_KEYMGMT_INFO getnextcertInfo; assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) ); assert( isWritePtr( iCertificate, sizeof( CRYPT_CERTIFICATE ) ) ); assert( isReadPtr( keyID, keyIDlength ) ); assert( isWritePtr( stateInfo, sizeof( int ) ) ); REQUIRES( keyIDtype == CRYPT_IKEYID_KEYID ); REQUIRES( keyIDlength > 4 && keyIDlength < MAX_INTLENGTH_SHORT ); REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY ); /* Clear return values */ *iCertificate = CRYPT_ERROR; *stateInfo = CRYPT_ERROR; /* Get the first certificate */ setMessageKeymgmtInfo( &getnextcertInfo, keyIDtype, keyID, keyIDlength, stateInfo, sizeof( int ), options ); return( krnlSendMessage( hardwareInfo->iCryptKeyset, IMESSAGE_KEY_GETFIRSTCERT, &getnextcertInfo, KEYMGMT_ITEM_PUBLICKEY ) ); }
static BOOLEAN sanityCheckWrite( const SESSION_INFO *sessionInfoPtr ) { assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) ); /* Make sure that the general state is in order */ if( sessionInfoPtr->sendBufSize < MIN_BUFFER_SIZE || \ sessionInfoPtr->sendBufSize >= MAX_BUFFER_SIZE ) return( FALSE ); if( sessionInfoPtr->sendBufStartOfs < 0 || \ sessionInfoPtr->sendBufStartOfs > FIXED_HEADER_MAX ) return( FALSE ); /* Make sure that the buffer position values are within bounds */ if( sessionInfoPtr->sendBufPos < sessionInfoPtr->sendBufStartOfs || \ sessionInfoPtr->sendBufPos >= sessionInfoPtr->sendBufSize ) return( FALSE ); if( sessionInfoPtr->sendBufPartialBufPos < 0 || \ sessionInfoPtr->sendBufPartialBufPos >= sessionInfoPtr->sendBufPos ) return( FALSE ); if( !sessionInfoPtr->partialWrite ) { if( sessionInfoPtr->sendBufPos > sessionInfoPtr->sendBufStartOfs + \ sessionInfoPtr->maxPacketSize ) return( FALSE ); } else { if( sessionInfoPtr->sendBufPartialBufPos >= sessionInfoPtr->sendBufPos ) return( FALSE ); } return( TRUE ); }
static int rsaInitKey( CONTEXT_INFO *contextInfoPtr, const void *key, const int keyLength ) { PERSONALITY_INFO *personalityInfoPtr; int keyHandle, status; assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) ); assert( isReadPtr( key, keyLength ) ); REQUIRES( keyLength == sizeof( CRYPT_PKCINFO_RSA ) ); /* Find a free personality slot to store the key */ status = findFreePersonality( &keyHandle ); if( cryptStatusError( status ) ) return( status ); personalityInfoPtr = &personalityInfo[ keyHandle ]; /* Load the key into the personality and copy the public-key portions (needed for certificates and the like) to the context using the helper function in hardware.c */ rsaKeyToInternal( personalityInfoPtr->keyInfo.pkcKeyInfo, key ); status = setPKCinfo( contextInfoPtr, contextInfoPtr->capabilityInfo->cryptAlgo, key ); if( cryptStatusError( status ) ) { deletePersonality( keyHandle ); return( status ); } return( completeInitKeyRSA( contextInfoPtr, personalityInfoPtr, keyHandle ) ); }
static int lookupPersonality( const void *keyID, const int keyIDlength, int *keyHandle ) { const int storageIDlength = min( keyIDlength, STORAGEID_SIZE ); int i; assert( isReadPtr( keyID, keyIDlength ) ); assert( isWritePtr( keyHandle, sizeof( int ) ) ); REQUIRES( keyIDlength >= 4 && keyIDlength <= KEYID_SIZE ); /* Clear return value */ *keyHandle = CRYPT_ERROR; /* Scan the personality table looking for one matching the given storageID */ for( i = 0; i < NO_PERSONALITIES; i++ ) { PERSONALITY_INFO *personalityInfoPtr = &personalityInfo[ i ]; if( !personalityInfoPtr->inUse ) continue; if( !memcmp( personalityInfoPtr->storageID, keyID, storageIDlength ) ) { *keyHandle = i; return( CRYPT_OK ); } } return( CRYPT_ERROR_NOTFOUND ); }
static void copyObjectInfo( INOUT PKCS12_INFO *destPkcs12Info, const PKCS12_INFO *srcPkcs12Info, const BOOLEAN isCertificate ) { assert( isWritePtr( destPkcs12Info, sizeof( PKCS12_INFO ) ) ); assert( isReadPtr( srcPkcs12Info, sizeof( PKCS12_INFO ) ) ); destPkcs12Info->flags |= srcPkcs12Info->flags; if( isCertificate ) { memcpy( &destPkcs12Info->certInfo, &srcPkcs12Info->certInfo, sizeof( PKCS12_OBJECT_INFO ) ); } else { memcpy( &destPkcs12Info->keyInfo, &srcPkcs12Info->keyInfo, sizeof( PKCS12_OBJECT_INFO ) ); } if( destPkcs12Info->labelLength <= 0 && \ srcPkcs12Info->labelLength > 0 ) { memcpy( destPkcs12Info->label, srcPkcs12Info->label, srcPkcs12Info->labelLength ); destPkcs12Info->labelLength = srcPkcs12Info->labelLength; } if( destPkcs12Info->idLength <= 0 && \ srcPkcs12Info->idLength > 0 ) { memcpy( destPkcs12Info->id, srcPkcs12Info->id, srcPkcs12Info->idLength ); destPkcs12Info->idLength = srcPkcs12Info->idLength; } }
static BOOLEAN sanityCheckURL( const URL_INFO *urlInfo ) { assert( isReadPtr( urlInfo, sizeof( URL_INFO ) ) ); /* Make sure that the URL type is valid. URL_TYPE_NONE is valid since it denotes an unrecognised URL type */ if( urlInfo->type < URL_TYPE_NONE || urlInfo->type >= URL_TYPE_LAST ) return( FALSE ); /* Make sure the schema, user info, and location are either absent or have valid values */ if( !checkUrlValue( urlInfo->schema, urlInfo->schemaLen, 2 + 3, 16 + 3 ) ) /* [...] + "://" */ return( FALSE ); if( !checkUrlValue( urlInfo->userInfo, urlInfo->userInfoLen, 1, CRYPT_MAX_TEXTSIZE ) ) return( FALSE ); if( !checkUrlValue( urlInfo->location, urlInfo->locationLen, 1, CRYPT_MAX_TEXTSIZE ) ) return( FALSE ); /* The host always has to be present */ if( urlInfo->host == NULL || \ urlInfo->hostLen < 1 || urlInfo->hostLen > MAX_URL_SIZE ) return( FALSE ); return( TRUE ); }
static BOOLEAN sanityCheck( const ENVELOPE_INFO *envelopeInfoPtr ) { assert( isReadPtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) ); /* Check the general envelope state */ if( !envelopeSanityCheck( envelopeInfoPtr ) ) return( FALSE ); /* Make sure that general envelope state is in order */ if( envelopeInfoPtr->type != CRYPT_FORMAT_PGP || \ ( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE ) ) return( FALSE ); /* Make sure that the buffer position is within bounds */ if( envelopeInfoPtr->buffer == NULL || \ envelopeInfoPtr->bufSize < MIN_BUFFER_SIZE || \ envelopeInfoPtr->bufSize >= MAX_BUFFER_SIZE ) return( FALSE ); /* If the auxBuffer isn't being used, make sure that all values related to it are clear */ if( envelopeInfoPtr->auxBuffer != NULL || \ envelopeInfoPtr->auxBufPos != 0 || envelopeInfoPtr->auxBufSize != 0 ) return( FALSE ); return( TRUE ); }
C_RET cryptQueryObject( C_IN void C_PTR objectData, C_IN int objectDataLength, C_OUT CRYPT_OBJECT_INFO C_PTR cryptObjectInfo ) { QUERY_INFO queryInfo = DUMMY_INIT_STRUCT; /* If USE_PGP undef'd */ STREAM stream; int value, length = objectDataLength, status; /* Perform basic error checking and clear the return value */ if( objectDataLength <= MIN_CRYPT_OBJECTSIZE || \ objectDataLength >= MAX_INTLENGTH ) return( CRYPT_ERROR_PARAM2 ); if( !isReadPtr( objectData, objectDataLength ) ) return( CRYPT_ERROR_PARAM1 ); if( !isWritePtrConst( cryptObjectInfo, sizeof( CRYPT_OBJECT_INFO ) ) ) return( CRYPT_ERROR_PARAM3 ); memset( cryptObjectInfo, 0, sizeof( CRYPT_OBJECT_INFO ) ); /* Query the object. This is just a wrapper for the lower-level object- query functions. Note that we use sPeek() rather than peekTag() because we want to continue processing (or at least checking for) PGP data if it's no ASN.1 */ sMemConnect( &stream, ( void * ) objectData, length ); status = value = sPeek( &stream ); if( cryptStatusError( status ) ) { sMemDisconnect( &stream ); return( status ); } if( value == BER_SEQUENCE || value == MAKE_CTAG( CTAG_RI_PWRI ) ) status = queryAsn1Object( &stream, &queryInfo ); else { #ifdef USE_PGP status = queryPgpObject( &stream, &queryInfo ); #else status = CRYPT_ERROR_BADDATA; #endif /* USE_PGP */ } sMemDisconnect( &stream ); if( cryptStatusError( status ) ) return( status ); /* Copy the externally-visible fields across */ cryptObjectInfo->objectType = queryInfo.type; cryptObjectInfo->cryptAlgo = queryInfo.cryptAlgo; cryptObjectInfo->cryptMode = queryInfo.cryptMode; if( queryInfo.type == CRYPT_OBJECT_SIGNATURE ) cryptObjectInfo->hashAlgo = queryInfo.hashAlgo; if( queryInfo.type == CRYPT_OBJECT_ENCRYPTED_KEY && \ queryInfo.saltLength > 0 ) { memcpy( cryptObjectInfo->salt, queryInfo.salt, queryInfo.saltLength ); cryptObjectInfo->saltSize = queryInfo.saltLength; if( queryInfo.keySetupAlgo != CRYPT_ALGO_NONE ) cryptObjectInfo->hashAlgo = queryInfo.keySetupAlgo; } return( CRYPT_OK ); }
int getWindowSize( const SESSION_INFO *sessionInfoPtr ) { assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) ); return( ( sessionInfoPtr->protocolFlags & SSH_PFLAG_WINDOWSIZE ) ? \ 0x1000000 : MAX_WINDOW_SIZE ); }
static BOOLEAN sanityCheck( const ENVELOPE_INFO *envelopeInfoPtr ) { assert( isReadPtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) ); /* Make sure that general envelope state is in order */ if( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE ) return( FALSE ); if( envelopeInfoPtr->envState < ENVSTATE_NONE || \ envelopeInfoPtr->envState >= ENVSTATE_LAST ) return( FALSE ); /* Make sure that the buffer position is within bounds */ if( envelopeInfoPtr->buffer == NULL || \ envelopeInfoPtr->bufPos < 0 || \ envelopeInfoPtr->bufPos > envelopeInfoPtr->bufSize || \ envelopeInfoPtr->bufSize < MIN_BUFFER_SIZE || \ envelopeInfoPtr->bufSize >= MAX_BUFFER_SIZE ) return( FALSE ); /* If the auxBuffer isn't being used, make sure that all values related to it are clear */ if( envelopeInfoPtr->auxBuffer != NULL || \ envelopeInfoPtr->auxBufPos != 0 || envelopeInfoPtr->auxBufSize != 0 ) return( FALSE ); return( TRUE ); }
int hwGetCapabilities( const CAPABILITY_INFO **capabilityInfo, int *noCapabilities ) { assert( isReadPtr( capabilityInfo, sizeof( CAPABILITY_INFO * ) ) ); assert( isWritePtr( noCapabilities, sizeof( int ) ) ); *capabilityInfo = capabilities; *noCapabilities = FAILSAFE_ARRAYSIZE( capabilities, CAPABILITY_INFO ); return( CRYPT_OK ); }
static int deleteItemFunction( DEVICE_INFO *deviceInfo, const KEYMGMT_ITEM_TYPE itemType, const CRYPT_KEYID_TYPE keyIDtype, const void *keyID, const int keyIDlength ) { HARDWARE_INFO *hardwareInfo = deviceInfo->deviceHardware; MESSAGE_KEYMGMT_INFO getkeyInfo, deletekeyInfo; int status; assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) ); assert( isReadPtr( keyID, keyIDlength ) ); REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY || \ itemType == KEYMGMT_ITEM_PRIVATEKEY ); REQUIRES( keyIDtype == CRYPT_KEYID_NAME ); REQUIRES( keyIDlength > 0 && keyIDlength <= CRYPT_MAX_TEXTSIZE ); /* Perform the delete both from the PKCS #15 storage object and the native storage. This gets a bit complicated because in order to find the hardware object we have to extract the storageID, and in order to get that we have to instantiate a dummy private-key object to contain it. In addition if the object that's stored isn't a private-key object then there's no associated cryptographic hardware object. To handle this we try and instantiate a dummy private-key object in order to get the storageID. If this succeeds, we locate the underlying hardware object and delete it. Finally, we delete the PKCS #15 object, either a pure public-key/certificate object or the private-key metadata for the cryptographic hardware object */ if( hardwareInfo->iCryptKeyset == CRYPT_ERROR ) return( CRYPT_ERROR_NOTINITED ); setMessageKeymgmtInfo( &getkeyInfo, keyIDtype, keyID, keyIDlength, NULL, 0, KEYMGMT_FLAG_NONE ); status = krnlSendMessage( hardwareInfo->iCryptKeyset, IMESSAGE_KEY_GETKEY, &getkeyInfo, KEYMGMT_ITEM_PRIVATEKEY ); if( cryptStatusOK( status ) ) { int keyHandle; /* It's a private-key object, get its hardware reference and delete it. If this fails we continue anyway because we know that there's also a PKCS #15 object to delete */ status = getHardwareReference( getkeyInfo.cryptHandle, &keyHandle ); if( cryptStatusOK( status ) ) ( void ) hwDeleteItem( keyHandle ); krnlSendNotifier( getkeyInfo.cryptHandle, IMESSAGE_DECREFCOUNT ); } setMessageKeymgmtInfo( &deletekeyInfo, keyIDtype, keyID, keyIDlength, NULL, 0, KEYMGMT_FLAG_NONE ); return( krnlSendMessage( hardwareInfo->iCryptKeyset, IMESSAGE_KEY_DELETEKEY, &deletekeyInfo, itemType ) ); }
int hwLookupItem( const void *keyID, const int keyIDlength, int *keyHandle ) { assert( isReadPtr( keyID, keyIDlength ) ); assert( isWritePtr( keyHandle, sizeof( int ) ) ); REQUIRES( keyIDlength >= 4 && keyIDlength <= KEYID_SIZE ); /* Clear return value */ *keyHandle = CRYPT_ERROR; return( lookupPersonality( keyID, keyIDlength, keyHandle ) ); }
static BOOLEAN sanityCheck( const RANDOM_INFO *randomInfo ) { assert( isReadPtr( randomInfo, sizeof( RANDOM_INFO ) ) ); /* Make sure that the X9.17 generator accounting information is within bounds. See the comment in generateX917() for the high-range check */ if( randomInfo->x917Count < 0 || \ randomInfo->x917Count > X917_MAX_CYCLES + \ ( MAX_RANDOM_BYTES / X917_POOLSIZE ) ) return( FALSE ); return( TRUE ); }
static void dummyEncrypt( const PERSONALITY_INFO *personalityInfoPtr, BYTE *data, const int length, const CRYPT_ALGO_TYPE cryptAlgo, const CRYPT_MODE_TYPE cryptMode ) { int i; assert( isReadPtr( personalityInfoPtr, sizeof( PERSONALITY_INFO ) ) ); assert( isWritePtr( data, length ) ); REQUIRES_V( cryptAlgo > CRYPT_ALGO_NONE && \ cryptAlgo < CRYPT_ALGO_LAST_EXTERNAL ); REQUIRES_V( cryptMode >= CRYPT_MODE_NONE && \ cryptMode < CRYPT_MODE_LAST ); if( isPkcAlgo( cryptAlgo ) ) { BYTE bignumData[ CRYPT_MAX_PKCSIZE + 8 ]; int bignumDataLength; bignumToExternal( bignumData, &bignumDataLength, personalityInfoPtr->keyInfo.pkcKeyInfo[ 0 ].data, personalityInfoPtr->keyInfo.pkcKeyInfo[ 0 ].dataSize ); for( i = 0; i < length; i++ ) data[ i ] ^= bignumData[ i ]; return; } /* We have to be a bit careful with the conventional encryption because the self-tests encrypt data in variable-length quantities to check for things like chaining problems, which means that for stream ciphers we really can't do anything more than repeatedly XOR with a fixed key byte */ if( cryptMode == CRYPT_MODE_CFB || cryptMode == CRYPT_MODE_OFB ) { const int keyDataOffset = CRYPT_MODE_CFB ? 0 : 1; for( i = 0; i < length; i++ ) data[ i ] ^= personalityInfoPtr->keyInfo.convKeyInfo[ keyDataOffset ]; } else { /* It's a block mode, we can at least use ECB, although we still can't chain because we don't know where we are in the data stream */ for( i = 0; i < length; i++ ) data[ i ] ^= personalityInfoPtr->keyInfo.convKeyInfo[ i % 16 ]; } }
void getCapabilityInfo( OUT CRYPT_QUERY_INFO *cryptQueryInfo, const CAPABILITY_INFO FAR_BSS *capabilityInfoPtr ) { assert( isWritePtr( cryptQueryInfo, sizeof( CRYPT_QUERY_INFO ) ) ); assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) ); memset( cryptQueryInfo, 0, sizeof( CRYPT_QUERY_INFO ) ); memcpy( cryptQueryInfo->algoName, capabilityInfoPtr->algoName, capabilityInfoPtr->algoNameLen ); cryptQueryInfo->algoName[ capabilityInfoPtr->algoNameLen ] = '\0'; cryptQueryInfo->blockSize = capabilityInfoPtr->blockSize; cryptQueryInfo->minKeySize = capabilityInfoPtr->minKeySize; cryptQueryInfo->keySize = capabilityInfoPtr->keySize; cryptQueryInfo->maxKeySize = capabilityInfoPtr->maxKeySize; }
static CRYPT_ATTRIBUTE_TYPE checkClientParameters( const SESSION_INFO *sessionInfoPtr ) { assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) ); /* Make sure that the network comms parameters are present */ if( sessionInfoPtr->transportSession == CRYPT_ERROR && \ sessionInfoPtr->networkSocket == CRYPT_ERROR && \ findSessionInfo( sessionInfoPtr->attributeList, CRYPT_SESSINFO_SERVER_NAME ) == NULL ) return( CRYPT_SESSINFO_SERVER_NAME ); /* Make sure that the username + password and/or user private key are present if required */ if( ( sessionInfoPtr->clientReqAttrFlags & SESSION_NEEDS_USERID ) && \ findSessionInfo( sessionInfoPtr->attributeList, CRYPT_SESSINFO_USERNAME ) == NULL ) return( CRYPT_SESSINFO_USERNAME ); if( ( sessionInfoPtr->clientReqAttrFlags & SESSION_NEEDS_PASSWORD ) && \ findSessionInfo( sessionInfoPtr->attributeList, CRYPT_SESSINFO_PASSWORD ) == NULL ) { /* There's no password present, see if we can use a private key as an alternative */ if( !( sessionInfoPtr->clientReqAttrFlags & \ SESSION_NEEDS_KEYORPASSWORD ) || \ sessionInfoPtr->privateKey == CRYPT_ERROR ) return( CRYPT_SESSINFO_PASSWORD ); } if( ( sessionInfoPtr->clientReqAttrFlags & SESSION_NEEDS_PRIVATEKEY ) && \ sessionInfoPtr->privateKey == CRYPT_ERROR ) { /* There's no private key present, see if we can use a password as an alternative */ if( !( sessionInfoPtr->clientReqAttrFlags & \ SESSION_NEEDS_KEYORPASSWORD ) || \ findSessionInfo( sessionInfoPtr->attributeList, CRYPT_SESSINFO_PASSWORD ) == NULL ) return( CRYPT_SESSINFO_PRIVATEKEY ); } /* Make sure that request/response protocol data is present if required */ if( ( sessionInfoPtr->clientReqAttrFlags & SESSION_NEEDS_REQUEST ) && \ sessionInfoPtr->iCertRequest == CRYPT_ERROR ) return( CRYPT_SESSINFO_REQUEST ); return( CRYPT_ATTRIBUTE_NONE ); }
static BOOLEAN isGeneralNameSelected( const CERT_INFO *certInfoPtr ) { CRYPT_ATTRIBUTE_TYPE fieldID; int status; assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) ); if( certInfoPtr->attributeCursor == NULL ) return( FALSE ); status = getAttributeIdInfo( certInfoPtr->attributeCursor, NULL, &fieldID, NULL ); if( cryptStatusError( status ) ) return( FALSE ); return( certInfoPtr->attributeCursor != NULL && \ isGeneralNameSelectionComponent( fieldID ) ? \ TRUE : FALSE ); }
static BOOLEAN sanityCheck( const PGP_INFO *pgpInfoPtr ) { assert( isReadPtr( pgpInfoPtr, sizeof( PGP_INFO ) ) ); /* Check that the basic fields are in order */ if( pgpInfoPtr->keyDataLen < 0 || \ pgpInfoPtr->keyDataLen >= MAX_INTLENGTH_SHORT || \ pgpInfoPtr->lastUserID < 0 || \ pgpInfoPtr->lastUserID > MAX_PGP_USERIDS || \ ( pgpInfoPtr->isOpenPGP != FALSE && \ pgpInfoPtr->isOpenPGP != TRUE ) || \ ( pgpInfoPtr->isComplete != FALSE && \ pgpInfoPtr->isComplete != TRUE ) ) return( FALSE ); return( TRUE ); }
static BOOLEAN sanityCheckRead( const SESSION_INFO *sessionInfoPtr ) { const int pendingPacketLength = sessionInfoPtr->pendingPacketLength; const int pendingPacketRemaining = sessionInfoPtr->pendingPacketRemaining; assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) ); /* Make sure that the general state is in order */ if( sessionInfoPtr->receiveBufSize < MIN_BUFFER_SIZE || \ sessionInfoPtr->receiveBufSize >= MAX_BUFFER_SIZE ) return( FALSE ); /* Make sure that the buffer position values are within bounds */ if( sessionInfoPtr->receiveBufEnd < 0 || \ sessionInfoPtr->receiveBufEnd > sessionInfoPtr->receiveBufSize || \ sessionInfoPtr->receiveBufPos < 0 || \ sessionInfoPtr->receiveBufPos > sessionInfoPtr->receiveBufEnd ) return( FALSE ); if( sessionInfoPtr->partialHeaderRemaining < 0 || \ sessionInfoPtr->partialHeaderRemaining > FIXED_HEADER_MAX ) return( FALSE ); /* If we haven't started processing data yet there's no packet information present */ if( pendingPacketLength == 0 && pendingPacketRemaining == 0 ) return( TRUE ); /* Make sure that packet information is within bounds */ if( pendingPacketLength < 0 || \ pendingPacketLength >= sessionInfoPtr->receiveBufSize || \ pendingPacketRemaining < 0 || \ pendingPacketRemaining >= sessionInfoPtr->receiveBufSize ) return( FALSE ); if( ( sessionInfoPtr->receiveBufEnd - \ sessionInfoPtr->receiveBufPos ) + pendingPacketRemaining != \ pendingPacketLength ) return( FALSE ); /* Make sure that packet header information is within bounds */ if( sessionInfoPtr->partialHeaderRemaining < 0 || \ sessionInfoPtr->partialHeaderRemaining > 16 ) return( FALSE ); /* 16 = SSH header size */ return( TRUE ); }
int cleanupHardwareContext( const CONTEXT_INFO *contextInfoPtr ) { assert( isReadPtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) ); /* If this is non-ephemeral context data then we leave it intact when the corresponding context is destroyed, the only way to delete it is with an explicit deleteItem() */ if( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) return( CRYPT_OK ); /* We have to be careful about deleting the context data since it may not have been set up yet, for example if we're called due to a failure in the complete-creation/initialisation step of setting up a context */ if( contextInfoPtr->deviceObject != CRYPT_ERROR ) hwDeleteItem( contextInfoPtr->deviceObject ); return( CRYPT_OK ); }
static void bignumToInternal( LONG *outData, int *outDataLength, const BYTE *inData, const int inDataLength ) { int inIndex, outIndex = 0, i; assert( isWritePtr( outData, CRYPT_MAX_PKCSIZE ) ); assert( isWritePtr( outDataLength, sizeof( int ) ) ); assert( isReadPtr( inData, inDataLength ) ); REQUIRES_V( inDataLength > 0 && inDataLength <= CRYPT_MAX_PKCSIZE ); for( i = 0; i < CRYPT_MAX_PKCSIZE / sizeof( LONG ); i++ ) outData[ i ] = 0L; for( inIndex = 0; inIndex < inDataLength; inIndex += sizeof( LONG ) ) { outData[ outIndex++ ] = mgetLong( inData ); } *outDataLength = outIndex; }
static BOOLEAN sanityCheck( const STREAM *stream ) { assert( isReadPtr( stream, sizeof( STREAM ) ) ); /* Null streams have no internal buffer so the buffer position indicators aren't used */ if( stream->type == STREAM_TYPE_NULL ) { /* Null streams, which act as data sinks, have a content-size indicator so although the buffer size is zero the buffer position values can be nonzero */ if( stream->bufSize != 0 ) return( FALSE ); if( stream->bufPos < 0 || stream->bufPos > stream->bufEnd || stream->bufEnd < 0 || stream->bufEnd >= MAX_BUFFER_SIZE ) return( FALSE ); return( TRUE ); } /* If it's not a null stream it has to be a memory stream */ if( stream->type != STREAM_TYPE_MEMORY ) return( FALSE ); /* Make sure that the buffer position is within bounds: bufEnd | <------ buffer ------> v +---------------------------+ | | | +---------------------------+ ^ ^ | | bufPos bufEnd */ if( stream->bufPos < 0 || stream->bufPos > stream->bufEnd || \ stream->bufEnd < 0 || stream->bufEnd > stream->bufSize || \ stream->bufSize <= 0 || stream->bufSize >= MAX_BUFFER_SIZE ) return( FALSE ); return( TRUE ); }
static int calculateCertStorage( const PKCS15_INFO *pkcs15infoPtr, OUT_PTR void **newCertDataPtr, OUT_LENGTH_SHORT_Z int *newCertDataSize, IN_LENGTH_SHORT const int certAttributeSize, IN_LENGTH_SHORT const int certSize ) { void *newCertData; assert( isReadPtr( pkcs15infoPtr, sizeof( PKCS15_INFO ) ) ); assert( isWritePtr( newCertDataPtr, sizeof( void * ) ) ); assert( isWritePtr( newCertDataSize, sizeof( int ) ) ); REQUIRES( certAttributeSize > 0 && \ certAttributeSize < MAX_INTLENGTH_SHORT ); REQUIRES( certSize > 0 && certSize < MAX_INTLENGTH_SHORT ); /* Calculate the new certificate data size */ #ifdef USE_PKCS15V12_FORM *newCertDataSize = sizeofObject( certAttributeSize + \ sizeofObject( \ sizeofObject( \ sizeofObject( certSize ) ) ) ); #else *newCertDataSize = sizeofObject( certAttributeSize + \ sizeofObject( \ sizeofObject( certSize ) ) ); #endif /* USE_PKCS15V12_FORM */ ENSURES( *newCertDataSize > 0 && *newCertDataSize < MAX_INTLENGTH ); /* If the new data will fit into the existing storage, we're done */ if( *newCertDataSize <= pkcs15infoPtr->certDataSize ) return( CRYPT_OK ); /* Allocate storage for the new data */ newCertData = clAlloc( "calculateCertStorage", *newCertDataSize ); if( newCertData == NULL ) return( CRYPT_ERROR_MEMORY ); *newCertDataPtr = newCertData; return( CRYPT_OK ); }
const CAPABILITY_INFO FAR_BSS *findCapabilityInfo( const CAPABILITY_INFO_LIST *capabilityInfoList, IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo ) { const CAPABILITY_INFO_LIST *capabilityInfoListPtr; int iterationCount; assert( isReadPtr( capabilityInfoList, sizeof( CAPABILITY_INFO_LIST ) ) ); /* Find the capability corresponding to the requested algorithm/mode */ for( capabilityInfoListPtr = capabilityInfoList, iterationCount = 0; capabilityInfoListPtr != NULL && iterationCount < FAILSAFE_ITERATIONS_MED; capabilityInfoListPtr = capabilityInfoListPtr->next, iterationCount++ ) { if( capabilityInfoListPtr->info->cryptAlgo == cryptAlgo ) return( capabilityInfoListPtr->info ); } ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_MED ); return( NULL ); }
static void bignumToExternal( BYTE *outData, int *outDataLength, const LONG *inData, const int inDataLength ) { int inIndex = 0, outIndex; assert( isWritePtr( outData, CRYPT_MAX_PKCSIZE ) ); assert( isWritePtr( outDataLength, sizeof( int ) ) ); assert( isReadPtr( inData, inDataLength * sizeof( LONG ) ) ); REQUIRES_V( inDataLength > 0 && \ inDataLength <= CRYPT_MAX_PKCSIZE / sizeof( LONG ) ); memset( outData, 0, CRYPT_MAX_PKCSIZE ); for( outIndex = 0; outIndex < inDataLength; outIndex++ ) { const LONG value = inData[ inIndex++ ]; mputLong( outData, value ); } *outDataLength = outIndex * sizeof( LONG ); }
static int getAttributeEncodingInfo( const ATTRIBUTE_LIST *attributeListPtr, OUT_OPT_PTR \ ATTRIBUTE_INFO **attributeInfoPtrPtr, OUT_INT_Z int *attributeDataSize ) { const ATTRIBUTE_INFO *attributeInfoPtr; BOOLEAN isConstructed = FALSE; assert( isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) ); assert( isWritePtr( attributeInfoPtrPtr, sizeof( ATTRIBUTE_INFO * ) ) ); assert( isWritePtr( attributeDataSize, sizeof( int ) ) ); /* Clear return value */ *attributeInfoPtrPtr = NULL; /* If it's a constructed attribute then the encoding information for the outermost wrapper will be recorded in the encoding FIFO, otherwise it's present directly */ if( attributeListPtr->fifoEnd > 0 ) { attributeInfoPtr = \ attributeListPtr->encodingFifo[ attributeListPtr->fifoEnd - 1 ]; isConstructed = TRUE; } else attributeInfoPtr = attributeListPtr->attributeInfoPtr; ENSURES( attributeInfoPtr != NULL ); /* Determine the size of the attribute payload */ if( isConstructed && attributeInfoPtr->fieldType != FIELDTYPE_CHOICE ) { *attributeDataSize = ( int ) sizeofObject( \ attributeListPtr->sizeFifo[ attributeListPtr->fifoEnd - 1 ] ); } else *attributeDataSize = attributeListPtr->encodedSize; *attributeInfoPtrPtr = ( ATTRIBUTE_INFO * ) attributeInfoPtr; return( CRYPT_OK ); }