sl@0: /* sl@0: * Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * testinteger.cpp sl@0: * Implementation for testing TInteger encoding/decoding sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include "testbigint.h" sl@0: #include "tasn1normaltest.h" sl@0: #include sl@0: #include sl@0: sl@0: #include sl@0: sl@0: sl@0: CTestBigInt* CTestBigInt::NewL(CASN1NormalTest &aASN1Action) sl@0: { sl@0: CTestBigInt* test = new (ELeave) CTestBigInt(aASN1Action); sl@0: return test; sl@0: } sl@0: sl@0: CTestBigInt::CTestBigInt(CASN1NormalTest &aASN1Action) : CTestBase(aASN1Action) sl@0: { sl@0: }; sl@0: sl@0: void CTestBigInt::GetName(TDes& aBuf) sl@0: { sl@0: aBuf.Copy(_L("Test BigInteger")); sl@0: } sl@0: sl@0: void CTestBigInt::FillParameterArray(void) sl@0: { sl@0: iParameters->Append(CTestParameter::EInt); sl@0: } sl@0: sl@0: sl@0: // This function can leave sl@0: TBool CTestBigInt::PerformTest(CConsoleBase& aConsole, const RInteger& aTest, const TInt &aTestNumber, const TInt &aTotalTests) sl@0: { sl@0: // Make the value to encode sl@0: RInteger encodedValue = RInteger::NewL(0); sl@0: CleanupStack::PushL(encodedValue); sl@0: encodedValue.CopyL(aTest); sl@0: sl@0: // Make the encoder sl@0: CASN1EncBigInt* encoder = CASN1EncBigInt::NewLC(encodedValue); sl@0: sl@0: // Prepare a buffer sl@0: HBufC8* buf = HBufC8::NewMaxLC(encoder->LengthDER()); sl@0: TPtr8 tBuf = buf->Des(); sl@0: sl@0: // Write into the buffer sl@0: TUint writeLength = 0; sl@0: encoder->WriteDERL(tBuf, writeLength); sl@0: sl@0: // Read it out again sl@0: TASN1DecInteger decoder; sl@0: TInt readLength = 0; sl@0: RInteger decodedValue = decoder.DecodeDERLongL(tBuf, readLength); sl@0: CleanupStack::PushL(decodedValue); sl@0: sl@0: //Check that a positive integer has not been encoded as negative - DEF038956 sl@0: TBool negEncodeErr = EFalse; sl@0: RInteger null = RInteger::NewL(0); sl@0: CleanupStack::PushL(null); sl@0: if (aTest > null) sl@0: { sl@0: HBufC8* originalValue = aTest.BufferLC(); sl@0: TPtrC8 tOriginalValue = originalValue->Des(); sl@0: //determine which byte to check (should a leading zero byte have been added) sl@0: if ((*originalValue)[0] & 0x80) sl@0: { sl@0: //for example 000000FF, aTest value FF, *buf 020200FF need to confirm (*buf)[2] is 00 sl@0: //encoder->LengthDER() = 4, tOriginalValue.Length() = 1 sl@0: if ((*buf)[encoder->LengthDER() - tOriginalValue.Length() - 1] != 0) sl@0: { sl@0: negEncodeErr = ETrue; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: //for example 0000007F, aTest value 7F, *buf 02027F need to confirm leading bit (*buf)[2] not set sl@0: //encoder->LengthDER() = 3, tOriginalValue.Length() = 1 sl@0: if ((*buf)[encoder->LengthDER() - tOriginalValue.Length()] & 0x80) sl@0: { sl@0: negEncodeErr = ETrue; sl@0: } sl@0: } sl@0: CleanupStack::PopAndDestroy(); //originalValue sl@0: } sl@0: CleanupStack::PopAndDestroy(&null); //null sl@0: sl@0: // Check lengths of reads + values sl@0: if ((writeLength != STATIC_CAST(TUint, readLength)) || !(decodedValue == encodedValue) || (negEncodeErr)) sl@0: //if(1) sl@0: { sl@0: aConsole.Printf(_L("\nERROR! Problem integer: \n")); sl@0: OutputIntegerL(aConsole, encodedValue); sl@0: OutputIntegerL(aConsole, decodedValue); sl@0: OutputEncodingL(aConsole, tBuf); sl@0: iASN1Action.ReportProgressL(KErrASN1EncodingError, aTestNumber, aTotalTests); sl@0: CleanupStack::PopAndDestroy(4, &encodedValue); // decodedValue, buf, encoder, encodedValue sl@0: return(EFalse); sl@0: } sl@0: else sl@0: { sl@0: iASN1Action.ReportProgressL(KErrNone, aTestNumber, aTotalTests); sl@0: CleanupStack::PopAndDestroy(4, &encodedValue); // decodedValue, buf, encoder, encodedValue sl@0: return(ETrue); sl@0: } sl@0: } sl@0: sl@0: sl@0: void CTestBigInt::OutputIntegerL(CConsoleBase& aConsole, RInteger& aInt) sl@0: { sl@0: aConsole.Printf(_L("Bytes() = ")); sl@0: TBuf<10> bytes; sl@0: bytes.AppendNum(aInt.ByteCount()); sl@0: bytes.Append(_L(", ")); sl@0: aConsole.Printf(bytes); sl@0: sl@0: aConsole.Printf(_L("Bits() = ")); sl@0: TBuf<10> bits; sl@0: bits.AppendNum(aInt.BitCount()); sl@0: bits.Append(_L(", ")); sl@0: aConsole.Printf(bits); sl@0: sl@0: HBufC8* buf = aInt.BufferLC(); sl@0: TPtr8 ptr = buf->Des(); sl@0: TInt size = ptr.Length(); sl@0: for (TInt i = 0; i < size; ++i) sl@0: { sl@0: TBuf<10> tbuf; sl@0: tbuf.AppendNumFixedWidth(ptr[i], EHex, 2); sl@0: aConsole.Printf(tbuf); sl@0: } sl@0: sl@0: RInteger null = RInteger::NewL(0); sl@0: if (aInt < null) sl@0: { sl@0: ASSERT(EFalse); // Shouldn't happen for new crypto api - no signed integers sl@0: aConsole.Printf(_L(" (-ve)")); sl@0: } sl@0: else sl@0: { sl@0: aConsole.Printf(_L(" (+ve)")); sl@0: } sl@0: sl@0: null.Close(); sl@0: sl@0: aConsole.Printf(_L("\n")); sl@0: CleanupStack::PopAndDestroy(); // buf; sl@0: } sl@0: sl@0: sl@0: TBool CTestBigInt::PerformTestsL(CConsoleBase& aConsole) sl@0: { sl@0: const TInt KMaxBits = 2048; sl@0: CTestParameter* test; sl@0: TInt totalTests, currentTest=0; sl@0: sl@0: if(!CountTests(totalTests)) return(EFalse); sl@0: sl@0: for(TInt pos = 0; pos < iValues->Count(); pos++) sl@0: { sl@0: test = (*iValues)[pos]; sl@0: sl@0: switch(test->GetType()) sl@0: { sl@0: case CTestParameter::EInt : sl@0: { sl@0: CIntTestParameter *rangeInt = REINTERPRET_CAST(CIntTestParameter*, test); sl@0: RInteger encodedValue; sl@0: encodedValue = RInteger::NewL(rangeInt->Value()); sl@0: CleanupStack::PushL(encodedValue); sl@0: if(PerformTest(aConsole, encodedValue, currentTest, totalTests)) sl@0: CleanupStack::PopAndDestroy(&encodedValue); sl@0: else sl@0: { sl@0: CleanupStack::PopAndDestroy(&encodedValue); sl@0: return(EFalse); sl@0: }; sl@0: currentTest++; sl@0: break; sl@0: } sl@0: case CTestParameter::EIntRange : sl@0: { sl@0: CIntRangeTestParameter *rangeInt = REINTERPRET_CAST(CIntRangeTestParameter*, test); sl@0: for(TInt test = rangeInt->Start(); test <= rangeInt->Finish(); test++) sl@0: { sl@0: RInteger encodedValue; sl@0: encodedValue = RInteger::NewL(test); sl@0: CleanupStack::PushL(encodedValue); sl@0: if(PerformTest(aConsole, encodedValue, currentTest, totalTests)) sl@0: CleanupStack::PopAndDestroy(&encodedValue); sl@0: else sl@0: { sl@0: CleanupStack::PopAndDestroy(&encodedValue); sl@0: return(EFalse); sl@0: } sl@0: currentTest++; sl@0: }; sl@0: break; sl@0: } sl@0: case CTestParameter::ERandom : sl@0: { sl@0: CRandomTestParameter *randomInt = REINTERPRET_CAST(CRandomTestParameter*, test); sl@0: for(TInt test = 0; test <= randomInt->Interations(); test++) sl@0: { sl@0: RInteger encodedValue; sl@0: encodedValue = RInteger::NewRandomL((test % KMaxBits) + 1, TInteger::EAllBitsRandom); sl@0: CleanupStack::PushL(encodedValue); sl@0: if(PerformTest(aConsole, encodedValue, currentTest, totalTests)) sl@0: CleanupStack::PopAndDestroy(&encodedValue); sl@0: else sl@0: { sl@0: CleanupStack::PopAndDestroy(&encodedValue); sl@0: return(EFalse); sl@0: } sl@0: currentTest++; sl@0: } sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: return EFalse; sl@0: } sl@0: } sl@0: } sl@0: iASN1Action.ReportProgressL(KErrNone, totalTests, totalTests); sl@0: return(ETrue); sl@0: }; sl@0: