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 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 // BER decode from source and DER reencode into dest 00079 CRYPTOPP_DLL void DERReencode(BufferedTransformation &source, BufferedTransformation &dest); 00080 00081 //! Object Identifier 00082 class CRYPTOPP_DLL OID 00083 { 00084 public: 00085 OID() {} 00086 OID(unsigned long v) : m_values(1, v) {} 00087 OID(BufferedTransformation &bt) {BERDecode(bt);} 00088 00089 inline OID & operator+=(unsigned long rhs) {m_values.push_back(rhs); return *this;} 00090 00091 void DEREncode(BufferedTransformation &bt) const; 00092 void BERDecode(BufferedTransformation &bt); 00093 00094 // throw BERDecodeErr() if decoded value doesn't equal this OID 00095 void BERDecodeAndCheck(BufferedTransformation &bt) const; 00096 00097 std::vector<unsigned long> m_values; 00098 00099 private: 00100 static void EncodeValue(BufferedTransformation &bt, unsigned long v); 00101 static unsigned int DecodeValue(BufferedTransformation &bt, unsigned long &v); 00102 }; 00103 00104 class EncodedObjectFilter : public Filter 00105 { 00106 public: 00107 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}; 00108 EncodedObjectFilter(BufferedTransformation *attachment = NULL, unsigned int nObjects = 1, word32 flags = 0); 00109 00110 void Put(const byte *inString, unsigned int length); 00111 00112 unsigned int GetNumberOfCompletedObjects() const {return m_nCurrentObject;} 00113 unsigned long GetPositionOfObject(unsigned int i) const {return m_positions[i];} 00114 00115 private: 00116 BufferedTransformation & CurrentTarget(); 00117 00118 word32 m_flags; 00119 unsigned int m_nObjects, m_nCurrentObject, m_level; 00120 std::vector<unsigned int> m_positions; 00121 ByteQueue m_queue; 00122 enum State {IDENTIFIER, LENGTH, BODY, TAIL, ALL_DONE} m_state; 00123 byte m_id; 00124 unsigned int m_lengthRemaining; 00125 }; 00126 00127 //! BER General Decoder 00128 class CRYPTOPP_DLL BERGeneralDecoder : public Store 00129 { 00130 public: 00131 explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag); 00132 explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag); 00133 ~BERGeneralDecoder(); 00134 00135 bool IsDefiniteLength() const {return m_definiteLength;} 00136 unsigned int RemainingLength() const {assert(m_definiteLength); return m_length;} 00137 bool EndReached() const; 00138 byte PeekByte() const; 00139 void CheckByte(byte b); 00140 00141 unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); 00142 unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const; 00143 00144 // call this to denote end of sequence 00145 void MessageEnd(); 00146 00147 protected: 00148 BufferedTransformation &m_inQueue; 00149 bool m_finished, m_definiteLength; 00150 unsigned int m_length; 00151 00152 private: 00153 void Init(byte asnTag); 00154 void StoreInitialize(const NameValuePairs &parameters) {assert(false);} 00155 unsigned int ReduceLength(unsigned int delta); 00156 }; 00157 00158 //! DER General Encoder 00159 class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue 00160 { 00161 public: 00162 explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED); 00163 explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED); 00164 ~DERGeneralEncoder(); 00165 00166 // call this to denote end of sequence 00167 void MessageEnd(); 00168 00169 private: 00170 BufferedTransformation &m_outQueue; 00171 bool m_finished; 00172 00173 byte m_asnTag; 00174 }; 00175 00176 //! BER Sequence Decoder 00177 class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder 00178 { 00179 public: 00180 explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED) 00181 : BERGeneralDecoder(inQueue, asnTag) {} 00182 explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED) 00183 : BERGeneralDecoder(inQueue, asnTag) {} 00184 }; 00185 00186 //! DER Sequence Encoder 00187 class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder 00188 { 00189 public: 00190 explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED) 00191 : DERGeneralEncoder(outQueue, asnTag) {} 00192 explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED) 00193 : DERGeneralEncoder(outQueue, asnTag) {} 00194 }; 00195 00196 //! BER Set Decoder 00197 class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder 00198 { 00199 public: 00200 explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag = SET | CONSTRUCTED) 00201 : BERGeneralDecoder(inQueue, asnTag) {} 00202 explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag = SET | CONSTRUCTED) 00203 : BERGeneralDecoder(inQueue, asnTag) {} 00204 }; 00205 00206 //! DER Set Encoder 00207 class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder 00208 { 00209 public: 00210 explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag = SET | CONSTRUCTED) 00211 : DERGeneralEncoder(outQueue, asnTag) {} 00212 explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag = SET | CONSTRUCTED) 00213 : DERGeneralEncoder(outQueue, asnTag) {} 00214 }; 00215 00216 template <class T> 00217 class ASNOptional : public member_ptr<T> 00218 { 00219 public: 00220 void BERDecode(BERSequenceDecoder &seqDecoder, byte tag, byte mask = ~CONSTRUCTED) 00221 { 00222 byte b; 00223 if (seqDecoder.Peek(b) && (b & mask) == tag) 00224 reset(new T(seqDecoder)); 00225 } 00226 void DEREncode(BufferedTransformation &out) 00227 { 00228 if (this->get() != NULL) 00229 this->get()->DEREncode(out); 00230 } 00231 }; 00232 00233 //! key that can be ASN.1 encoded 00234 /** derived class should override either BERDecodeKey or BERDecodeKey2 */ 00235 class CRYPTOPP_DLL ASN1Key : public ASN1CryptoMaterial 00236 { 00237 public: 00238 virtual OID GetAlgorithmID() const =0; 00239 virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt) 00240 {BERDecodeNull(bt); return false;} 00241 virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const 00242 {DEREncodeNull(bt); return false;} // see RFC 2459, section 7.3.1 00243 //! decode subjectPublicKey part of subjectPublicKeyInfo, or privateKey part of privateKeyInfo, without the BIT STRING or OCTET STRING header 00244 virtual void BERDecodeKey(BufferedTransformation &bt) {assert(false);} 00245 virtual void BERDecodeKey2(BufferedTransformation &bt, bool parametersPresent, unsigned int size) 00246 {BERDecodeKey(bt);} 00247 //! encode subjectPublicKey part of subjectPublicKeyInfo, or privateKey part of privateKeyInfo, without the BIT STRING or OCTET STRING header 00248 virtual void DEREncodeKey(BufferedTransformation &bt) const =0; 00249 }; 00250 00251 //! encodes/decodes subjectPublicKeyInfo 00252 class CRYPTOPP_DLL X509PublicKey : virtual public ASN1Key, public PublicKey 00253 { 00254 public: 00255 void BERDecode(BufferedTransformation &bt); 00256 void DEREncode(BufferedTransformation &bt) const; 00257 }; 00258 00259 //! encodes/decodes privateKeyInfo 00260 class CRYPTOPP_DLL PKCS8PrivateKey : virtual public ASN1Key, public PrivateKey 00261 { 00262 public: 00263 void BERDecode(BufferedTransformation &bt); 00264 void DEREncode(BufferedTransformation &bt) const; 00265 00266 //! decode optional attributes including context-specific tag 00267 /*! /note default implementation stores attributes to be output in DEREncodeOptionalAttributes */ 00268 virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt); 00269 //! encode optional attributes including context-specific tag 00270 virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const; 00271 00272 private: 00273 ByteQueue m_optionalAttributes; 00274 }; 00275 00276 // ******************************************************** 00277 00278 //! DER Encode Unsigned 00279 /*! for INTEGER, BOOLEAN, and ENUM */ 00280 template <class T> 00281 unsigned int DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER) 00282 { 00283 byte buf[sizeof(w)+1]; 00284 unsigned int bc; 00285 if (asnTag == BOOLEAN) 00286 { 00287 buf[sizeof(w)] = w ? 0xff : 0; 00288 bc = 1; 00289 } 00290 else 00291 { 00292 buf[0] = 0; 00293 for (unsigned int i=0; i<sizeof(w); i++) 00294 buf[i+1] = byte(w >> (sizeof(w)-1-i)*8); 00295 bc = sizeof(w); 00296 while (bc > 1 && buf[sizeof(w)+1-bc] == 0) 00297 --bc; 00298 if (buf[sizeof(w)+1-bc] & 0x80) 00299 ++bc; 00300 } 00301 out.Put(asnTag); 00302 unsigned int lengthBytes = DERLengthEncode(out, bc); 00303 out.Put(buf+sizeof(w)+1-bc, bc); 00304 return 1+lengthBytes+bc; 00305 } 00306 00307 //! BER Decode Unsigned 00308 // VC60 workaround: std::numeric_limits<T>::max conflicts with MFC max macro 00309 // CW41 workaround: std::numeric_limits<T>::max causes a template error 00310 template <class T> 00311 void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER, 00312 T minValue = 0, T maxValue = 0xffffffff) 00313 { 00314 byte b; 00315 if (!in.Get(b) || b != asnTag) 00316 BERDecodeError(); 00317 00318 unsigned int bc; 00319 BERLengthDecode(in, bc); 00320 00321 SecByteBlock buf(bc); 00322 00323 if (bc != in.Get(buf, bc)) 00324 BERDecodeError(); 00325 00326 const byte *ptr = buf; 00327 while (bc > sizeof(w) && *ptr == 0) 00328 { 00329 bc--; 00330 ptr++; 00331 } 00332 if (bc > sizeof(w)) 00333 BERDecodeError(); 00334 00335 w = 0; 00336 for (unsigned int i=0; i<bc; i++) 00337 w = (w << 8) | ptr[i]; 00338 00339 if (w < minValue || w > maxValue) 00340 BERDecodeError(); 00341 } 00342 00343 inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) 00344 {return lhs.m_values == rhs.m_values;} 00345 inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) 00346 {return lhs.m_values != rhs.m_values;} 00347 inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) 00348 {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());} 00349 inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs) 00350 {return ::CryptoPP::OID(lhs)+=rhs;} 00351 00352 NAMESPACE_END 00353 00354 #endif

Generated on Fri Aug 27 16:09:12 2004 for Crypto++ by doxygen 1.3.8