Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

asn.h

00001 #ifndef CRYPTOPP_ASN_H
00002 #define CRYPTOPP_ASN_H
00003 
00004 #include "filters.h"
00005 #include "queue.h"
00006 #include <vector>
00007 
00008 NAMESPACE_BEGIN(CryptoPP)
00009 
00010 // these tags and flags are not complete
00011 enum ASNTag
00012 {
00013         BOOLEAN                         = 0x01,
00014         INTEGER                         = 0x02,
00015         BIT_STRING                      = 0x03,
00016         OCTET_STRING            = 0x04,
00017         TAG_NULL                        = 0x05,
00018         OBJECT_IDENTIFIER       = 0x06,
00019         OBJECT_DESCRIPTOR       = 0x07,
00020         EXTERNAL                        = 0x08,
00021         REAL                            = 0x09,
00022         ENUMERATED                      = 0x0a,
00023         UTF8_STRING                     = 0x0c,
00024         SEQUENCE                        = 0x10,
00025         SET                             = 0x11,
00026         NUMERIC_STRING          = 0x12,
00027         PRINTABLE_STRING        = 0x13,
00028         T61_STRING                      = 0x14,
00029         VIDEOTEXT_STRING        = 0x15,
00030         IA5_STRING                      = 0x16,
00031         UTC_TIME                        = 0x17,
00032         GENERALIZED_TIME        = 0x18,
00033         GRAPHIC_STRING          = 0x19,
00034         VISIBLE_STRING          = 0x1a,
00035         GENERAL_STRING          = 0x1b
00036 };
00037 
00038 enum ASNIdFlag
00039 {
00040         UNIVERSAL                       = 0x00,
00041 //      DATA                            = 0x01,
00042 //      HEADER                          = 0x02,
00043         CONSTRUCTED             = 0x20,
00044         APPLICATION             = 0x40,
00045         CONTEXT_SPECIFIC        = 0x80,
00046         PRIVATE                         = 0xc0
00047 };
00048 
00049 inline void BERDecodeError() {throw BERDecodeErr();}
00050 
00051 class CRYPTOPP_DLL UnknownOID : public BERDecodeErr
00052 {
00053 public:
00054         UnknownOID() : BERDecodeErr("BER decode error: unknown object identifier") {}
00055         UnknownOID(const char *err) : BERDecodeErr(err) {}
00056 };
00057 
00058 // unsigned int DERLengthEncode(unsigned int length, byte *output=0);
00059 CRYPTOPP_DLL unsigned int DERLengthEncode(BufferedTransformation &out, unsigned int length);
00060 // returns false if indefinite length
00061 CRYPTOPP_DLL bool BERLengthDecode(BufferedTransformation &in, unsigned int &length);
00062 
00063 CRYPTOPP_DLL void DEREncodeNull(BufferedTransformation &out);
00064 CRYPTOPP_DLL void BERDecodeNull(BufferedTransformation &in);
00065 
00066 CRYPTOPP_DLL unsigned int DEREncodeOctetString(BufferedTransformation &out, const byte *str, unsigned int strLen);
00067 CRYPTOPP_DLL unsigned int DEREncodeOctetString(BufferedTransformation &out, const SecByteBlock &str);
00068 CRYPTOPP_DLL unsigned int BERDecodeOctetString(BufferedTransformation &in, SecByteBlock &str);
00069 CRYPTOPP_DLL unsigned int BERDecodeOctetString(BufferedTransformation &in, BufferedTransformation &str);
00070 
00071 // for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING
00072 CRYPTOPP_DLL unsigned int DEREncodeTextString(BufferedTransformation &out, const std::string &str, byte asnTag);
00073 CRYPTOPP_DLL unsigned int BERDecodeTextString(BufferedTransformation &in, std::string &str, byte asnTag);
00074 
00075 CRYPTOPP_DLL unsigned int DEREncodeBitString(BufferedTransformation &out, const byte *str, unsigned int strLen, unsigned int unusedBits=0);
00076 CRYPTOPP_DLL unsigned int BERDecodeBitString(BufferedTransformation &in, SecByteBlock &str, unsigned int &unusedBits);
00077 
00078 //! Object Identifier
00079 class CRYPTOPP_DLL OID
00080 {
00081 public:
00082         OID() {}
00083         OID(unsigned long v) : m_values(1, v) {}
00084         OID(BufferedTransformation &bt) {BERDecode(bt);}
00085 
00086         inline OID & operator+=(unsigned long rhs) {m_values.push_back(rhs); return *this;}
00087 
00088         void DEREncode(BufferedTransformation &bt) const;
00089         void BERDecode(BufferedTransformation &bt);
00090 
00091         // throw BERDecodeErr() if decoded value doesn't equal this OID
00092         void BERDecodeAndCheck(BufferedTransformation &bt) const;
00093 
00094         std::vector<unsigned long> m_values;
00095 
00096 private:
00097         static void EncodeValue(BufferedTransformation &bt, unsigned long v);
00098         static unsigned int DecodeValue(BufferedTransformation &bt, unsigned long &v);
00099 };
00100 
00101 class EncodedObjectFilter : public Filter
00102 {
00103 public:
00104         enum Flag {PUT_OBJECTS=1, PUT_MESSANGE_END_AFTER_EACH_OBJECT=2, PUT_MESSANGE_END_AFTER_ALL_OBJECTS=4, PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS=8};
00105         EncodedObjectFilter(BufferedTransformation *attachment = NULL, unsigned int nObjects = 1, word32 flags = 0);
00106 
00107         void Put(const byte *inString, unsigned int length);
00108 
00109         unsigned int GetNumberOfCompletedObjects() const {return m_nCurrentObject;}
00110         unsigned long GetPositionOfObject(unsigned int i) const {return m_positions[i];}
00111 
00112 private:
00113         BufferedTransformation & CurrentTarget();
00114 
00115         word32 m_flags;
00116         unsigned int m_nObjects, m_nCurrentObject, m_level;
00117         std::vector<unsigned int> m_positions;
00118         ByteQueue m_queue;
00119         enum State {IDENTIFIER, LENGTH, BODY, TAIL, ALL_DONE} m_state;
00120         byte m_id;
00121         unsigned int m_lengthRemaining;
00122 };
00123 
00124 //! BER General Decoder
00125 class CRYPTOPP_DLL BERGeneralDecoder : public Store
00126 {
00127 public:
00128         explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag);
00129         explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag);
00130         ~BERGeneralDecoder();
00131 
00132         bool IsDefiniteLength() const {return m_definiteLength;}
00133         unsigned int RemainingLength() const {assert(m_definiteLength); return m_length;}
00134         bool EndReached() const;
00135         byte PeekByte() const;
00136         void CheckByte(byte b);
00137 
00138         unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00139         unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
00140 
00141         // call this to denote end of sequence
00142         void MessageEnd();
00143 
00144 protected:
00145         BufferedTransformation &m_inQueue;
00146         bool m_finished, m_definiteLength;
00147         unsigned int m_length;
00148 
00149 private:
00150         void StoreInitialize(const NameValuePairs &parameters) {assert(false);}
00151         unsigned int ReduceLength(unsigned int delta);
00152 };
00153 
00154 //! DER General Encoder
00155 class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue
00156 {
00157 public:
00158         explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
00159         explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
00160         ~DERGeneralEncoder();
00161 
00162         // call this to denote end of sequence
00163         void MessageEnd();
00164 
00165 private:
00166         BufferedTransformation &m_outQueue;
00167         bool m_finished;
00168 
00169         byte m_asnTag;
00170 };
00171 
00172 //! BER Sequence Decoder
00173 class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder
00174 {
00175 public:
00176         explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
00177                 : BERGeneralDecoder(inQueue, asnTag) {}
00178         explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
00179                 : BERGeneralDecoder(inQueue, asnTag) {}
00180 };
00181 
00182 //! DER Sequence Encoder
00183 class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder
00184 {
00185 public:
00186         explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
00187                 : DERGeneralEncoder(outQueue, asnTag) {}
00188         explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
00189                 : DERGeneralEncoder(outQueue, asnTag) {}
00190 };
00191 
00192 //! BER Set Decoder
00193 class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder
00194 {
00195 public:
00196         explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag = SET | CONSTRUCTED)
00197                 : BERGeneralDecoder(inQueue, asnTag) {}
00198         explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag = SET | CONSTRUCTED)
00199                 : BERGeneralDecoder(inQueue, asnTag) {}
00200 };
00201 
00202 //! DER Set Encoder
00203 class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder
00204 {
00205 public:
00206         explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag = SET | CONSTRUCTED)
00207                 : DERGeneralEncoder(outQueue, asnTag) {}
00208         explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag = SET | CONSTRUCTED)
00209                 : DERGeneralEncoder(outQueue, asnTag) {}
00210 };
00211 
00212 template <class T>
00213 class ASNOptional : public member_ptr<T>
00214 {
00215 public:
00216         void BERDecode(BERSequenceDecoder &seqDecoder, byte tag, byte mask = ~CONSTRUCTED)
00217         {
00218                 byte b;
00219                 if (seqDecoder.Peek(b) && (b & mask) == tag)
00220                         reset(new T(seqDecoder));
00221         }
00222         void DEREncode(BufferedTransformation &out)
00223         {
00224                 if (get() != NULL)
00225                         get()->DEREncode(out);
00226         }
00227 };
00228 
00229 //! .
00230 class CRYPTOPP_DLL ASN1Key : public ASN1CryptoMaterial
00231 {
00232 public:
00233         virtual OID GetAlgorithmID() const =0;
00234         virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
00235                 {BERDecodeNull(bt); return false;}
00236         virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
00237                 {DEREncodeNull(bt); return false;}      // see RFC 2459, section 7.3.1
00238         // one of the following two should be overriden
00239         virtual void BERDecodeKey(BufferedTransformation &bt) {assert(false);}
00240         virtual void BERDecodeKey2(BufferedTransformation &bt, bool parametersPresent, unsigned int size)
00241                 {BERDecodeKey(bt);}
00242         virtual void DEREncodeKey(BufferedTransformation &bt) const =0;
00243 };
00244 
00245 //! .
00246 class CRYPTOPP_DLL X509PublicKey : virtual public ASN1Key, public PublicKey
00247 {
00248 public:
00249         void BERDecode(BufferedTransformation &bt);
00250         void DEREncode(BufferedTransformation &bt) const;
00251 };
00252 
00253 //! .
00254 class CRYPTOPP_DLL PKCS8PrivateKey : virtual public ASN1Key, public PrivateKey
00255 {
00256 public:
00257         void BERDecode(BufferedTransformation &bt);
00258         void DEREncode(BufferedTransformation &bt) const;
00259 
00260         virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt)
00261                 {}      // TODO: skip optional attributes if present
00262         virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const
00263                 {}
00264 };
00265 
00266 // ********************************************************
00267 
00268 //! DER Encode Unsigned
00269 /*! for INTEGER, BOOLEAN, and ENUM */
00270 template <class T>
00271 unsigned int DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER)
00272 {
00273         byte buf[sizeof(w)+1];
00274         unsigned int bc;
00275         if (asnTag == BOOLEAN)
00276         {
00277                 buf[sizeof(w)] = w ? 0xff : 0;
00278                 bc = 1;
00279         }
00280         else
00281         {
00282                 buf[0] = 0;
00283                 for (unsigned int i=0; i<sizeof(w); i++)
00284                         buf[i+1] = byte(w >> (sizeof(w)-1-i)*8);
00285                 bc = sizeof(w);
00286                 while (bc > 1 && buf[sizeof(w)+1-bc] == 0)
00287                         --bc;
00288                 if (buf[sizeof(w)+1-bc] & 0x80)
00289                         ++bc;
00290         }
00291         out.Put(asnTag);
00292         unsigned int lengthBytes = DERLengthEncode(out, bc);
00293         out.Put(buf+sizeof(w)+1-bc, bc);
00294         return 1+lengthBytes+bc;
00295 }
00296 
00297 //! BER Decode Unsigned
00298 // VC60 workaround: std::numeric_limits<T>::max conflicts with MFC max macro
00299 // CW41 workaround: std::numeric_limits<T>::max causes a template error
00300 template <class T>
00301 void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
00302                                            T minValue = 0, T maxValue = 0xffffffff)
00303 {
00304         byte b;
00305         if (!in.Get(b) || b != asnTag)
00306                 BERDecodeError();
00307 
00308         unsigned int bc;
00309         BERLengthDecode(in, bc);
00310 
00311         SecByteBlock buf(bc);
00312 
00313         if (bc != in.Get(buf, bc))
00314                 BERDecodeError();
00315 
00316         const byte *ptr = buf;
00317         while (bc > sizeof(w) && *ptr == 0)
00318         {
00319                 bc--;
00320                 ptr++;
00321         }
00322         if (bc > sizeof(w))
00323                 BERDecodeError();
00324 
00325         w = 0;
00326         for (unsigned int i=0; i<bc; i++)
00327                 w = (w << 8) | ptr[i];
00328 
00329         if (w < minValue || w > maxValue)
00330                 BERDecodeError();
00331 }
00332 
00333 inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
00334         {return lhs.m_values == rhs.m_values;}
00335 inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
00336         {return lhs.m_values != rhs.m_values;}
00337 inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
00338         {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());}
00339 inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs)
00340         {return ::CryptoPP::OID(lhs)+=rhs;}
00341 
00342 NAMESPACE_END
00343 
00344 #endif

Generated on Tue Jul 8 23:34:08 2003 for Crypto++ by doxygen 1.3.2