Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/SharedDependencies/Sources/cryptopp/asn.cpp
2 views
1
// asn.cpp - originally written and placed in the public domain by Wei Dai
2
// CryptoPP::Test namespace added by JW in February 2017
3
4
#include "pch.h"
5
#include "config.h"
6
7
#ifndef CRYPTOPP_IMPORTS
8
9
#include "cryptlib.h"
10
#include "asn.h"
11
#include "misc.h"
12
13
#include <iostream>
14
#include <iomanip>
15
#include <sstream>
16
#include <time.h>
17
18
NAMESPACE_BEGIN(CryptoPP)
19
20
size_t DERLengthEncode(BufferedTransformation &bt, lword length)
21
{
22
size_t i=0;
23
if (length <= 0x7f)
24
{
25
bt.Put(byte(length));
26
i++;
27
}
28
else
29
{
30
bt.Put(byte(BytePrecision(length) | 0x80));
31
i++;
32
for (int j=BytePrecision(length); j; --j)
33
{
34
bt.Put(byte(length >> (j-1)*8));
35
i++;
36
}
37
}
38
return i;
39
}
40
41
bool BERLengthDecode(BufferedTransformation &bt, lword &length, bool &definiteLength)
42
{
43
byte b;
44
45
if (!bt.Get(b))
46
return false;
47
48
if (!(b & 0x80))
49
{
50
definiteLength = true;
51
length = b;
52
}
53
else
54
{
55
unsigned int lengthBytes = b & 0x7f;
56
57
if (lengthBytes == 0)
58
{
59
definiteLength = false;
60
return true;
61
}
62
63
definiteLength = true;
64
length = 0;
65
while (lengthBytes--)
66
{
67
if (length >> (8*(sizeof(length)-1)))
68
BERDecodeError(); // length about to overflow
69
70
if (!bt.Get(b))
71
return false;
72
73
length = (length << 8) | b;
74
}
75
}
76
return true;
77
}
78
79
bool BERLengthDecode(BufferedTransformation &bt, size_t &length)
80
{
81
lword lw = 0;
82
bool definiteLength = false;
83
if (!BERLengthDecode(bt, lw, definiteLength))
84
BERDecodeError();
85
if (!SafeConvert(lw, length))
86
BERDecodeError();
87
return definiteLength;
88
}
89
90
void DEREncodeNull(BufferedTransformation &out)
91
{
92
out.Put(TAG_NULL);
93
out.Put(0);
94
}
95
96
void BERDecodeNull(BufferedTransformation &in)
97
{
98
byte b;
99
if (!in.Get(b) || b != TAG_NULL)
100
BERDecodeError();
101
size_t length;
102
if (!BERLengthDecode(in, length) || length != 0)
103
BERDecodeError();
104
}
105
106
/// ASN Strings
107
size_t DEREncodeOctetString(BufferedTransformation &bt, const byte *str, size_t strLen)
108
{
109
bt.Put(OCTET_STRING);
110
size_t lengthBytes = DERLengthEncode(bt, strLen);
111
bt.Put(str, strLen);
112
return 1+lengthBytes+strLen;
113
}
114
115
size_t DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str)
116
{
117
return DEREncodeOctetString(bt, ConstBytePtr(str), BytePtrSize(str));
118
}
119
120
size_t BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str)
121
{
122
byte b;
123
if (!bt.Get(b) || b != OCTET_STRING)
124
BERDecodeError();
125
126
size_t bc;
127
if (!BERLengthDecode(bt, bc))
128
BERDecodeError();
129
if (bc > bt.MaxRetrievable()) // Issue 346
130
BERDecodeError();
131
132
str.New(bc);
133
if (bc != bt.Get(BytePtr(str), bc))
134
BERDecodeError();
135
return bc;
136
}
137
138
size_t BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str)
139
{
140
byte b;
141
if (!bt.Get(b) || b != OCTET_STRING)
142
BERDecodeError();
143
144
size_t bc;
145
if (!BERLengthDecode(bt, bc))
146
BERDecodeError();
147
if (bc > bt.MaxRetrievable()) // Issue 346
148
BERDecodeError();
149
150
bt.TransferTo(str, bc);
151
return bc;
152
}
153
154
size_t DEREncodeTextString(BufferedTransformation &bt, const byte* str, size_t strLen, byte asnTag)
155
{
156
bt.Put(asnTag);
157
size_t lengthBytes = DERLengthEncode(bt, strLen);
158
bt.Put(str, strLen);
159
return 1+lengthBytes+strLen;
160
}
161
162
size_t DEREncodeTextString(BufferedTransformation &bt, const SecByteBlock &str, byte asnTag)
163
{
164
return DEREncodeTextString(bt, ConstBytePtr(str), BytePtrSize(str), asnTag);
165
}
166
167
size_t DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag)
168
{
169
return DEREncodeTextString(bt, ConstBytePtr(str), BytePtrSize(str), asnTag);
170
}
171
172
size_t BERDecodeTextString(BufferedTransformation &bt, SecByteBlock &str, byte asnTag)
173
{
174
byte b;
175
if (!bt.Get(b) || b != asnTag)
176
BERDecodeError();
177
178
size_t bc;
179
if (!BERLengthDecode(bt, bc))
180
BERDecodeError();
181
if (bc > bt.MaxRetrievable()) // Issue 346
182
BERDecodeError();
183
184
str.resize(bc);
185
if (bc != bt.Get(BytePtr(str), BytePtrSize(str)))
186
BERDecodeError();
187
188
return bc;
189
}
190
191
size_t BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag)
192
{
193
byte b;
194
if (!bt.Get(b) || b != asnTag)
195
BERDecodeError();
196
197
size_t bc;
198
if (!BERLengthDecode(bt, bc))
199
BERDecodeError();
200
if (bc > bt.MaxRetrievable()) // Issue 346
201
BERDecodeError();
202
203
str.resize(bc);
204
if (bc != bt.Get(BytePtr(str), BytePtrSize(str)))
205
BERDecodeError();
206
207
return bc;
208
}
209
210
size_t DEREncodeDate(BufferedTransformation &bt, const SecByteBlock &str, byte asnTag)
211
{
212
bt.Put(asnTag);
213
size_t lengthBytes = DERLengthEncode(bt, str.size());
214
bt.Put(ConstBytePtr(str), BytePtrSize(str));
215
return 1+lengthBytes+str.size();
216
}
217
218
size_t BERDecodeDate(BufferedTransformation &bt, SecByteBlock &str, byte asnTag)
219
{
220
byte b;
221
if (!bt.Get(b) || b != asnTag)
222
BERDecodeError();
223
224
size_t bc;
225
if (!BERLengthDecode(bt, bc))
226
BERDecodeError();
227
if (bc > bt.MaxRetrievable()) // Issue 346
228
BERDecodeError();
229
230
str.resize(bc);
231
if (bc != bt.Get(BytePtr(str), BytePtrSize(str)))
232
BERDecodeError();
233
234
return bc;
235
}
236
237
size_t DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits)
238
{
239
bt.Put(BIT_STRING);
240
size_t lengthBytes = DERLengthEncode(bt, strLen+1);
241
bt.Put((byte)unusedBits);
242
bt.Put(str, strLen);
243
return 2+lengthBytes+strLen;
244
}
245
246
size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
247
{
248
byte b;
249
if (!bt.Get(b) || b != BIT_STRING)
250
BERDecodeError();
251
252
size_t bc;
253
if (!BERLengthDecode(bt, bc))
254
BERDecodeError();
255
if (bc == 0)
256
BERDecodeError();
257
if (bc > bt.MaxRetrievable()) // Issue 346
258
BERDecodeError();
259
260
// X.690, 8.6.2.2: "The number [of unused bits] shall be in the range zero to seven"
261
byte unused;
262
if (!bt.Get(unused) || unused > 7)
263
BERDecodeError();
264
unusedBits = unused;
265
str.resize(bc-1);
266
if ((bc-1) != bt.Get(BytePtr(str), bc-1))
267
BERDecodeError();
268
return bc-1;
269
}
270
271
void DERReencode(BufferedTransformation &source, BufferedTransformation &dest)
272
{
273
byte tag;
274
source.Peek(tag);
275
BERGeneralDecoder decoder(source, tag);
276
DERGeneralEncoder encoder(dest, tag);
277
if (decoder.IsDefiniteLength())
278
decoder.TransferTo(encoder, decoder.RemainingLength());
279
else
280
{
281
while (!decoder.EndReached())
282
DERReencode(decoder, encoder);
283
}
284
decoder.MessageEnd();
285
encoder.MessageEnd();
286
}
287
288
size_t BERDecodePeekLength(const BufferedTransformation &bt)
289
{
290
lword count = (std::min)(bt.MaxRetrievable(), static_cast<lword>(16));
291
if (count == 0) return 0;
292
293
ByteQueue tagAndLength;
294
bt.CopyTo(tagAndLength, count);
295
296
// Skip tag
297
tagAndLength.Skip(1);
298
299
// BERLengthDecode fails for indefinite length.
300
size_t length;
301
if (!BERLengthDecode(tagAndLength, length))
302
return 0;
303
304
return length;
305
}
306
307
void OID::EncodeValue(BufferedTransformation &bt, word32 v)
308
{
309
for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7)
310
bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
311
bt.Put((byte)(v & 0x7f));
312
}
313
314
size_t OID::DecodeValue(BufferedTransformation &bt, word32 &v)
315
{
316
byte b;
317
size_t i=0;
318
v = 0;
319
while (true)
320
{
321
if (!bt.Get(b))
322
BERDecodeError();
323
i++;
324
if (v >> (8*sizeof(v)-7)) // v about to overflow
325
BERDecodeError();
326
v <<= 7;
327
v += b & 0x7f;
328
if (!(b & 0x80))
329
return i;
330
}
331
}
332
333
void OID::DEREncode(BufferedTransformation &bt) const
334
{
335
CRYPTOPP_ASSERT(m_values.size() >= 2);
336
ByteQueue temp;
337
temp.Put(byte(m_values[0] * 40 + m_values[1]));
338
for (size_t i=2; i<m_values.size(); i++)
339
EncodeValue(temp, m_values[i]);
340
bt.Put(OBJECT_IDENTIFIER);
341
DERLengthEncode(bt, temp.CurrentSize());
342
temp.TransferTo(bt);
343
}
344
345
void OID::BERDecode(BufferedTransformation &bt)
346
{
347
byte b;
348
if (!bt.Get(b) || b != OBJECT_IDENTIFIER)
349
BERDecodeError();
350
351
size_t length;
352
if (!BERLengthDecode(bt, length) || length < 1)
353
BERDecodeError();
354
355
if (!bt.Get(b))
356
BERDecodeError();
357
358
length--;
359
m_values.resize(2);
360
m_values[0] = b / 40;
361
m_values[1] = b % 40;
362
363
while (length > 0)
364
{
365
word32 v;
366
size_t valueLen = DecodeValue(bt, v);
367
if (valueLen > length)
368
BERDecodeError();
369
m_values.push_back(v);
370
length -= valueLen;
371
}
372
}
373
374
void OID::BERDecodeAndCheck(BufferedTransformation &bt) const
375
{
376
OID oid(bt);
377
if (*this != oid)
378
BERDecodeError();
379
}
380
381
std::ostream& OID::Print(std::ostream& out) const
382
{
383
std::ostringstream oss;
384
for (size_t i = 0; i < m_values.size(); ++i)
385
{
386
oss << m_values[i];
387
if (i+1 < m_values.size())
388
oss << ".";
389
}
390
return out << oss.str();
391
}
392
393
inline BufferedTransformation & EncodedObjectFilter::CurrentTarget()
394
{
395
if (m_flags & PUT_OBJECTS)
396
return *AttachedTransformation();
397
else
398
return TheBitBucket();
399
}
400
401
void EncodedObjectFilter::Put(const byte *inString, size_t length)
402
{
403
if (m_nCurrentObject == m_nObjects)
404
{
405
AttachedTransformation()->Put(inString, length);
406
return;
407
}
408
409
LazyPutter lazyPutter(m_queue, inString, length);
410
411
while (m_queue.AnyRetrievable())
412
{
413
switch (m_state)
414
{
415
case IDENTIFIER:
416
if (!m_queue.Get(m_id))
417
return;
418
m_queue.TransferTo(CurrentTarget(), 1);
419
m_state = LENGTH;
420
// fall through
421
case LENGTH:
422
{
423
byte b;
424
if (m_level > 0 && m_id == 0 && m_queue.Peek(b) && b == 0)
425
{
426
m_queue.TransferTo(CurrentTarget(), 1);
427
m_level--;
428
m_state = IDENTIFIER;
429
break;
430
}
431
ByteQueue::Walker walker(m_queue);
432
bool definiteLength = false;
433
if (!BERLengthDecode(walker, m_lengthRemaining, definiteLength))
434
return;
435
m_queue.TransferTo(CurrentTarget(), walker.GetCurrentPosition());
436
if (!((m_id & CONSTRUCTED) || definiteLength))
437
BERDecodeError();
438
if (!definiteLength)
439
{
440
if (!(m_id & CONSTRUCTED))
441
BERDecodeError();
442
m_level++;
443
m_state = IDENTIFIER;
444
break;
445
}
446
m_state = BODY;
447
}
448
// fall through
449
case BODY:
450
m_lengthRemaining -= m_queue.TransferTo(CurrentTarget(), m_lengthRemaining);
451
452
if (m_lengthRemaining == 0)
453
m_state = IDENTIFIER;
454
// fall through
455
case TAIL:
456
case ALL_DONE:
457
default: ;
458
}
459
460
if (m_state == IDENTIFIER && m_level == 0)
461
{
462
// just finished processing a level 0 object
463
++m_nCurrentObject;
464
465
if (m_flags & PUT_MESSANGE_END_AFTER_EACH_OBJECT)
466
AttachedTransformation()->MessageEnd();
467
468
if (m_nCurrentObject == m_nObjects)
469
{
470
if (m_flags & PUT_MESSANGE_END_AFTER_ALL_OBJECTS)
471
AttachedTransformation()->MessageEnd();
472
473
if (m_flags & PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS)
474
AttachedTransformation()->MessageSeriesEnd();
475
476
m_queue.TransferAllTo(*AttachedTransformation());
477
return;
478
}
479
}
480
}
481
}
482
483
BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue)
484
: m_inQueue(inQueue), m_length(0), m_finished(false)
485
{
486
Init(DefaultTag);
487
}
488
489
BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag)
490
: m_inQueue(inQueue), m_length(0), m_finished(false)
491
{
492
Init(asnTag);
493
}
494
495
BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag)
496
: m_inQueue(inQueue), m_length(0), m_finished(false)
497
{
498
Init(asnTag);
499
}
500
501
void BERGeneralDecoder::Init(byte asnTag)
502
{
503
byte b;
504
if (!m_inQueue.Get(b) || b != asnTag)
505
BERDecodeError();
506
507
if (!BERLengthDecode(m_inQueue, m_length, m_definiteLength))
508
BERDecodeError();
509
510
if (!m_definiteLength && !(asnTag & CONSTRUCTED))
511
BERDecodeError(); // cannot be primitive and have indefinite length
512
}
513
514
BERGeneralDecoder::~BERGeneralDecoder()
515
{
516
try // avoid throwing in destructor
517
{
518
if (!m_finished)
519
MessageEnd();
520
}
521
catch (const Exception&)
522
{
523
// CRYPTOPP_ASSERT(0);
524
}
525
}
526
527
bool BERGeneralDecoder::EndReached() const
528
{
529
if (m_definiteLength)
530
return m_length == 0;
531
else
532
{ // check end-of-content octets
533
word16 i;
534
return (m_inQueue.PeekWord16(i)==2 && i==0);
535
}
536
}
537
538
byte BERGeneralDecoder::PeekByte() const
539
{
540
byte b;
541
if (!Peek(b))
542
BERDecodeError();
543
return b;
544
}
545
546
void BERGeneralDecoder::CheckByte(byte check)
547
{
548
byte b;
549
if (!Get(b) || b != check)
550
BERDecodeError();
551
}
552
553
void BERGeneralDecoder::MessageEnd()
554
{
555
m_finished = true;
556
if (m_definiteLength)
557
{
558
if (m_length != 0)
559
BERDecodeError();
560
}
561
else
562
{ // remove end-of-content octets
563
word16 i;
564
if (m_inQueue.GetWord16(i) != 2 || i != 0)
565
BERDecodeError();
566
}
567
}
568
569
size_t BERGeneralDecoder::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
570
{
571
if (m_definiteLength && transferBytes > m_length)
572
transferBytes = m_length;
573
size_t blockedBytes = m_inQueue.TransferTo2(target, transferBytes, channel, blocking);
574
ReduceLength(transferBytes);
575
return blockedBytes;
576
}
577
578
size_t BERGeneralDecoder::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
579
{
580
if (m_definiteLength)
581
end = STDMIN(m_length, end);
582
return m_inQueue.CopyRangeTo2(target, begin, end, channel, blocking);
583
}
584
585
lword BERGeneralDecoder::ReduceLength(lword delta)
586
{
587
if (m_definiteLength)
588
{
589
if (m_length < delta)
590
BERDecodeError();
591
m_length -= delta;
592
}
593
return delta;
594
}
595
596
DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue)
597
: m_outQueue(outQueue), m_asnTag(DefaultTag), m_finished(false)
598
{
599
}
600
601
DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag)
602
: m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
603
{
604
}
605
606
DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)
607
: m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
608
{
609
}
610
611
DERGeneralEncoder::~DERGeneralEncoder()
612
{
613
try // avoid throwing in constructor
614
{
615
if (!m_finished)
616
MessageEnd();
617
}
618
catch (const Exception&)
619
{
620
CRYPTOPP_ASSERT(0);
621
}
622
}
623
624
void DERGeneralEncoder::MessageEnd()
625
{
626
m_finished = true;
627
lword length = CurrentSize();
628
m_outQueue.Put(m_asnTag);
629
DERLengthEncode(m_outQueue, length);
630
TransferTo(m_outQueue);
631
}
632
633
// *************************************************************
634
635
void X509PublicKey::BERDecode(BufferedTransformation &bt)
636
{
637
BERSequenceDecoder subjectPublicKeyInfo(bt);
638
BERSequenceDecoder algorithm(subjectPublicKeyInfo);
639
GetAlgorithmID().BERDecodeAndCheck(algorithm);
640
bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm);
641
algorithm.MessageEnd();
642
643
BERGeneralDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
644
subjectPublicKey.CheckByte(0); // unused bits
645
BERDecodePublicKey(subjectPublicKey, parametersPresent, (size_t)subjectPublicKey.RemainingLength());
646
subjectPublicKey.MessageEnd();
647
subjectPublicKeyInfo.MessageEnd();
648
}
649
650
void X509PublicKey::DEREncode(BufferedTransformation &bt) const
651
{
652
DERSequenceEncoder subjectPublicKeyInfo(bt);
653
654
DERSequenceEncoder algorithm(subjectPublicKeyInfo);
655
GetAlgorithmID().DEREncode(algorithm);
656
DEREncodeAlgorithmParameters(algorithm);
657
algorithm.MessageEnd();
658
659
DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
660
subjectPublicKey.Put(0); // unused bits
661
DEREncodePublicKey(subjectPublicKey);
662
subjectPublicKey.MessageEnd();
663
664
subjectPublicKeyInfo.MessageEnd();
665
}
666
667
void PKCS8PrivateKey::BERDecode(BufferedTransformation &bt)
668
{
669
BERSequenceDecoder privateKeyInfo(bt);
670
word32 version;
671
BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 0); // check version
672
673
BERSequenceDecoder algorithm(privateKeyInfo);
674
GetAlgorithmID().BERDecodeAndCheck(algorithm);
675
bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm);
676
algorithm.MessageEnd();
677
678
BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING);
679
BERDecodePrivateKey(octetString, parametersPresent, (size_t)privateKeyInfo.RemainingLength());
680
octetString.MessageEnd();
681
682
if (!privateKeyInfo.EndReached())
683
BERDecodeOptionalAttributes(privateKeyInfo);
684
privateKeyInfo.MessageEnd();
685
}
686
687
void PKCS8PrivateKey::DEREncode(BufferedTransformation &bt) const
688
{
689
DERSequenceEncoder privateKeyInfo(bt);
690
DEREncodeUnsigned<word32>(privateKeyInfo, 0); // version
691
692
DERSequenceEncoder algorithm(privateKeyInfo);
693
GetAlgorithmID().DEREncode(algorithm);
694
DEREncodeAlgorithmParameters(algorithm);
695
algorithm.MessageEnd();
696
697
DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING);
698
DEREncodePrivateKey(octetString);
699
octetString.MessageEnd();
700
701
DEREncodeOptionalAttributes(privateKeyInfo);
702
privateKeyInfo.MessageEnd();
703
}
704
705
void PKCS8PrivateKey::BERDecodeOptionalAttributes(BufferedTransformation &bt)
706
{
707
DERReencode(bt, m_optionalAttributes);
708
}
709
710
void PKCS8PrivateKey::DEREncodeOptionalAttributes(BufferedTransformation &bt) const
711
{
712
m_optionalAttributes.CopyTo(bt);
713
}
714
715
NAMESPACE_END
716
717
#endif
718
719