sl@0: /* sl@0: * Copyright (c) 1998-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: * This file contains the implementation of the UTC time ASN1 object. sl@0: * At this moment in time this class will only deal with Zulu times and sl@0: * doesn't have any kind of handling for time offsets. This is not going to be sl@0: * a problem for certificate implementations as the PKIX (RFC2459) profile sl@0: * defines that certificate validity periods are specified as Zulu times. sl@0: * Points that need updating if handling for offsets are marked with __OFFSET__ sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include sl@0: sl@0: EXPORT_C TASN1DecUTCTime::TASN1DecUTCTime() sl@0: { sl@0: } sl@0: sl@0: sl@0: TTime TASN1DecUTCTime::GetTimeL(const TDesC8& aSource) sl@0: sl@0: { sl@0: // __OFFSET__ Extract corrected time to include offset too. sl@0: sl@0: // Did this checking ought to be done on creation rather than when we attempt to get the result? sl@0: // YES! sl@0: sl@0: // I guess we ought to check that the contents we've got are long enough to contain a time! sl@0: if (aSource.Length()<11) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: // Check all digits the main bit of time are valid - this doesn't check the seconds or offset sl@0: TInt i; sl@0: for (i=0;i<10;i++) sl@0: { sl@0: TUint8 j; sl@0: j=(TUint8)(aSource[i]-'0'); sl@0: if (j>=10) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: } sl@0: // Uh-oh, looks like we're going to have to pull each bit manually and pop it in a TDateTime thing sl@0: TInt Year,Month,Day,Hour,Minute,Second=0; // Only set seconds to zero 'cos they are optional, everything else is going to be set sl@0: Year=(aSource[0]-'0')*10+aSource[1]-'0'; sl@0: Year+=(Year<50)?2000:1900; // collection to fit with PKIX UTC/Generalised time rollover at 2049/2050 sl@0: Month=(aSource[2]-'0')*10+aSource[3]-'0'; sl@0: Month--; // Because the enum for months starts at 0 not 1 sl@0: Day=((aSource[4]-'0')*10+aSource[5]-'0') -1;//added -1 for offset from zero(!) sl@0: Hour=(aSource[6]-'0')*10+aSource[7]-'0'; sl@0: Minute=(aSource[8]-'0')*10+aSource[9]-'0'; sl@0: TInt Pos=10; sl@0: sl@0: if (aSource.Length()>11) sl@0: { sl@0: if ((aSource[Pos]>='0')&&(aSource[Pos]<='9')) sl@0: { sl@0: // seconds sl@0: Second=(aSource[Pos++]-'0')*10; sl@0: Second += aSource[Pos++]-'0'; sl@0: } sl@0: } sl@0: if (aSource.Length()>Pos) sl@0: { sl@0: switch (aSource[Pos]) sl@0: { sl@0: case 'Z': sl@0: // Zulu - nothing more to do sl@0: break; sl@0: case '+': sl@0: case '-': sl@0: // __OFFSET__ Extract corrected time to include offset too. sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: default: sl@0: // Error! sl@0: User::Leave(KErrArgument); sl@0: break; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: if (MonthEDecember) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: TMonth month = (TMonth)Month; sl@0: sl@0: if ( (Day<0 || Day>=Time::DaysInMonth(Year,month)) || sl@0: (Hour<0 || Hour>=24) || sl@0: (Minute<0 || Minute>=60) || sl@0: (Second<0 || Second>=60) ) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: TDateTime D(Year,month,Day,Hour,Minute,Second,0); sl@0: sl@0: TTime T(D); sl@0: return T; sl@0: } sl@0: sl@0: // __OFFSET__ Add GetOffset() method sl@0: sl@0: EXPORT_C TTime TASN1DecUTCTime::DecodeDERL(const TDesC8& aSource,TInt& aPos) sl@0: sl@0: { sl@0: TPtrC8 Source=aSource.Mid(aPos); sl@0: TASN1DecGeneric gen(Source); sl@0: gen.InitL(); sl@0: TTime t = GetTimeL(gen.GetContentDER()); sl@0: aPos+=gen.LengthDER(); sl@0: return t; sl@0: } sl@0: sl@0: EXPORT_C TTime TASN1DecUTCTime::DecodeDERL(const TASN1DecGeneric& aGen) sl@0: sl@0: { sl@0: return GetTimeL(aGen.GetContentDER()); sl@0: }