00001
00002
00003
00004
00005
00006
00007 #ifndef CRYPTOPP_ASN_H
00008 #define CRYPTOPP_ASN_H
00009
00010 #include "cryptlib.h"
00011 #include "filters.h"
00012 #include "smartptr.h"
00013 #include "stdcpp.h"
00014 #include "queue.h"
00015 #include "misc.h"
00016
00017 NAMESPACE_BEGIN(CryptoPP)
00018
00019
00020 enum ASNTag
00021 {
00022 BOOLEAN = 0x01,
00023 INTEGER = 0x02,
00024 BIT_STRING = 0x03,
00025 OCTET_STRING = 0x04,
00026 TAG_NULL = 0x05,
00027 OBJECT_IDENTIFIER = 0x06,
00028 OBJECT_DESCRIPTOR = 0x07,
00029 EXTERNAL = 0x08,
00030 REAL = 0x09,
00031 ENUMERATED = 0x0a,
00032 UTF8_STRING = 0x0c,
00033 SEQUENCE = 0x10,
00034 SET = 0x11,
00035 NUMERIC_STRING = 0x12,
00036 PRINTABLE_STRING = 0x13,
00037 T61_STRING = 0x14,
00038 VIDEOTEXT_STRING = 0x15,
00039 IA5_STRING = 0x16,
00040 UTC_TIME = 0x17,
00041 GENERALIZED_TIME = 0x18,
00042 GRAPHIC_STRING = 0x19,
00043 VISIBLE_STRING = 0x1a,
00044 GENERAL_STRING = 0x1b
00045 };
00046
00047 enum ASNIdFlag
00048 {
00049 UNIVERSAL = 0x00,
00050
00051
00052 CONSTRUCTED = 0x20,
00053 APPLICATION = 0x40,
00054 CONTEXT_SPECIFIC = 0x80,
00055 PRIVATE = 0xc0
00056 };
00057
00058 inline void BERDecodeError() {throw BERDecodeErr();}
00059
00060 class CRYPTOPP_DLL UnknownOID : public BERDecodeErr
00061 {
00062 public:
00063 UnknownOID() : BERDecodeErr("BER decode error: unknown object identifier") {}
00064 UnknownOID(const char *err) : BERDecodeErr(err) {}
00065 };
00066
00067
00068 CRYPTOPP_DLL size_t CRYPTOPP_API DERLengthEncode(BufferedTransformation &out, lword length);
00069
00070 CRYPTOPP_DLL bool CRYPTOPP_API BERLengthDecode(BufferedTransformation &in, size_t &length);
00071
00072 CRYPTOPP_DLL void CRYPTOPP_API DEREncodeNull(BufferedTransformation &out);
00073 CRYPTOPP_DLL void CRYPTOPP_API BERDecodeNull(BufferedTransformation &in);
00074
00075 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &out, const byte *str, size_t strLen);
00076 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &out, const SecByteBlock &str);
00077 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &in, SecByteBlock &str);
00078 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &in, BufferedTransformation &str);
00079
00080
00081 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &out, const std::string &str, byte asnTag);
00082 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeTextString(BufferedTransformation &in, std::string &str, byte asnTag);
00083
00084 CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeBitString(BufferedTransformation &out, const byte *str, size_t strLen, unsigned int unusedBits=0);
00085 CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeBitString(BufferedTransformation &in, SecByteBlock &str, unsigned int &unusedBits);
00086
00087
00088 CRYPTOPP_DLL void CRYPTOPP_API DERReencode(BufferedTransformation &source, BufferedTransformation &dest);
00089
00090
00091 class CRYPTOPP_DLL OID
00092 {
00093 public:
00094 OID() {}
00095 OID(word32 v) : m_values(1, v) {}
00096 OID(BufferedTransformation &bt) {BERDecode(bt);}
00097
00098 inline OID & operator+=(word32 rhs) {m_values.push_back(rhs); return *this;}
00099
00100 void DEREncode(BufferedTransformation &bt) const;
00101 void BERDecode(BufferedTransformation &bt);
00102
00103
00104 void BERDecodeAndCheck(BufferedTransformation &bt) const;
00105
00106 std::vector<word32> m_values;
00107
00108 private:
00109 static void EncodeValue(BufferedTransformation &bt, word32 v);
00110 static size_t DecodeValue(BufferedTransformation &bt, word32 &v);
00111 };
00112
00113 class EncodedObjectFilter : public Filter
00114 {
00115 public:
00116 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};
00117 EncodedObjectFilter(BufferedTransformation *attachment = NULL, unsigned int nObjects = 1, word32 flags = 0);
00118
00119 void Put(const byte *inString, size_t length);
00120
00121 unsigned int GetNumberOfCompletedObjects() const {return m_nCurrentObject;}
00122 unsigned long GetPositionOfObject(unsigned int i) const {return m_positions[i];}
00123
00124 private:
00125 BufferedTransformation & CurrentTarget();
00126
00127 word32 m_flags;
00128 unsigned int m_nObjects, m_nCurrentObject, m_level;
00129 std::vector<unsigned int> m_positions;
00130 ByteQueue m_queue;
00131 enum State {IDENTIFIER, LENGTH, BODY, TAIL, ALL_DONE} m_state;
00132 byte m_id;
00133 lword m_lengthRemaining;
00134 };
00135
00136
00137 class CRYPTOPP_DLL BERGeneralDecoder : public Store
00138 {
00139 public:
00140 explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag);
00141 explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag);
00142 ~BERGeneralDecoder();
00143
00144 bool IsDefiniteLength() const {return m_definiteLength;}
00145 lword RemainingLength() const {assert(m_definiteLength); return m_length;}
00146 bool EndReached() const;
00147 byte PeekByte() const;
00148 void CheckByte(byte b);
00149
00150 size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
00151 size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
00152
00153
00154 void MessageEnd();
00155
00156 protected:
00157 BufferedTransformation &m_inQueue;
00158 bool m_finished, m_definiteLength;
00159 lword m_length;
00160
00161 private:
00162 void Init(byte asnTag);
00163 void StoreInitialize(const NameValuePairs ¶meters)
00164 {CRYPTOPP_UNUSED(parameters); assert(false);}
00165 lword ReduceLength(lword delta);
00166 };
00167
00168
00169
00170
00171
00172
00173
00174 class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue
00175 {
00176 public:
00177 #if defined(CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562)
00178 explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
00179 explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
00180 #else
00181 explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag );
00182 explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag );
00183 #endif
00184 ~DERGeneralEncoder();
00185
00186
00187 void MessageEnd();
00188
00189 private:
00190 BufferedTransformation &m_outQueue;
00191 bool m_finished;
00192
00193 byte m_asnTag;
00194 };
00195
00196
00197 class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder
00198 {
00199 public:
00200 explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
00201 : BERGeneralDecoder(inQueue, asnTag) {}
00202 explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
00203 : BERGeneralDecoder(inQueue, asnTag) {}
00204 };
00205
00206
00207 class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder
00208 {
00209 public:
00210 explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
00211 : DERGeneralEncoder(outQueue, asnTag) {}
00212 explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
00213 : DERGeneralEncoder(outQueue, asnTag) {}
00214 };
00215
00216
00217 class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder
00218 {
00219 public:
00220 explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag = SET | CONSTRUCTED)
00221 : BERGeneralDecoder(inQueue, asnTag) {}
00222 explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag = SET | CONSTRUCTED)
00223 : BERGeneralDecoder(inQueue, asnTag) {}
00224 };
00225
00226
00227 class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder
00228 {
00229 public:
00230 explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag = SET | CONSTRUCTED)
00231 : DERGeneralEncoder(outQueue, asnTag) {}
00232 explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag = SET | CONSTRUCTED)
00233 : DERGeneralEncoder(outQueue, asnTag) {}
00234 };
00235
00236 template <class T>
00237 class ASNOptional : public member_ptr<T>
00238 {
00239 public:
00240 void BERDecode(BERSequenceDecoder &seqDecoder, byte tag, byte mask = ~CONSTRUCTED)
00241 {
00242 byte b;
00243 if (seqDecoder.Peek(b) && (b & mask) == tag)
00244 reset(new T(seqDecoder));
00245 }
00246 void DEREncode(BufferedTransformation &out)
00247 {
00248 if (this->get() != NULL)
00249 this->get()->DEREncode(out);
00250 }
00251 };
00252
00253
00254 template <class BASE>
00255 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1CryptoMaterial : public ASN1Object, public BASE
00256 {
00257 public:
00258 void Save(BufferedTransformation &bt) const
00259 {BEREncode(bt);}
00260 void Load(BufferedTransformation &bt)
00261 {BERDecode(bt);}
00262 };
00263
00264
00265 class CRYPTOPP_DLL X509PublicKey : public ASN1CryptoMaterial<PublicKey>
00266 {
00267 public:
00268 void BERDecode(BufferedTransformation &bt);
00269 void DEREncode(BufferedTransformation &bt) const;
00270
00271 virtual OID GetAlgorithmID() const =0;
00272 virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
00273 {BERDecodeNull(bt); return false;}
00274 virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
00275 {DEREncodeNull(bt); return false;}
00276
00277
00278 virtual void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0;
00279
00280 virtual void DEREncodePublicKey(BufferedTransformation &bt) const =0;
00281 };
00282
00283
00284 class CRYPTOPP_DLL PKCS8PrivateKey : public ASN1CryptoMaterial<PrivateKey>
00285 {
00286 public:
00287 void BERDecode(BufferedTransformation &bt);
00288 void DEREncode(BufferedTransformation &bt) const;
00289
00290 virtual OID GetAlgorithmID() const =0;
00291 virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
00292 {BERDecodeNull(bt); return false;}
00293 virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
00294 {DEREncodeNull(bt); return false;}
00295
00296
00297 virtual void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0;
00298
00299 virtual void DEREncodePrivateKey(BufferedTransformation &bt) const =0;
00300
00301
00302
00303 virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt);
00304
00305 virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const;
00306
00307 protected:
00308 ByteQueue m_optionalAttributes;
00309 };
00310
00311
00312
00313
00314
00315 template <class T>
00316 size_t DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER)
00317 {
00318 byte buf[sizeof(w)+1];
00319 unsigned int bc;
00320 if (asnTag == BOOLEAN)
00321 {
00322 buf[sizeof(w)] = w ? 0xff : 0;
00323 bc = 1;
00324 }
00325 else
00326 {
00327 buf[0] = 0;
00328 for (unsigned int i=0; i<sizeof(w); i++)
00329 buf[i+1] = byte(w >> (sizeof(w)-1-i)*8);
00330 bc = sizeof(w);
00331 while (bc > 1 && buf[sizeof(w)+1-bc] == 0)
00332 --bc;
00333 if (buf[sizeof(w)+1-bc] & 0x80)
00334 ++bc;
00335 }
00336 out.Put(asnTag);
00337 size_t lengthBytes = DERLengthEncode(out, bc);
00338 out.Put(buf+sizeof(w)+1-bc, bc);
00339 return 1+lengthBytes+bc;
00340 }
00341
00342
00343 template <class T>
00344 void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER,
00345 T minValue = 0, T maxValue = ((std::numeric_limits<T>::max)()))
00346 {
00347 byte b;
00348 if (!in.Get(b) || b != asnTag)
00349 BERDecodeError();
00350
00351 size_t bc;
00352 bool definite = BERLengthDecode(in, bc);
00353 if (!definite)
00354 BERDecodeError();
00355
00356 SecByteBlock buf(bc);
00357
00358 if (bc != in.Get(buf, bc))
00359 BERDecodeError();
00360
00361 const byte *ptr = buf;
00362 while (bc > sizeof(w) && *ptr == 0)
00363 {
00364 bc--;
00365 ptr++;
00366 }
00367 if (bc > sizeof(w))
00368 BERDecodeError();
00369
00370 w = 0;
00371 for (unsigned int i=0; i<bc; i++)
00372 w = (w << 8) | ptr[i];
00373
00374 if (w < minValue || w > maxValue)
00375 BERDecodeError();
00376 }
00377
00378 inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
00379 {return lhs.m_values == rhs.m_values;}
00380 inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
00381 {return lhs.m_values != rhs.m_values;}
00382 inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
00383 {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());}
00384 inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs)
00385 {return ::CryptoPP::OID(lhs)+=rhs;}
00386
00387 NAMESPACE_END
00388
00389 #endif