1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/securityanddataprivacytools/securitytools/certapp/encdec/encdec.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,398 @@
1.4 +#ifndef __ENCDEC_H__
1.5 +#define __ENCDEC_H__/*
1.6 +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.7 +* All rights reserved.
1.8 +* This component and the accompanying materials are made available
1.9 +* under the terms of the License "Eclipse Public License v1.0"
1.10 +* which accompanies this distribution, and is available
1.11 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.12 +*
1.13 +* Initial Contributors:
1.14 +* Nokia Corporation - initial contribution.
1.15 +*
1.16 +* Contributors:
1.17 +*
1.18 +* Description:
1.19 +*
1.20 +*/
1.21 +
1.22 +
1.23 +#include <s32strm.h>
1.24 +#include "filestream.h"
1.25 +#include "logger.h"
1.26 +
1.27 +/**
1.28 + * @file
1.29 + * @internalComponent
1.30 + */
1.31 +
1.32 +typedef uint64_t TUint64;
1.33 +typedef int64_t TInt64;
1.34 +
1.35 +typedef int TInt32;
1.36 +typedef unsigned int TUint32;
1.37 +
1.38 +typedef short TInt16;
1.39 +typedef unsigned short TUint16;
1.40 +
1.41 +typedef signed char TInt8;
1.42 +typedef unsigned char TUint8;
1.43 +
1.44 +typedef TUint32 TChar;
1.45 +
1.46 +typedef int TBool;
1.47 +
1.48 +typedef void TAny;
1.49 +
1.50 +TUint8 fromHex(TUint8 ch);
1.51 +TUint32 ReadUnsignedNumber(std::string &aStr, size_t aSize);
1.52 +class RDecodeReadStream
1.53 + {
1.54 +public:
1.55 + // Create store based stream in binary mode
1.56 + RDecodeReadStream(CFileStore *aStore, RReadStream &aReadStream);
1.57 + // Create a file based stream in human mode
1.58 + RDecodeReadStream(const std::string &aCertBaseName, RReadStream &aReadStream);
1.59 +
1.60 + void RawRead(void *aPtr, TUint32 aLength);
1.61 +
1.62 + void CheckName(const std::string &aExpected);
1.63 + TUint32 ReadUnsignedNumber(size_t aSize);
1.64 +
1.65 + // Return current token
1.66 + const std::string &Token() const;
1.67 + // Discard current token and read the next
1.68 + void ReadNextToken();
1.69 +
1.70 + // Return the token after the current token.
1.71 + // The current token is not updated.
1.72 + // This will only look ahead a single token.
1.73 + const std::string &PeakToken();
1.74 +
1.75 + bool HumanReadable() const;
1.76 + void Close();
1.77 +
1.78 + CFileStore *iStore; // Only used for STORE based streams ie. not human readable
1.79 + std::string iCertBaseName; // Only used for file based streams ie. human readable
1.80 +
1.81 + RReadStream &iReadStream;
1.82 +private:
1.83 + bool iHumanReadable;
1.84 + std::string iToken;
1.85 + bool iPrefetchedTokenIsValid;
1.86 + std::string iPrefetchedToken;
1.87 +
1.88 + void GetToken(std::string &aToken);
1.89 + };
1.90 +
1.91 +
1.92 +class REncodeWriteStream
1.93 + {
1.94 +public:
1.95 + // Construct stream based on a store in binary mode
1.96 + REncodeWriteStream(CFileStore *aStore, RWriteStream &aWriteStream); // store stream
1.97 + // Construct stream based on a file in human mode
1.98 + REncodeWriteStream(const std::string &aCertBaseName, RWriteStream &aWriteStream); // file stream
1.99 + // Create a human readable log
1.100 + REncodeWriteStream(Log &aLog);
1.101 +
1.102 + /**
1.103 + Write binary data to the output stream without escaping
1.104 + it. This data is allowed to contain the NUL (0) character and
1.105 + may be binary data for the store file or UTF-8 text for the
1.106 + human readable config file output.
1.107 + */
1.108 + void WriteBin(const void *aPtr, TUint32 aLength);
1.109 + /**
1.110 + Write a C style string to the output stream without escaping
1.111 + it. It is NOT safe to write a generic UTF-8 string via this
1.112 + this function, because such a string may contain embedded 0
1.113 + characters. A 7-bit ASCII string will work reliably. This
1.114 + function is intended for writing 7-but ASCII strings to the
1.115 + human readable config file, and should not be used for writing
1.116 + data to a store file.
1.117 + */
1.118 + void WriteQuotedUtf8(const void *aStr, TUint32 aLength);
1.119 + /**
1.120 + Write a single byte.
1.121 + */
1.122 + void WriteByte(TUint8 aByte);
1.123 + /**
1.124 + Write a UTF-8 string quoting backslash and double quote characters.
1.125 +
1.126 + A backslash will be written as \\
1.127 + A quote character will be written as \"
1.128 +
1.129 + Note that all bytes in UTF-8 escape sequences have the top bit
1.130 + set therefore the quoting technique used by this function will
1.131 + not effect them.
1.132 + */
1.133 + void WriteCStr(const void *aCstr);
1.134 +
1.135 + void WriteHexNumber(TUint32 aNumber);
1.136 +
1.137 + void WriteSpace();
1.138 + void WriteLineEnd();
1.139 +
1.140 + void WriteIndent();
1.141 + void IncIndent();
1.142 + void DecIndent();
1.143 +
1.144 + bool HumanReadable() const;
1.145 + bool &PemOut();
1.146 + bool &Verbose();
1.147 + void Close();
1.148 +
1.149 + bool Quiet() const;
1.150 +
1.151 + CFileStore *StoreObject();
1.152 + RWriteStream &StoreWriteStream();
1.153 +
1.154 + std::string CertFileName(TUint32 aFormat, TUint32 aCertNumber);
1.155 +
1.156 +private:
1.157 + CFileStore *iStore; // Only used for STORE based streams ie. not human readable
1.158 + std::string iCertBaseName; // Only used for file based streams ie. human readable
1.159 +
1.160 + RWriteStream *iWriteStream; // STORE or file based stream, valid if iLogStream==0
1.161 +
1.162 + std::ostream *iLogStream;
1.163 +private:
1.164 + bool iHumanReadable;
1.165 + bool iPemOut;
1.166 + bool iVerbose;
1.167 + int iIndentLevel;
1.168 + };
1.169 +
1.170 +/**
1.171 + A template which generates a class which can be
1.172 + internalised/externalised via the REncodeWriteStream and
1.173 + RDecodeReadStream templates.
1.174 +
1.175 + The constructor takes a C string constant which specifies the field
1.176 + name.
1.177 +
1.178 + The optional aCommentOnlyInHumanMode parameter changes operation in human
1.179 + mode only - The field will be written as a comment, and will not be
1.180 + accepted whilst reading.
1.181 +
1.182 + Typical use is something like this:-
1.183 + EncDecObject<TUint32> fieldCost("cost");
1.184 +
1.185 + Typically this template will not require specialisations to handle
1.186 + additional types.
1.187 +*/
1.188 +template <class T> class EncDecObject
1.189 + {
1.190 +public:
1.191 + EncDecObject(const char *aName, bool aCommentOnlyInHumanMode = false)
1.192 + : iName(aName), iCommentOnlyInHumanMode(aCommentOnlyInHumanMode), iValue()
1.193 + {
1.194 + }
1.195 +
1.196 + const std::string &Name() const { return iName; }
1.197 +
1.198 + const T &Value() const { return iValue; }
1.199 + T &Value() { return iValue; }
1.200 +
1.201 + bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; }
1.202 +private:
1.203 + std::string iName;
1.204 + bool iCommentOnlyInHumanMode;
1.205 + T iValue;
1.206 + };
1.207 +
1.208 +/**
1.209 + Class for handling Enum values
1.210 + */
1.211 +struct EnumEntry
1.212 + {
1.213 + const char *iName;
1.214 + TUint32 iValue;
1.215 + };
1.216 +
1.217 +// This class should be template by a type which standard store can
1.218 +// internalise/externalise ie TUint8/TUin16/TUint32 (probably not an enum)
1.219 +template<typename T>class EncDecEnum
1.220 + {
1.221 +public:
1.222 + /**
1.223 + Construct an object for handling an enum type.
1.224 + aEnumEntries must be a pointer to a static array of EnumEntry
1.225 + structs terminated by one with iName==0.
1.226 + */
1.227 + EncDecEnum(const char *aName, const EnumEntry *aEnumEntries, bool aCommentOnlyInHumanMode = false);
1.228 +
1.229 + const std::string &Name() const { return iName; }
1.230 +
1.231 + const T &Value() const { return iValue; }
1.232 + T &Value() { return iValue; }
1.233 +
1.234 + const char *ValueName() const { return ValueToName(iValue); }
1.235 +
1.236 + bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; }
1.237 +
1.238 + void SetValue(const T &aValue);
1.239 + void SetValue(const char *aName);
1.240 +private:
1.241 + const char *ValueToName(const T &aValue) const;
1.242 + std::string iName;
1.243 + TUint8 iWidth;
1.244 + const EnumEntry *iEnumEntries; // Array terminated by entry with iName==0
1.245 + bool iCommentOnlyInHumanMode;
1.246 + T iValue;
1.247 + };
1.248 +
1.249 +/*
1.250 + The EncDecContainer class manages a set of objects which inherit
1.251 + from the EncDecContainerItem base class. It can be
1.252 + internalised/externalised via the REncodeWriteStream and
1.253 + RDecodeReadStream templates.
1.254 +
1.255 + The constructor takes a C string constant which specifies the
1.256 + container name.
1.257 +
1.258 + The binary form is a 32 bit count followed by a sequence of
1.259 + EncDecContainerItem objects.
1.260 +
1.261 + In human readable form is a sequence of zero or more human readable
1.262 + representations of T bracketed by StartX and EndX. Where X is the
1.263 + container name.
1.264 +*/
1.265 +class EncDecContainerItem
1.266 + {
1.267 +public:
1.268 + virtual ~EncDecContainerItem();
1.269 +
1.270 + // Get the type name for the container. If 0 then do not bracket item with StartType/EndType
1.271 + virtual const char *ItemType() const = 0;
1.272 + // If ItemType()!=0 then ItemName will be included after StartType
1.273 + virtual std::string ItemName() const;
1.274 + virtual void SetItemName(const std::string &aName);
1.275 + virtual void Encode(REncodeWriteStream &aWriteStream) = 0;
1.276 + virtual void Decode(RDecodeReadStream &aReadStream) = 0;
1.277 + };
1.278 +
1.279 +typedef EncDecContainerItem *EncDecContainerItemFactoryFunc();
1.280 +
1.281 +class EncDecContainer
1.282 + {
1.283 +public:
1.284 + EncDecContainer(const char *aContainerName, EncDecContainerItemFactoryFunc *aFactory);
1.285 + ~EncDecContainer();
1.286 +
1.287 + void push_back(EncDecContainerItem *aItem);
1.288 + const EncDecContainerItem &operator[](TUint32 aIndex) const;
1.289 + EncDecContainerItem &operator[](TUint32 aIndex);
1.290 + TUint32 size() const;
1.291 + void reset();
1.292 +
1.293 + void Encode(REncodeWriteStream &aWriteStream) const;
1.294 + void Decode(RDecodeReadStream &aReadStream);
1.295 +
1.296 +private:
1.297 + std::string iName;
1.298 + EncDecContainerItemFactoryFunc *iFactory;
1.299 + std::vector<EncDecContainerItem *> iArray;
1.300 + };
1.301 +
1.302 +void readContainer(const std::string &aFileName, bool aHuman, EncDecContainer &container);
1.303 +void writeContainer(const char *aFileName, bool aHuman, bool aPemOut, bool aVerbose, const EncDecContainer &container);
1.304 +
1.305 +/*
1.306 + The EncodeHuman template functions are used to convert a type to
1.307 + human readable form.
1.308 +
1.309 + Do NOT try and write specialisations of these templates, it probably
1.310 + will not work, instead just write a conventional function which is
1.311 + selected via the norml overloading rules. See GOTW articles on the
1.312 + web.
1.313 + */
1.314 +
1.315 +// The basic EncodeHuman template assumes that T is an unsigned
1.316 +// integer and encodes it in hex.
1.317 +template <class T> void EncodeHuman(REncodeWriteStream& aStream,const T &aUnsignedIntType)
1.318 +{
1.319 + aStream.WriteHexNumber(aUnsignedIntType);
1.320 +}
1.321 +
1.322 +void EncodeHuman(REncodeWriteStream& aStream,const TUid &aUid);
1.323 +void EncodeHuman(REncodeWriteStream& aStream,const TName &aName);
1.324 +
1.325 +/*
1.326 + The DecodeHuman template functions are used to read in the human
1.327 + readable form.
1.328 +
1.329 + Do NOT try and write specialisations of these templates, it probably
1.330 + will not work, instead just write a conventional function which is
1.331 + selected via the norml overloading rules. See GOTW articles on the
1.332 + web.
1.333 + */
1.334 +
1.335 +// The basic DecodeHuman template assumes that T is an unsigned integer
1.336 +// and decodes it from either decimal or hex (starting with 0x). The
1.337 +// code calls RDecodeReadStream::ReadUnsignedNumber which will decode
1.338 +// the number (max 32bits) and check it fits into specified type.
1.339 +template <class T> void DecodeHuman(RDecodeReadStream& aStream,T &aUnsignedIntType)
1.340 +{
1.341 + aUnsignedIntType = (T) aStream.ReadUnsignedNumber(sizeof(aUnsignedIntType));
1.342 +}
1.343 +
1.344 +void DecodeHuman(RDecodeReadStream& aStream,TUid &aUid);
1.345 +void DecodeHuman(RDecodeReadStream& aStream,TName &aName);
1.346 +
1.347 +/*
1.348 + The following two template operators require the object which is
1.349 + being internalised or externalised to provide a const Name function
1.350 + (which returns the field name) and two Value functions (one const
1.351 + and one not) which return a reference to an instance of the type
1.352 + being handled. A function called CommentOnlyInHumanMode should
1.353 + return true if the human output should be prefixed with # and should
1.354 + be reject when reading.
1.355 +
1.356 + Typicaly types will be wrapped by the EncDecObject template to
1.357 + provide the Name() and Value() functions required by these
1.358 + templates.
1.359 +
1.360 + Do NOT try and write specialisations of these templates, it probably
1.361 + will not work, instead just write a conventional function which is
1.362 + selected via the norml overloading rules. See GOTW articles on the
1.363 + web.
1.364 +
1.365 + Note: You probably only need to enhance the EncodeHuman/DecodeHuman
1.366 + functions unless you are adding a new variable length container type.
1.367 + */
1.368 +
1.369 +/*
1.370 + The externalise operator << first checks if the destination stream
1.371 + is HumanReadable. If it is, it writes the Name(), followed by a
1.372 + space, calls EncodeHuman, then WriteLineEnd. If the stream is not
1.373 + HumanReadable it simply applies the << operator to the Value().
1.374 +*/
1.375 +template <class T>
1.376 +inline REncodeWriteStream& operator<<(REncodeWriteStream& aStream,const T& anObject);
1.377 +
1.378 +REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecContainer &aContainer);
1.379 +
1.380 +template <typename T>
1.381 +REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecEnum<T> &aEncDecEnum);
1.382 +
1.383 +/*
1.384 + The internalise operator >> first checks if the source stream is
1.385 + HumanReadable. If it is, it reads/checks the field name then calls
1.386 + DecodeHuman. If the stream is not HumanReadable
1.387 + it simply applies the >> operator to the Value().
1.388 +*/
1.389 +template <class T>
1.390 +inline RDecodeReadStream& operator>>(RDecodeReadStream& aStream,T& anObject);
1.391 +
1.392 +RDecodeReadStream& operator>>(RDecodeReadStream& aStream,EncDecContainer &aContainer);
1.393 +
1.394 +template <typename T>
1.395 +RDecodeReadStream& operator>>(RDecodeReadStream& aStream, EncDecEnum<T> &aEncDecEnum);
1.396 +
1.397 +#include "encdec.inl"
1.398 +
1.399 +
1.400 +
1.401 +#endif