38 const long position = stell( stream );
45 REQUIRES( maxMpiSize > 0 && maxMpiSize >= minMpiSize && \
51 status = readInteger16Ubits( stream, NULL, &dummy, minMpiSize,
55 *length = ( int ) stell( stream ) -
position;
67 static
int getMinPacketSize(
IN_BYTE const int packetType )
70 packetType <= 0xFF ), 0 );
96 assert(
isWritePtr( packetGroupLength,
sizeof(
int ) ) );
99 *packetGroupLength = 0;
109 ctb = status = sPeek( stream );
142 status = pgpReadPacketHeader( stream, NULL, &length, \
143 getMinPacketSize( type ) );
146 endPos = stell( stream ) +
length;
147 status = sSkip( stream, length );
160 ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
165 *packetGroupLength =
endPos;
178 static
int readPrivateKeyDecryptionInfo(
INOUT STREAM *stream,
181 const int ctb = sgetc( stream );
189 keyInfo->saltSize = keyInfo->keySetupIterations = 0;
211 status = sread( stream, keyInfo->iv, ivSize );
214 keyInfo->ivSize = ivSize;
226 value = sPeek( stream );
227 status = readPgpAlgo( stream, &keyInfo->cryptAlgo,
248 status =
value = sgetc( stream );
253 status = readPgpAlgo( stream, &keyInfo->hashAlgo,
306 value = sgetc( stream );
309 iterations = ( 16 + ( ( long )
value & 0x0F ) ) << (
value >> 4 );
312 if( iterations >= 32768L )
314 keyInfo->keySetupIterations = ( int ) iterations;
324 keyInfo->hashedChecksum =
TRUE;
326 status = sread( stream, keyInfo->iv, ivSize );
329 keyInfo->ivSize = ivSize;
337 static
int readPublicKeyComponents(
INOUT STREAM *stream,
346 assert(
isWritePtr( pubKeyComponentLength,
sizeof(
int ) ) );
349 *pubKeyComponentLength = 0;
352 status = pgpPkcAlgo = sgetc( stream );
382 *pubKeyComponentLength = totalLength +
length;
430 *pubKeyComponentLength = totalLength;
447 assert( pgpInfo == NULL || \
449 assert( hashInfo == NULL || \
454 if( hashInfo != NULL )
455 memcpy( &localHashInfo, hashInfo,
sizeof(
HASHINFO ) );
475 for( status =
CRYPT_OK, iterationCount = 0;
481 status = ctb = sPeek( stream );
494 status = pgpReadPacketHeader( stream, &ctb, &packetLength, \
495 getMinPacketSize( packetType ) );
498 status = sSkip( stream, packetLength );
500 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
513 status = pgpReadPacketHeader( stream, &ctb, &packetLength, \
514 getMinPacketSize( packetType ) );
521 status = sMemGetDataBlock( stream, &dataPtr, packetLength );
524 pgpInfo->userID[ pgpInfo->lastUserID ] = dataPtr;
525 pgpInfo->userIDlen[ pgpInfo->lastUserID++ ] = ( int ) packetLength;
527 return( sSkip( stream, packetLength ) );
602 int pubKeyPos, pubKeyPayloadPos,
endPos, pubKeyPayloadLen;
612 ctb = sPeek( stream );
624 keyInfo = &pgpInfo->subKey;
633 keyInfo = &pgpInfo->subKey;
643 "Invalid PGP CTB %02X for key packet group %d",
646 status = pgpReadPacketHeader( stream, NULL, &packetLength, 64 );
651 "Invalid PGP key packet header for key packet group %d",
654 if( packetLength < 64 || packetLength > sMemDataLeft( stream ) )
658 "Invalid PGP key packet length %ld for key packet group %d",
659 packetLength, keyGroupNo ) );
668 status = sSkip( stream, packetLength );
669 for( iterationCount = 0;
674 status = readUserID( stream, pgpInfo,
675 isPrimaryKey ? &hashInfo : NULL );
677 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
682 "Invalid additional PGP subkey information for key "
683 "packet group %d", keyGroupNo ) );
703 pubKeyPos = stell( stream );
706 status = value = sgetc( stream );
732 packetHeader[ 0 ] = 0x99;
736 status = sread( stream, packetHeader + 4, 4 );
738 status = sSkip( stream, 2 );
743 pubKeyPayloadPos = stell( stream );
744 status = readPublicKeyComponents( stream, keyInfo, &length );
752 DEBUG_DIAG((
"Encountered unrecognised algorithm while "
759 "Invalid PGP public-key components for key packet group %d",
766 status = sMemGetDataBlockAbs( stream, pubKeyPos, &keyInfo->pubKeyData,
770 DEBUG_DIAG((
"Couldn't set up reference to key data" ));
774 pubKeyPayloadLen = stell( stream ) - pubKeyPayloadPos;
775 status = sMemGetDataBlockAbs( stream, pubKeyPayloadPos, &pubKeyPayload,
779 DEBUG_DIAG((
"Couldn't set up reference to key data" ));
786 packetHeader[ 1 ] =
intToByte( ( ( 1 + 4 + length ) >> 8 ) & 0xFF );
787 packetHeader[ 2 ] =
intToByte( ( 1 + 4 + length ) & 0xFF );
791 hashFunction( hashInfo, NULL, 0, packetHeader, 1 + 2 + 1 + 4,
803 status = readPrivateKeyDecryptionInfo( stream, keyInfo );
811 DEBUG_DIAG((
"Encountered unrecognised algorithm while "
818 "Invalid PGP private-key decryption information for "
819 "key packet group %d", keyGroupNo ) );
824 status = sMemGetDataBlock( stream, &keyInfo->privKeyData,
836 packetHeader[ 0 ] = 0x99;
847 for( iterationCount = 0;
852 status = readUserID( stream, pgpInfo,
853 isPrimaryKey ? &hashInfo : NULL );
855 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
860 "Invalid PGP userID information for key packet group %d",
865 if( pgpInfo->lastUserID <= 0 )
867 pgpInfo->userID[ 0 ] =
"PGP key (no user ID found)";
868 pgpInfo->userIDlen[ 0 ] = 26;
869 pgpInfo->lastUserID = 1;
878 static
int processPacketGroup(
INOUT STREAM *stream,
885 int iterationCount,
status;
889 assert( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
893 REQUIRES( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
894 ( keyMatchInfo != NULL && matchedKeyInfoPtrPtr != NULL && \
895 pgpInfo->keyData != NULL && \
904 memset( &pgpInfo->subKey, 0,
sizeof(
PGP_KEYINFO ) );
907 pgpInfo->lastUserID = 0;
910 for( status =
CRYPT_OK, iterationCount = 0;
915 status = readKey( stream, pgpInfo, keyGroupNo, errorInfo );
917 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
925 if( keyMatchInfo == NULL )
926 pgpFreeEntry( pgpInfo );
931 if( keyMatchInfo == NULL )
935 if( pgpCheckKeyMatch( pgpInfo, &pgpInfo->key, keyMatchInfo ) )
937 *matchedKeyInfoPtrPtr = &pgpInfo->key;
940 if( pgpCheckKeyMatch( pgpInfo, &pgpInfo->subKey, keyMatchInfo ) )
942 *matchedKeyInfoPtrPtr = &pgpInfo->subKey;
963 static
int processKeyringPackets(
INOUT STREAM *stream,
975 int bufEnd, keyGroupNo = 0, iterationCount,
status;
980 assert( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
987 REQUIRES( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
988 ( keyMatchInfo != NULL && matchedKeyInfoPtrPtr != NULL && \
989 pgpInfo->keyData != NULL && \
994 *unhandledDataPresent =
FALSE;
1004 for( moreData =
TRUE, bufEnd = 0, iterationCount = 0;
1005 ( moreData || bufEnd > 0 ) && \
1009 PGP_INFO *pgpInfoPtr = &pgpInfo[ keyGroupNo ];
1025 REQUIRES( bufEnd >= 0 && bufEnd < bufSize );
1027 status = length = sread( stream, buffer + bufEnd,
1037 if( keyGroupNo > 0 )
1046 if( length < bufSize - bufEnd )
1056 sMemConnect( &keyStream, buffer, bufEnd );
1057 status = scanPacketGroup( &keyStream, &length, !moreData );
1058 sMemDisconnect( &keyStream );
1062 *unhandledDataPresent =
TRUE;
1066 if( length <= bufEnd )
1068 if( bufEnd - length > 0 )
1072 memmove( buffer, buffer + length, bufEnd - length );
1081 status = sseek( stream, stell( stream ) + ( length - bufEnd ) );
1090 ( status, errorInfo,
1091 "Couldn't parse key packet group %d", keyGroupNo ) );
1097 if( keyMatchInfo == NULL )
1101 if( ( pgpInfoPtr->keyData = \
1102 clAlloc(
"readKeyring", length ) ) == NULL )
1106 memcpy( pgpInfoPtr->keyData, buffer, length );
1107 if( bufEnd > length )
1110 memmove( buffer, buffer + length, bufEnd - length );
1115 sMemConnect( &keyStream, pgpInfoPtr->keyData, length );
1116 status = processPacketGroup( &keyStream, pgpInfoPtr, keyMatchInfo,
1117 matchedKeyInfoPtrPtr, keyGroupNo,
1119 sMemDisconnect( &keyStream );
1133 *unhandledDataPresent =
TRUE;
1135 insecureKeys =
TRUE;
1140 if( keyMatchInfo != NULL )
1148 if( keyGroupNo >= maxNoPgpObjects )
1152 "Maximum keyset object item count %d reached, no more "
1153 "room to add further items", maxNoPgpObjects ) );
1159 if( keyMatchInfo != NULL )
1171 if( keyGroupNo <= 0 )
1194 assert( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
1199 REQUIRES( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
1200 ( keyMatchInfo != NULL && matchedKeyInfoPtrPtr != NULL && \
1201 pgpInfo->keyData != NULL && \
1206 if( matchedKeyInfoPtrPtr != NULL )
1207 *matchedKeyInfoPtrPtr = NULL;
1216 status = processKeyringPackets( stream, pgpInfo, maxNoPgpObjects,
1218 keyMatchInfo, matchedKeyInfoPtrPtr,
1219 &unhandledDataPresent, errorInfo );
1221 clFree(
"readKeyring", buffer );