static void dummyGenRandom( void *buffer, const int length ) { HASHFUNCTION_ATOMIC hashFunctionAtomic; BYTE hashBuffer[ CRYPT_MAX_HASHSIZE ], *bufPtr = buffer; static int counter = 0; int hashSize, i; assert( isWritePtr( buffer, length ) ); REQUIRES_V( length >= 1 && length < MAX_BUFFER_SIZE ); /* Fill the buffer with random-ish data. This gets a bit tricky because we need to fool the entropy tests so we can't just fill it with a fixed (or even semi-random) pattern but have to set up a somewhat kludgy PRNG */ getHashAtomicParameters( CRYPT_ALGO_SHA1, 0, &hashFunctionAtomic, &hashSize ); memset( hashBuffer, counter, hashSize ); counter++; for( i = 0; i < length; i++ ) { if( i % hashSize == 0 ) { hashFunctionAtomic( hashBuffer, CRYPT_MAX_HASHSIZE, hashBuffer, hashSize ); } bufPtr[ i ] = hashBuffer[ i % hashSize ]; } }
CHECK_RETVAL \ int checkDHdata( void ) { HASHFUNCTION_ATOMIC hashFunctionAtomic; BYTE hashValue[ 20 + 8 ]; getHashAtomicParameters( CRYPT_ALGO_SHA1, 0, &hashFunctionAtomic, NULL ); /* Generate/check the SHA-1 values for the primes. This doesn't cover all of the data, but is needed to bootstrap the full check because only the hashes of the primes have been published */ #if 0 hashFunctionAtomic( hashValue, 20, dh1024SSL + 2, sizeof( dh1024SSL ) - 5 ); hashFunctionAtomic( hashValue, 20, dh1536SSL + 2, sizeof( dh1536SSL ) - 5 ); hashFunctionAtomic( hashValue, 20, dh2048SSL + 2, sizeof( dh2048SSL ) - 5 ); hashFunctionAtomic( hashValue, 20, dh3072SSL + 2, sizeof( dh3072SSL ) - 5 ); #endif /* 0 */ /* Check the SHA-1 values for the DH data */ hashFunctionAtomic( hashValue, 20, dh1024SSL, sizeof( dh1024SSL ) ); if( memcmp( hashValue, \ "\x46\xF4\x47\xC3\x69\x00\x6F\x22\x91\x0E\x24\xF5\x73\x68\xE6\xF7", 16 ) ) retIntError(); hashFunctionAtomic( hashValue, 20, dh1536SSL, sizeof( dh1536SSL ) ); if( memcmp( hashValue, \ "\xA3\xEC\x2F\x85\xC7\xD3\x74\xD2\x56\x53\x22\xED\x53\x87\x6F\xDC", 16 ) ) retIntError(); hashFunctionAtomic( hashValue, 20, dh2048SSL, sizeof( dh2048SSL ) ); if( memcmp( hashValue, \ "\x0E\x8E\x49\x9F\xD9\x18\x02\xCB\x5D\x42\x03\xA5\xE1\x67\x51\xDB", 16 ) ) retIntError(); hashFunctionAtomic( hashValue, 20, dh3072SSL, sizeof( dh3072SSL ) ); if( memcmp( hashValue, \ "\x8F\x4A\x19\xEF\x85\x1D\x91\xEA\x18\xE8\xB8\xB9\x9F\xF0\xFD\xF8", 16 ) ) retIntError(); /* Now that we've verified that the DH data is valid, calculate a checksum for each value to allow it to be quickly checked before it's loaded into a context */ dh1024checksum = checksumData( dh1024SSL, sizeof( dh1024SSL ) ); dh1536checksum = checksumData( dh1536SSL, sizeof( dh1536SSL ) ); dh2048checksum = checksumData( dh2048SSL, sizeof( dh2048SSL ) ); dh3072checksum = checksumData( dh3072SSL, sizeof( dh3072SSL ) ); return( CRYPT_OK ); }
static int readKeyIdentifiers( INOUT STREAM *stream, INOUT PKCS15_INFO *pkcs15infoPtr, IN_LENGTH const int endPos ) { int iterationCount, status; assert( isWritePtr( stream, sizeof( STREAM ) ) ); assert( isWritePtr( pkcs15infoPtr, sizeof( PKCS15_INFO ) ) ); REQUIRES( endPos > 0 && endPos > stell( stream ) && \ endPos < MAX_INTLENGTH ); for( status = CRYPT_OK, iterationCount = 0; cryptStatusOK( status ) && stell( stream ) < endPos && \ iterationCount < FAILSAFE_ITERATIONS_MED; iterationCount++ ) { long value; int payloadLength; /* Read each identifier type and copy the useful ones into the PKCS #15 information */ readSequence( stream, &payloadLength ); status = readShortInteger( stream, &value ); if( cryptStatusError( status ) ) return( status ); switch( value ) { case PKCS15_KEYID_ISSUERANDSERIALNUMBER: { HASHFUNCTION_ATOMIC hashFunctionAtomic; void *iAndSPtr = DUMMY_INIT_PTR; int iAndSLength, hashSize; /* If we've already got the iAndSID, use that version instead */ if( pkcs15infoPtr->iAndSIDlength > 0 ) { status = readUniversal( stream ); continue; } /* Hash the full issuerAndSerialNumber to get an iAndSID */ getHashAtomicParameters( CRYPT_ALGO_SHA1, 0, &hashFunctionAtomic, &hashSize ); status = getStreamObjectLength( stream, &iAndSLength ); if( cryptStatusOK( status ) ) status = sMemGetDataBlock( stream, &iAndSPtr, iAndSLength ); if( cryptStatusOK( status ) ) status = sSkip( stream, iAndSLength ); if( cryptStatusError( status ) ) return( status ); hashFunctionAtomic( pkcs15infoPtr->iAndSID, KEYID_SIZE, iAndSPtr, iAndSLength ); pkcs15infoPtr->iAndSIDlength = hashSize; break; } case PKCS15_KEYID_SUBJECTKEYIDENTIFIER: status = readOctetString( stream, pkcs15infoPtr->keyID, &pkcs15infoPtr->keyIDlength, 8, CRYPT_MAX_HASHSIZE ); break; case PKCS15_KEYID_ISSUERANDSERIALNUMBERHASH: /* If we've already got the iAndSID by hashing the issuerAndSerialNumber, use that version instead */ if( pkcs15infoPtr->iAndSIDlength > 0 ) { status = readUniversal( stream ); continue; } status = readOctetString( stream, pkcs15infoPtr->iAndSID, &pkcs15infoPtr->iAndSIDlength, KEYID_SIZE, KEYID_SIZE ); break; case PKCS15_KEYID_ISSUERNAMEHASH: status = readOctetString( stream, pkcs15infoPtr->issuerNameID, &pkcs15infoPtr->issuerNameIDlength, KEYID_SIZE, KEYID_SIZE ); break; case PKCS15_KEYID_SUBJECTNAMEHASH: status = readOctetString( stream, pkcs15infoPtr->subjectNameID, &pkcs15infoPtr->subjectNameIDlength, KEYID_SIZE, KEYID_SIZE ); break; case PKCS15_KEYID_PGP2: status = readOctetString( stream, pkcs15infoPtr->pgp2KeyID, &pkcs15infoPtr->pgp2KeyIDlength, PGP_KEYID_SIZE, PGP_KEYID_SIZE ); break; case PKCS15_KEYID_OPENPGP: status = readOctetString( stream, pkcs15infoPtr->openPGPKeyID, &pkcs15infoPtr->openPGPKeyIDlength, PGP_KEYID_SIZE, PGP_KEYID_SIZE ); break; default: status = readUniversal( stream ); } } if( iterationCount >= FAILSAFE_ITERATIONS_MED ) { /* This could be either an internal error or some seriously malformed data, since we can't tell without human intervention we throw a debug exception but otherwise treat it as bad data */ DEBUG_DIAG(( "Encountered more than %d key IDs", FAILSAFE_ITERATIONS_MED )); assert( DEBUG_WARN ); return( CRYPT_ERROR_BADDATA ); } return( status ); }