00001
00002
00003
#include "pch.h"
00004
00005
#ifndef CRYPTOPP_IMPORTS
00006
00007
#include "asn.h"
00008
00009
#include <iomanip>
00010
#include <time.h>
00011
00012 NAMESPACE_BEGIN(CryptoPP)
00013 USING_NAMESPACE(std)
00014
00015
00016
unsigned int DERLengthEncode(
BufferedTransformation &bt,
unsigned int length)
00017 {
00018
unsigned int i=0;
00019
if (length <= 0x7f)
00020 {
00021 bt.Put(byte(length));
00022 i++;
00023 }
00024
else
00025 {
00026 bt.Put(byte(BytePrecision(length) | 0x80));
00027 i++;
00028
for (
int j=BytePrecision(length); j; --j)
00029 {
00030 bt.Put(byte(length >> (j-1)*8));
00031 i++;
00032 }
00033 }
00034
return i;
00035 }
00036
00037
bool BERLengthDecode(
BufferedTransformation &bt,
unsigned int &length,
bool &definiteLength)
00038 {
00039 byte b;
00040
00041
if (!bt.
Get(b))
00042
return false;
00043
00044
if (!(b & 0x80))
00045 {
00046 definiteLength =
true;
00047 length = b;
00048 }
00049
else
00050 {
00051
unsigned int lengthBytes = b & 0x7f;
00052
00053
if (lengthBytes == 0)
00054 {
00055 definiteLength =
false;
00056
return true;
00057 }
00058
00059 definiteLength =
true;
00060 length = 0;
00061
while (lengthBytes--)
00062 {
00063
if (length >> (8*(
sizeof(length)-1)))
00064 BERDecodeError();
00065
00066
if (!bt.
Get(b))
00067
return false;
00068
00069 length = (length << 8) | b;
00070 }
00071 }
00072
return true;
00073 }
00074
00075
bool BERLengthDecode(
BufferedTransformation &bt,
unsigned int &length)
00076 {
00077
bool definiteLength;
00078
if (!BERLengthDecode(bt, length, definiteLength))
00079 BERDecodeError();
00080
return definiteLength;
00081 }
00082
00083
void DEREncodeNull(
BufferedTransformation &out)
00084 {
00085 out.
Put(TAG_NULL);
00086 out.
Put(0);
00087 }
00088
00089
void BERDecodeNull(
BufferedTransformation &in)
00090 {
00091 byte b;
00092
if (!in.
Get(b) || b != TAG_NULL)
00093 BERDecodeError();
00094
unsigned int length;
00095
if (!BERLengthDecode(in, length) || length != 0)
00096 BERDecodeError();
00097 }
00098
00099
00100
unsigned int DEREncodeOctetString(
BufferedTransformation &bt,
const byte *str,
unsigned int strLen)
00101 {
00102 bt.
Put(OCTET_STRING);
00103
unsigned int lengthBytes = DERLengthEncode(bt, strLen);
00104 bt.
Put(str, strLen);
00105
return 1+lengthBytes+strLen;
00106 }
00107
00108
unsigned int DEREncodeOctetString(
BufferedTransformation &bt,
const SecByteBlock &str)
00109 {
00110
return DEREncodeOctetString(bt, str.
begin(), str.
size());
00111 }
00112
00113
unsigned int BERDecodeOctetString(
BufferedTransformation &bt,
SecByteBlock &str)
00114 {
00115 byte b;
00116
if (!bt.
Get(b) || b != OCTET_STRING)
00117 BERDecodeError();
00118
00119
unsigned int bc;
00120
if (!BERLengthDecode(bt, bc))
00121 BERDecodeError();
00122
00123 str.
resize(bc);
00124
if (bc != bt.
Get(str, bc))
00125 BERDecodeError();
00126
return bc;
00127 }
00128
00129
unsigned int BERDecodeOctetString(
BufferedTransformation &bt,
BufferedTransformation &str)
00130 {
00131 byte b;
00132
if (!bt.
Get(b) || b != OCTET_STRING)
00133 BERDecodeError();
00134
00135
unsigned int bc;
00136
if (!BERLengthDecode(bt, bc))
00137 BERDecodeError();
00138
00139 bt.
TransferTo(str, bc);
00140
return bc;
00141 }
00142
00143
unsigned int DEREncodeTextString(
BufferedTransformation &bt,
const std::string &str, byte asnTag)
00144 {
00145 bt.
Put(asnTag);
00146
unsigned int lengthBytes = DERLengthEncode(bt, str.size());
00147 bt.
Put((
const byte *)str.data(), str.size());
00148
return 1+lengthBytes+str.size();
00149 }
00150
00151
unsigned int BERDecodeTextString(
BufferedTransformation &bt, std::string &str, byte asnTag)
00152 {
00153 byte b;
00154
if (!bt.
Get(b) || b != asnTag)
00155 BERDecodeError();
00156
00157
unsigned int bc;
00158
if (!BERLengthDecode(bt, bc))
00159 BERDecodeError();
00160
00161
SecByteBlock temp(bc);
00162
if (bc != bt.
Get(temp, bc))
00163 BERDecodeError();
00164 str.assign((
char *)temp.begin(), bc);
00165
return bc;
00166 }
00167
00168
00169
unsigned int DEREncodeBitString(
BufferedTransformation &bt,
const byte *str,
unsigned int strLen,
unsigned int unusedBits)
00170 {
00171 bt.
Put(BIT_STRING);
00172
unsigned int lengthBytes = DERLengthEncode(bt, strLen+1);
00173 bt.
Put((byte)unusedBits);
00174 bt.
Put(str, strLen);
00175
return 2+lengthBytes+strLen;
00176 }
00177
00178
unsigned int BERDecodeBitString(
BufferedTransformation &bt,
SecByteBlock &str,
unsigned int &unusedBits)
00179 {
00180 byte b;
00181
if (!bt.
Get(b) || b != BIT_STRING)
00182 BERDecodeError();
00183
00184
unsigned int bc;
00185
if (!BERLengthDecode(bt, bc))
00186 BERDecodeError();
00187
00188 byte unused;
00189
if (!bt.
Get(unused))
00190 BERDecodeError();
00191 unusedBits = unused;
00192 str.
resize(bc-1);
00193
if ((bc-1) != bt.
Get(str, bc-1))
00194 BERDecodeError();
00195
return bc-1;
00196 }
00197
00198
void DERReencode(
BufferedTransformation &source,
BufferedTransformation &dest)
00199 {
00200 byte tag;
00201 source.
Peek(tag);
00202
BERGeneralDecoder decoder(source, tag);
00203
DERGeneralEncoder encoder(dest, tag);
00204
if (decoder.IsDefiniteLength())
00205 decoder.TransferTo(encoder, decoder.RemainingLength());
00206
else
00207 {
00208
while (!decoder.EndReached())
00209 DERReencode(decoder, encoder);
00210 }
00211 decoder.MessageEnd();
00212 encoder.MessageEnd();
00213 }
00214
00215
void OID::EncodeValue(
BufferedTransformation &bt,
unsigned long v)
00216 {
00217
for (
unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7)
00218 bt.
Put((byte)(0x80 | ((v >> i) & 0x7f)));
00219 bt.
Put((byte)(v & 0x7f));
00220 }
00221
00222
unsigned int OID::DecodeValue(
BufferedTransformation &bt,
unsigned long &v)
00223 {
00224 byte b;
00225
unsigned int i=0;
00226 v = 0;
00227
while (
true)
00228 {
00229
if (!bt.
Get(b))
00230 BERDecodeError();
00231 i++;
00232 v <<= 7;
00233 v += b & 0x7f;
00234
if (!(b & 0x80))
00235
return i;
00236 }
00237 }
00238
00239
void OID::DEREncode(
BufferedTransformation &bt)
const
00240
{
00241 assert(m_values.size() >= 2);
00242
ByteQueue temp;
00243 temp.
Put(byte(m_values[0] * 40 + m_values[1]));
00244
for (
unsigned int i=2; i<m_values.size(); i++)
00245 EncodeValue(temp, m_values[i]);
00246 bt.
Put(OBJECT_IDENTIFIER);
00247 DERLengthEncode(bt, temp.
CurrentSize());
00248 temp.
TransferTo(bt);
00249 }
00250
00251
void OID::BERDecode(
BufferedTransformation &bt)
00252 {
00253 byte b;
00254
if (!bt.
Get(b) || b != OBJECT_IDENTIFIER)
00255 BERDecodeError();
00256
00257
unsigned int length;
00258
if (!BERLengthDecode(bt, length) || length < 1)
00259 BERDecodeError();
00260
00261
if (!bt.
Get(b))
00262 BERDecodeError();
00263
00264 length--;
00265 m_values.resize(2);
00266 m_values[0] = b / 40;
00267 m_values[1] = b % 40;
00268
00269
while (length > 0)
00270 {
00271
unsigned long v;
00272
unsigned int valueLen = DecodeValue(bt, v);
00273
if (valueLen > length)
00274 BERDecodeError();
00275 m_values.push_back(v);
00276 length -= valueLen;
00277 }
00278 }
00279
00280
void OID::BERDecodeAndCheck(
BufferedTransformation &bt)
const
00281
{
00282
OID oid(bt);
00283
if (*
this != oid)
00284 BERDecodeError();
00285 }
00286
00287
inline BufferedTransformation & EncodedObjectFilter::CurrentTarget()
00288 {
00289
if (m_flags & PUT_OBJECTS)
00290
return *AttachedTransformation();
00291
else
00292
return TheBitBucket();
00293 }
00294
00295
void EncodedObjectFilter::Put(
const byte *inString,
unsigned int length)
00296 {
00297
if (m_nCurrentObject == m_nObjects)
00298 {
00299 AttachedTransformation()->Put(inString, length);
00300
return;
00301 }
00302
00303
LazyPutter lazyPutter(m_queue, inString, length);
00304
00305
while (m_queue.AnyRetrievable())
00306 {
00307
switch (m_state)
00308 {
00309
case IDENTIFIER:
00310
if (!m_queue.Get(m_id))
00311
return;
00312 m_queue.TransferTo(CurrentTarget(), 1);
00313 m_state = LENGTH;
00314
case LENGTH:
00315 {
00316 byte b;
00317
if (m_level > 0 && m_id == 0 && m_queue.Peek(b) && b == 0)
00318 {
00319 m_queue.TransferTo(CurrentTarget(), 1);
00320 m_level--;
00321 m_state = IDENTIFIER;
00322
break;
00323 }
00324 ByteQueue::Walker walker(m_queue);
00325
bool definiteLength;
00326
if (!BERLengthDecode(walker, m_lengthRemaining, definiteLength))
00327
return;
00328 m_queue.TransferTo(CurrentTarget(), walker.GetCurrentPosition());
00329
if (!((m_id & CONSTRUCTED) || definiteLength))
00330 BERDecodeError();
00331
if (!definiteLength)
00332 {
00333
if (!(m_id & CONSTRUCTED))
00334 BERDecodeError();
00335 m_level++;
00336 m_state = IDENTIFIER;
00337
break;
00338 }
00339 m_state = BODY;
00340 }
00341
case BODY:
00342 m_lengthRemaining -= m_queue.TransferTo(CurrentTarget(), m_lengthRemaining);
00343
00344
if (m_lengthRemaining == 0)
00345 m_state = IDENTIFIER;
00346 }
00347
00348
if (m_state == IDENTIFIER && m_level == 0)
00349 {
00350
00351 ++m_nCurrentObject;
00352
00353
if (m_flags & PUT_MESSANGE_END_AFTER_EACH_OBJECT)
00354 AttachedTransformation()->MessageEnd();
00355
00356
if (m_nCurrentObject == m_nObjects)
00357 {
00358
if (m_flags & PUT_MESSANGE_END_AFTER_ALL_OBJECTS)
00359 AttachedTransformation()->MessageEnd();
00360
00361
if (m_flags & PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS)
00362 AttachedTransformation()->MessageSeriesEnd();
00363
00364 m_queue.TransferAllTo(*AttachedTransformation());
00365
return;
00366 }
00367 }
00368 }
00369 }
00370
00371 BERGeneralDecoder::BERGeneralDecoder(
BufferedTransformation &inQueue, byte asnTag)
00372 : m_inQueue(inQueue), m_finished(false)
00373 {
00374 Init(asnTag);
00375 }
00376
00377 BERGeneralDecoder::BERGeneralDecoder(
BERGeneralDecoder &inQueue, byte asnTag)
00378 : m_inQueue(inQueue), m_finished(false)
00379 {
00380 Init(asnTag);
00381 }
00382
00383
void BERGeneralDecoder::Init(byte asnTag)
00384 {
00385 byte b;
00386
if (!m_inQueue.
Get(b) || b != asnTag)
00387 BERDecodeError();
00388
00389 m_definiteLength = BERLengthDecode(m_inQueue, m_length);
00390
if (!m_definiteLength && !(asnTag & CONSTRUCTED))
00391 BERDecodeError();
00392 }
00393
00394 BERGeneralDecoder::~BERGeneralDecoder()
00395 {
00396
try
00397 {
00398
if (!m_finished)
00399 MessageEnd();
00400 }
00401
catch (...)
00402 {
00403 }
00404 }
00405
00406
bool BERGeneralDecoder::EndReached()
const
00407
{
00408
if (m_definiteLength)
00409
return m_length == 0;
00410
else
00411 {
00412 word16 i;
00413
return (m_inQueue.
PeekWord16(i)==2 && i==0);
00414 }
00415 }
00416
00417 byte BERGeneralDecoder::PeekByte()
const
00418
{
00419 byte b;
00420
if (!
Peek(b))
00421 BERDecodeError();
00422
return b;
00423 }
00424
00425
void BERGeneralDecoder::CheckByte(byte check)
00426 {
00427 byte b;
00428
if (!
Get(b) || b != check)
00429 BERDecodeError();
00430 }
00431
00432
void BERGeneralDecoder::MessageEnd()
00433 {
00434 m_finished =
true;
00435
if (m_definiteLength)
00436 {
00437
if (m_length != 0)
00438 BERDecodeError();
00439 }
00440
else
00441 {
00442 word16 i;
00443
if (m_inQueue.
GetWord16(i) != 2 || i != 0)
00444 BERDecodeError();
00445 }
00446 }
00447
00448
unsigned int BERGeneralDecoder::TransferTo2(
BufferedTransformation &target,
unsigned long &transferBytes,
const std::string &channel,
bool blocking)
00449 {
00450
if (m_definiteLength && transferBytes > m_length)
00451 transferBytes = m_length;
00452
unsigned int blockedBytes = m_inQueue.
TransferTo2(target, transferBytes, channel, blocking);
00453 ReduceLength(transferBytes);
00454
return blockedBytes;
00455 }
00456
00457
unsigned int BERGeneralDecoder::CopyRangeTo2(
BufferedTransformation &target,
unsigned long &begin,
unsigned long end,
const std::string &channel,
bool blocking)
const
00458
{
00459
if (m_definiteLength)
00460 end = STDMIN((
unsigned long)m_length, end);
00461
return m_inQueue.
CopyRangeTo2(target, begin, end, channel, blocking);
00462 }
00463
00464
unsigned int BERGeneralDecoder::ReduceLength(
unsigned int delta)
00465 {
00466
if (m_definiteLength)
00467 {
00468
if (m_length < delta)
00469 BERDecodeError();
00470 m_length -= delta;
00471 }
00472
return delta;
00473 }
00474
00475 DERGeneralEncoder::DERGeneralEncoder(
BufferedTransformation &outQueue, byte asnTag)
00476 : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
00477 {
00478 }
00479
00480 DERGeneralEncoder::DERGeneralEncoder(
DERGeneralEncoder &outQueue, byte asnTag)
00481 : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
00482 {
00483 }
00484
00485 DERGeneralEncoder::~DERGeneralEncoder()
00486 {
00487
try
00488 {
00489
if (!m_finished)
00490 MessageEnd();
00491 }
00492
catch (...)
00493 {
00494 }
00495 }
00496
00497
void DERGeneralEncoder::MessageEnd()
00498 {
00499 m_finished =
true;
00500
unsigned int length = (
unsigned int)CurrentSize();
00501 m_outQueue.
Put(m_asnTag);
00502 DERLengthEncode(m_outQueue, length);
00503
TransferTo(m_outQueue);
00504 }
00505
00506
00507
00508 void X509PublicKey::BERDecode(
BufferedTransformation &bt)
00509 {
00510
BERSequenceDecoder subjectPublicKeyInfo(bt);
00511
BERSequenceDecoder algorithm(subjectPublicKeyInfo);
00512 GetAlgorithmID().
BERDecodeAndCheck(algorithm);
00513
bool parametersPresent = algorithm.
EndReached() ?
false : BERDecodeAlgorithmParameters(algorithm);
00514 algorithm.
MessageEnd();
00515
00516
BERGeneralDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
00517 subjectPublicKey.
CheckByte(0);
00518 BERDecodeKey2(subjectPublicKey, parametersPresent, subjectPublicKey.
RemainingLength());
00519 subjectPublicKey.
MessageEnd();
00520 subjectPublicKeyInfo.
MessageEnd();
00521 }
00522
00523 void X509PublicKey::DEREncode(
BufferedTransformation &bt)
const
00524
{
00525
DERSequenceEncoder subjectPublicKeyInfo(bt);
00526
00527
DERSequenceEncoder algorithm(subjectPublicKeyInfo);
00528 GetAlgorithmID().
DEREncode(algorithm);
00529 DEREncodeAlgorithmParameters(algorithm);
00530 algorithm.
MessageEnd();
00531
00532
DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
00533 subjectPublicKey.
Put(0);
00534
DEREncodeKey(subjectPublicKey);
00535 subjectPublicKey.
MessageEnd();
00536
00537 subjectPublicKeyInfo.
MessageEnd();
00538 }
00539
00540 void PKCS8PrivateKey::BERDecode(
BufferedTransformation &bt)
00541 {
00542
BERSequenceDecoder privateKeyInfo(bt);
00543 word32 version;
00544 BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 0);
00545
00546
BERSequenceDecoder algorithm(privateKeyInfo);
00547 GetAlgorithmID().
BERDecodeAndCheck(algorithm);
00548
bool parametersPresent = BERDecodeAlgorithmParameters(algorithm);
00549 algorithm.
MessageEnd();
00550
00551
BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING);
00552 BERDecodeKey2(octetString, parametersPresent, privateKeyInfo.
RemainingLength());
00553 octetString.
MessageEnd();
00554
00555
if (!privateKeyInfo.EndReached())
00556
BERDecodeOptionalAttributes(privateKeyInfo);
00557 privateKeyInfo.MessageEnd();
00558 }
00559
00560 void PKCS8PrivateKey::DEREncode(
BufferedTransformation &bt)
const
00561
{
00562
DERSequenceEncoder privateKeyInfo(bt);
00563 DEREncodeUnsigned<word32>(privateKeyInfo, 0);
00564
00565
DERSequenceEncoder algorithm(privateKeyInfo);
00566 GetAlgorithmID().
DEREncode(algorithm);
00567 DEREncodeAlgorithmParameters(algorithm);
00568 algorithm.
MessageEnd();
00569
00570
DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING);
00571
DEREncodeKey(octetString);
00572 octetString.
MessageEnd();
00573
00574
DEREncodeOptionalAttributes(privateKeyInfo);
00575 privateKeyInfo.MessageEnd();
00576 }
00577
00578 void PKCS8PrivateKey::BERDecodeOptionalAttributes(
BufferedTransformation &bt)
00579 {
00580 DERReencode(bt, m_optionalAttributes);
00581 }
00582
00583 void PKCS8PrivateKey::DEREncodeOptionalAttributes(
BufferedTransformation &bt)
const
00584
{
00585 m_optionalAttributes.
CopyTo(bt);
00586 }
00587
00588 NAMESPACE_END
00589
00590
#endif