Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class 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 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 unsigned int DERLengthEncode(BufferedTransformation &out, unsigned int length);
00060 // returns false if indefinite length
00061 bool BERLengthDecode(BufferedTransformation &in, unsigned int &length);
00062 
00063 void DEREncodeNull(BufferedTransformation &out);
00064 void BERDecodeNull(BufferedTransformation &in);
00065 
00066 unsigned int DEREncodeOctetString(BufferedTransformation &out, const byte *str, unsigned int strLen);
00067 unsigned int DEREncodeOctetString(BufferedTransformation &out, const SecByteBlock &str);
00068 unsigned int BERDecodeOctetString(BufferedTransformation &in, SecByteBlock &str);
00069 unsigned int BERDecodeOctetString(BufferedTransformation &in, BufferedTransformation &str);
00070 
00071 // for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING
00072 unsigned int DEREncodeTextString(BufferedTransformation &out, const std::string &str, byte asnTag);
00073 unsigned int BERDecodeTextString(BufferedTransformation &in, std::string &str, byte asnTag);
00074 
00075 unsigned int DEREncodeBitString(BufferedTransformation &out, const byte *str, unsigned int strLen, unsigned int unusedBits=0);
00076 unsigned int BERDecodeBitString(BufferedTransformation &in, SecByteBlock &str, unsigned int &unusedBits);
00077 
00078 //! Object Identifier
00079 class 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 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 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 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 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 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 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 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         //! decode subjectPublicKey part of subjectPublicKeyInfo, or privateKey part of privateKeyInfo, without the BIT STRING or OCTET STRING header
00240         virtual void BERDecodeKey(BufferedTransformation &bt) {assert(false);}
00241         virtual void BERDecodeKey2(BufferedTransformation &bt, bool parametersPresent, unsigned int size)
00242                 {BERDecodeKey(bt);}
00243         //! encode subjectPublicKey part of subjectPublicKeyInfo, or privateKey part of privateKeyInfo, without the BIT STRING or OCTET STRING header
00244         virtual void DEREncodeKey(BufferedTransformation &bt) const =0;
00245 };
00246 
00247 //! encodes/decodes subjectPublicKeyInfo
00248 class X509PublicKey : virtual public ASN1Key, public PublicKey
00249 {
00250 public:
00251         void BERDecode(BufferedTransformation &bt);
00252         void DEREncode(BufferedTransformation &bt) const;
00253 };
00254 
00255 //! encodes/decodes privateKeyInfo
00256 class PKCS8PrivateKey : virtual public ASN1Key, public PrivateKey
00257 {
00258 public:
00259         void BERDecode(BufferedTransformation &bt);
00260         void DEREncode(BufferedTransformation &bt) const;
00261 
00262         virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt)
00263                 {}      // TODO: skip optional attributes if present
00264         virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const
00265                 {}
00266 };
00267 
00268 // ********************************************************
00269 
00270 //! DER Encode Unsigned
00271 /*! for INTEGER, BOOLEAN, and ENUM */
00272 template <class T>
00273 unsigned int DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER)
00274 {
00275         byte buf[sizeof(w)+1];
00276         unsigned int bc;
00277         if (asnTag == BOOLEAN)
00278         {
00279                 buf[sizeof(w)] = w ? 0xff : 0;
00280                 bc = 1;
00281         }
00282         else
00283         {
00284                 buf[0] = 0;
00285                 for (unsigned int i=0; i<sizeof(w); i++)
00286                         buf[i+1] = byte(w >> (sizeof(w)-1-i)*8);
00287                 bc = sizeof(w);
00288                 while (bc > 1 && buf[sizeof(w)+1-bc] == 0)
00289                         --bc;
00290                 if (buf[sizeof(w)+1-bc] & 0x80)
00291                         ++bc;
00292         }
00293         out.Put(asnTag);
00294         unsigned int lengthBytes = DERLengthEncode(out, bc);
00295         out.Put(buf+sizeof(w)+1-bc, bc);
00296         return 1+lengthBytes+bc;
00297 }
00298 
00299 //! BER Decode Unsigned
00300 // VC60 workaround: std::numeric_limits<T>::max conflicts with MFC max macro
00301 // CW41 workaround: std::numeric_limits<T>::max causes a template error
00302 template <class T>
00303 void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
00304                                            T minValue = 0, T maxValue = 0xffffffff)
00305 {
00306         byte b;
00307         if (!in.Get(b) || b != asnTag)
00308                 BERDecodeError();
00309 
00310         unsigned int bc;
00311         BERLengthDecode(in, bc);
00312 
00313         SecByteBlock buf(bc);
00314 
00315         if (bc != in.Get(buf, bc))
00316                 BERDecodeError();
00317 
00318         const byte *ptr = buf;
00319         while (bc > sizeof(w) && *ptr == 0)
00320         {
00321                 bc--;
00322                 ptr++;
00323         }
00324         if (bc > sizeof(w))
00325                 BERDecodeError();
00326 
00327         w = 0;
00328         for (unsigned int i=0; i<bc; i++)
00329                 w = (w << 8) | ptr[i];
00330 
00331         if (w < minValue || w > maxValue)
00332                 BERDecodeError();
00333 }
00334 
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 lhs.m_values != rhs.m_values;}
00339 inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
00340         {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());}
00341 inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs)
00342         {return ::CryptoPP::OID(lhs)+=rhs;}
00343 
00344 NAMESPACE_END
00345 
00346 #endif

Generated on Mon Apr 19 18:12:28 2004 for Crypto++ by doxygen 1.3.6-20040222