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 Wed Jul 28 08:07:06 2004 for Crypto++ by doxygen 1.3.7