00001
00002
00003 #include "pch.h"
00004 #include "asn.h"
00005
00006 #include <iomanip>
00007 #include <time.h>
00008
00009 NAMESPACE_BEGIN(CryptoPP)
00010 USING_NAMESPACE(std)
00011
00013 unsigned int DERLengthEncode(BufferedTransformation &bt, unsigned int length)
00014 {
00015 unsigned int i=0;
00016 if (length <= 0x7f)
00017 {
00018 bt.Put(byte(length));
00019 i++;
00020 }
00021 else
00022 {
00023 bt.Put(byte(BytePrecision(length) | 0x80));
00024 i++;
00025 for (int j=BytePrecision(length); j; --j)
00026 {
00027 bt.Put(byte(length >> (j-1)*8));
00028 i++;
00029 }
00030 }
00031 return i;
00032 }
00033
00034 bool BERLengthDecode(BufferedTransformation &bt, unsigned int &length)
00035 {
00036 byte b;
00037
00038 if (!bt.Get(b))
00039 BERDecodeError();
00040
00041 if (!(b & 0x80))
00042 length = b;
00043 else
00044 {
00045 unsigned int lengthBytes = b & 0x7f;
00046
00047 if (lengthBytes == 0)
00048 return false;
00049
00050 length = 0;
00051 while (lengthBytes--)
00052 {
00053 if (length >> (8*(sizeof(length)-1)))
00054 BERDecodeError();
00055
00056 if (!bt.Get(b))
00057 BERDecodeError();
00058
00059 length = (length << 8) | b;
00060 }
00061 }
00062 return true;
00063 }
00064
00065 void DEREncodeNull(BufferedTransformation &out)
00066 {
00067 out.Put(TAG_NULL);
00068 out.Put(0);
00069 }
00070
00071 void BERDecodeNull(BufferedTransformation &in)
00072 {
00073 byte b;
00074 if (!in.Get(b) || b != TAG_NULL)
00075 BERDecodeError();
00076 unsigned int length;
00077 if (!BERLengthDecode(in, length) || length != 0)
00078 BERDecodeError();
00079 }
00080
00082 unsigned int DEREncodeOctetString(BufferedTransformation &bt, const byte *str, unsigned int strLen)
00083 {
00084 bt.Put(OCTET_STRING);
00085 unsigned int lengthBytes = DERLengthEncode(bt, strLen);
00086 bt.Put(str, strLen);
00087 return 1+lengthBytes+strLen;
00088 }
00089
00090 unsigned int DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str)
00091 {
00092 return DEREncodeOctetString(bt, str.ptr, str.size);
00093 }
00094
00095 unsigned int BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str)
00096 {
00097 byte b;
00098 if (!bt.Get(b) || b != OCTET_STRING)
00099 BERDecodeError();
00100
00101 unsigned int bc;
00102 if (!BERLengthDecode(bt, bc))
00103 BERDecodeError();
00104
00105 str.Resize(bc);
00106 if (bc != bt.Get(str, bc))
00107 BERDecodeError();
00108 return bc;
00109 }
00110
00111 unsigned int BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str)
00112 {
00113 byte b;
00114 if (!bt.Get(b) || b != OCTET_STRING)
00115 BERDecodeError();
00116
00117 unsigned int bc;
00118 if (!BERLengthDecode(bt, bc))
00119 BERDecodeError();
00120
00121 bt.TransferTo(str, bc);
00122 return bc;
00123 }
00124
00125 unsigned int DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag)
00126 {
00127 bt.Put(asnTag);
00128 unsigned int lengthBytes = DERLengthEncode(bt, str.size());
00129 bt.Put((const byte *)str.data(), str.size());
00130 return 1+lengthBytes+str.size();
00131 }
00132
00133 unsigned int BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag)
00134 {
00135 byte b;
00136 if (!bt.Get(b) || b != asnTag)
00137 BERDecodeError();
00138
00139 unsigned int bc;
00140 if (!BERLengthDecode(bt, bc))
00141 BERDecodeError();
00142
00143 SecByteBlock temp(bc);
00144 if (bc != bt.Get(temp, bc))
00145 BERDecodeError();
00146 str.assign((char *)temp.ptr, bc);
00147 return bc;
00148 }
00149
00151 unsigned int DEREncodeBitString(BufferedTransformation &bt, const byte *str, unsigned int strLen, unsigned int unusedBits)
00152 {
00153 bt.Put(BIT_STRING);
00154 unsigned int lengthBytes = DERLengthEncode(bt, strLen+1);
00155 bt.Put((byte)unusedBits);
00156 bt.Put(str, strLen);
00157 return 1+lengthBytes+strLen;
00158 }
00159
00160 unsigned int BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
00161 {
00162 byte b;
00163 if (!bt.Get(b) || b != BIT_STRING)
00164 BERDecodeError();
00165
00166 unsigned int bc;
00167 if (!BERLengthDecode(bt, bc))
00168 BERDecodeError();
00169
00170 byte unused;
00171 if (!bt.Get(unused))
00172 BERDecodeError();
00173 unusedBits = unused;
00174 str.Resize(bc-1);
00175 if ((bc-1) != bt.Get(str, bc-1))
00176 BERDecodeError();
00177 return bc-1;
00178 }
00179
00180 void OID::EncodeValue(BufferedTransformation &bt, unsigned long v)
00181 {
00182 for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7)-7; i != 0; i-=7)
00183 bt.Put(0x80 | ((v >> i) & 0x7f));
00184 bt.Put(v & 0x7f);
00185 }
00186
00187 unsigned int OID::DecodeValue(BufferedTransformation &bt, unsigned long &v)
00188 {
00189 byte b;
00190 unsigned int i=0;
00191 v = 0;
00192 while (true)
00193 {
00194 if (!bt.Get(b))
00195 BERDecodeError();
00196 i++;
00197 v <<= 7;
00198 v += b & 0x7f;
00199 if (!(b & 0x80))
00200 return i;
00201 }
00202 }
00203
00204 void OID::DEREncode(BufferedTransformation &bt) const
00205 {
00206 assert(m_values.size() >= 2);
00207 ByteQueue temp;
00208 temp.Put(byte(m_values[0] * 40 + m_values[1]));
00209 for (unsigned int i=2; i<m_values.size(); i++)
00210 EncodeValue(temp, m_values[i]);
00211 bt.Put(OBJECT_IDENTIFIER);
00212 DERLengthEncode(bt, temp.CurrentSize());
00213 temp.TransferTo(bt);
00214 }
00215
00216 void OID::BERDecode(BufferedTransformation &bt)
00217 {
00218 byte b;
00219 if (!bt.Get(b) || b != OBJECT_IDENTIFIER)
00220 BERDecodeError();
00221
00222 unsigned int length;
00223 if (!BERLengthDecode(bt, length) || length < 1)
00224 BERDecodeError();
00225
00226 if (!bt.Get(b))
00227 BERDecodeError();
00228
00229 length--;
00230 m_values.resize(2);
00231 m_values[0] = b / 40;
00232 m_values[1] = b % 40;
00233
00234 while (length > 0)
00235 {
00236 unsigned long v;
00237 unsigned int valueLen = DecodeValue(bt, v);
00238 if (valueLen > length)
00239 BERDecodeError();
00240 m_values.push_back(v);
00241 length -= valueLen;
00242 }
00243 }
00244
00245 void OID::BERDecodeAndCheck(BufferedTransformation &bt) const
00246 {
00247 OID oid(bt);
00248 if (*this != oid)
00249 BERDecodeError();
00250 }
00251
00252 BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag)
00253 : m_inQueue(inQueue), m_finished(false)
00254 {
00255 byte b;
00256 if (!m_inQueue.Get(b) || b != asnTag)
00257 BERDecodeError();
00258
00259 m_definiteLength = BERLengthDecode(m_inQueue, m_length);
00260 }
00261
00262 BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag)
00263 : m_inQueue(inQueue), m_finished(false)
00264 {
00265 byte b;
00266 if (!m_inQueue.Get(b) || b != asnTag)
00267 BERDecodeError();
00268
00269 m_definiteLength = BERLengthDecode(m_inQueue, m_length);
00270 if (!m_definiteLength && !(asnTag | CONSTRUCTED))
00271 BERDecodeError();
00272 }
00273
00274 BERGeneralDecoder::~BERGeneralDecoder()
00275 {
00276 try
00277 {
00278 if (!m_finished)
00279 MessageEnd();
00280 }
00281 catch (...)
00282 {
00283 }
00284 }
00285
00286 bool BERGeneralDecoder::EndReached() const
00287 {
00288 if (m_definiteLength)
00289 return m_length == 0;
00290 else
00291 {
00292 word16 i;
00293 return (m_inQueue.PeekWord16(i)==2 && i==0);
00294 }
00295 }
00296
00297 byte BERGeneralDecoder::PeekByte() const
00298 {
00299 byte b;
00300 if (!Peek(b))
00301 BERDecodeError();
00302 return b;
00303 }
00304
00305 void BERGeneralDecoder::CheckByte(byte check)
00306 {
00307 byte b;
00308 if (!Get(b) || b != check)
00309 BERDecodeError();
00310 }
00311
00312 void BERGeneralDecoder::MessageEnd(int)
00313 {
00314 m_finished = true;
00315 if (m_definiteLength)
00316 {
00317 if (m_length != 0)
00318 BERDecodeError();
00319 }
00320 else
00321 {
00322 word16 i;
00323 if (m_inQueue.GetWord16(i) != 2 || i != 0)
00324 BERDecodeError();
00325 }
00326 }
00327
00328 unsigned long BERGeneralDecoder::TransferTo(BufferedTransformation &target, unsigned long transferMax)
00329 {
00330 return ReduceLength(m_inQueue.TransferTo(target, m_definiteLength ? STDMIN(transferMax, (unsigned long)m_length) : transferMax));
00331 }
00332
00333 unsigned long BERGeneralDecoder::CopyTo(BufferedTransformation &target, unsigned long copyMax) const
00334 {
00335 return m_inQueue.CopyTo(target, m_definiteLength ? STDMIN(copyMax, (unsigned long)m_length) : copyMax);
00336 }
00337
00338 unsigned int BERGeneralDecoder::ReduceLength(unsigned int delta)
00339 {
00340 if (m_definiteLength)
00341 {
00342 if (m_length < delta)
00343 BERDecodeError();
00344 m_length -= delta;
00345 }
00346 return delta;
00347 }
00348
00349 DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag)
00350 : m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
00351 {
00352 }
00353
00354 DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)
00355 : m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
00356 {
00357 }
00358
00359 DERGeneralEncoder::~DERGeneralEncoder()
00360 {
00361 try
00362 {
00363 if (!m_finished)
00364 MessageEnd();
00365 }
00366 catch (...)
00367 {
00368 }
00369 }
00370
00371 void DERGeneralEncoder::MessageEnd(int)
00372 {
00373 m_finished = true;
00374 unsigned int length = (unsigned int)CurrentSize();
00375 m_outQueue.Put(m_asnTag);
00376 DERLengthEncode(m_outQueue, length);
00377 TransferTo(m_outQueue);
00378 }
00379
00380 NAMESPACE_END