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
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
00042
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
00059 CRYPTOPP_DLL
unsigned int DERLengthEncode(
BufferedTransformation &out,
unsigned int length);
00060
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
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
00079 CRYPTOPP_DLL
void DERReencode(
BufferedTransformation &source,
BufferedTransformation &dest);
00080
00081
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
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
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
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 ¶meters) {assert(
false);}
00155
unsigned int ReduceLength(
unsigned int delta);
00156 };
00157
00158
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
00167
void MessageEnd();
00168
00169
private:
00170
BufferedTransformation &m_outQueue;
00171
bool m_finished;
00172
00173 byte m_asnTag;
00174 };
00175
00176
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
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
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
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
00234
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;}
00243
00244 virtual void BERDecodeKey(
BufferedTransformation &bt) {assert(
false);}
00245
virtual void BERDecodeKey2(
BufferedTransformation &bt,
bool parametersPresent,
unsigned int size)
00246 {BERDecodeKey(bt);}
00247
00248
virtual void DEREncodeKey(
BufferedTransformation &bt)
const =0;
00249 };
00250
00251
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
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
00267
00268
virtual void BERDecodeOptionalAttributes(
BufferedTransformation &bt);
00269
00270
virtual void DEREncodeOptionalAttributes(
BufferedTransformation &bt)
const;
00271
00272
private:
00273
ByteQueue m_optionalAttributes;
00274 };
00275
00276
00277
00278
00279
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
00308
00309
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