11using System ;
2- using System . Diagnostics ;
3- #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
4- using System . Buffers . Binary ;
5- #endif
62using System . IO ;
73
84using Org . BouncyCastle . Utilities ;
@@ -65,8 +61,7 @@ internal static int FindLimit(Stream input)
6561 private readonly int m_depth ;
6662 private readonly int m_limit ;
6763 private readonly bool m_leaveOpen ;
68-
69- internal byte [ ] [ ] m_tmpBuffers ;
64+ private readonly byte [ ] m_tmp ;
7065
7166 /**
7267 * Create an ASN1InputStream based on the input byte array. The length of DER objects in
@@ -106,11 +101,11 @@ public Asn1InputStream(Stream input, int limit)
106101 }
107102
108103 public Asn1InputStream ( Stream input , int limit , bool leaveOpen )
109- : this ( input , FindDepth ( ) , limit , leaveOpen , new byte [ 16 ] [ ] )
104+ : this ( input , FindDepth ( ) , limit , leaveOpen , tmp : new byte [ 16 ] )
110105 {
111106 }
112107
113- internal Asn1InputStream ( Stream input , int depth , int limit , bool leaveOpen , byte [ ] [ ] tmpBuffers )
108+ internal Asn1InputStream ( Stream input , int depth , int limit , bool leaveOpen , byte [ ] tmp )
114109 : base ( input )
115110 {
116111 if ( ! input . CanRead )
@@ -119,18 +114,16 @@ internal Asn1InputStream(Stream input, int depth, int limit, bool leaveOpen, byt
119114 m_depth = depth ;
120115 m_limit = limit ;
121116 m_leaveOpen = leaveOpen ;
122- m_tmpBuffers = tmpBuffers ;
117+ m_tmp = tmp ;
123118 }
124119
125120 private Asn1InputStream CreateSubStream ( Stream sub , int limit ) =>
126- new Asn1InputStream ( sub , DecrementDepth ( m_depth ) , limit , leaveOpen : true , m_tmpBuffers ) ;
121+ new Asn1InputStream ( sub , DecrementDepth ( m_depth ) , limit , leaveOpen : true , m_tmp ) ;
127122
128123 public int Limit => m_limit ;
129124
130125 protected override void Dispose ( bool disposing )
131126 {
132- m_tmpBuffers = null ;
133-
134127 if ( m_leaveOpen )
135128 {
136129 base . Detach ( disposing ) ;
@@ -152,7 +145,7 @@ private Asn1Object BuildObject(int tagHdr, int tagNo, int length)
152145 DefiniteLengthInputStream defIn = new DefiniteLengthInputStream ( s , length , limit : length ) ;
153146
154147 if ( 0 == ( tagHdr & Asn1Tags . Flags ) )
155- return CreatePrimitiveDerObject ( tagNo , defIn , m_tmpBuffers ) ;
148+ return CreatePrimitiveDerObject ( tagNo , defIn , m_tmp ) ;
156149
157150 int tagClass = tagHdr & Asn1Tags . Private ;
158151 if ( 0 != tagClass )
@@ -258,7 +251,7 @@ public Asn1Object ReadObject()
258251 throw new IOException ( "indefinite-length primitive encoding encountered" ) ;
259252
260253 IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream ( s , m_limit ) ;
261- Asn1StreamParser sp = Asn1StreamParser . CreateSubParser ( indIn , m_depth , m_limit , m_tmpBuffers ) ;
254+ Asn1StreamParser sp = Asn1StreamParser . CreateSubParser ( indIn , m_depth , m_limit , m_tmp ) ;
262255
263256 int tagClass = tagHdr & Asn1Tags . Private ;
264257 if ( 0 != tagClass )
@@ -401,64 +394,22 @@ internal static int ReadLength(Stream s)
401394 return length ;
402395 }
403396
404- private static bool GetBuffer ( DefiniteLengthInputStream defIn , byte [ ] [ ] tmpBuffers , out byte [ ] contents )
405- {
406- int len = defIn . Remaining ;
407- if ( len >= tmpBuffers . Length )
408- {
409- contents = defIn . ToArray ( ) ;
410- return false ;
411- }
412-
413- byte [ ] buf = tmpBuffers [ len ] ;
414- if ( buf == null )
415- {
416- buf = tmpBuffers [ len ] = new byte [ len ] ;
417- }
418-
419- defIn . ReadAllIntoByteArray ( buf ) ;
420-
421- contents = buf ;
422- return true ;
423- }
424-
425- internal static Asn1Object CreatePrimitiveDerObject ( int tagNo , DefiniteLengthInputStream defIn ,
426- byte [ ] [ ] tmpBuffers )
397+ internal static Asn1Object CreatePrimitiveDerObject ( int tagNo , DefiniteLengthInputStream defIn , byte [ ] tmp )
427398 {
428399 switch ( tagNo )
429400 {
430401 case Asn1Tags . BmpString :
431- {
432- return CreateDerBmpString ( defIn ) ;
433- }
402+ return DerBmpString . CreatePrimitive ( defIn ) ;
434403 case Asn1Tags . Boolean :
435- {
436- GetBuffer ( defIn , tmpBuffers , out var contents ) ;
437- return DerBoolean . CreatePrimitive ( contents ) ;
438- }
404+ return DerBoolean . CreatePrimitive ( defIn ) ;
439405 case Asn1Tags . Enumerated :
440- {
441- bool usedBuffer = GetBuffer ( defIn , tmpBuffers , out var contents ) ;
442- return DerEnumerated . CreatePrimitive ( contents , clone : usedBuffer ) ;
443- }
406+ return DerEnumerated . CreatePrimitive ( defIn ) ;
444407 case Asn1Tags . Null :
445- {
446- Asn1Null . CheckContentsLength ( defIn . Remaining ) ;
447- Debug . Assert ( defIn . Remaining == 0 ) ;
448- return Asn1Null . CreatePrimitive ( ) ;
449- }
408+ return Asn1Null . CreatePrimitive ( defIn ) ;
450409 case Asn1Tags . ObjectIdentifier :
451- {
452- DerObjectIdentifier . CheckContentsLength ( defIn . Remaining ) ;
453- bool usedBuffer = GetBuffer ( defIn , tmpBuffers , out var contents ) ;
454- return DerObjectIdentifier . CreatePrimitive ( contents , clone : usedBuffer ) ;
455- }
410+ return DerObjectIdentifier . CreatePrimitive ( defIn , tmp ) ;
456411 case Asn1Tags . RelativeOid :
457- {
458- Asn1RelativeOid . CheckContentsLength ( defIn . Remaining ) ;
459- bool usedBuffer = GetBuffer ( defIn , tmpBuffers , out var contents ) ;
460- return Asn1RelativeOid . CreatePrimitive ( contents , clone : usedBuffer ) ;
461- }
412+ return Asn1RelativeOid . CreatePrimitive ( defIn , tmp ) ;
462413 }
463414
464415 byte [ ] bytes = defIn . ToArray ( ) ;
@@ -513,88 +464,5 @@ internal static Asn1Object CreatePrimitiveDerObject(int tagNo, DefiniteLengthInp
513464 throw new IOException ( "unknown tag " + tagNo + " encountered" ) ;
514465 }
515466 }
516-
517- private static DerBmpString CreateDerBmpString ( DefiniteLengthInputStream defIn )
518- {
519- int remainingBytes = defIn . Remaining ;
520- if ( 0 != ( remainingBytes & 1 ) )
521- throw new IOException ( "malformed BMPString encoding encountered" ) ;
522-
523- int length = remainingBytes / 2 ;
524-
525- #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
526- return DerBmpString . CreatePrimitive ( length , defIn , ( str , defIn ) =>
527- {
528- int stringPos = 0 ;
529-
530- Span < byte > buf = stackalloc byte [ 8 ] ;
531- while ( remainingBytes >= 8 )
532- {
533- if ( Streams . ReadFully ( defIn , buf ) != 8 )
534- throw new EndOfStreamException ( "EOF encountered in middle of BMPString" ) ;
535-
536- str [ stringPos ] = ( char ) BinaryPrimitives . ReadUInt16BigEndian ( buf [ 0 ..] ) ;
537- str [ stringPos + 1 ] = ( char ) BinaryPrimitives . ReadUInt16BigEndian ( buf [ 2 ..] ) ;
538- str [ stringPos + 2 ] = ( char ) BinaryPrimitives . ReadUInt16BigEndian ( buf [ 4 ..] ) ;
539- str [ stringPos + 3 ] = ( char ) BinaryPrimitives . ReadUInt16BigEndian ( buf [ 6 ..] ) ;
540- stringPos += 4 ;
541- remainingBytes -= 8 ;
542- }
543- if ( remainingBytes > 0 )
544- {
545- if ( Streams . ReadFully ( defIn , buf ) != remainingBytes )
546- throw new EndOfStreamException ( "EOF encountered in middle of BMPString" ) ;
547-
548- int bufPos = 0 ;
549- do
550- {
551- int b1 = buf [ bufPos ++ ] << 8 ;
552- int b2 = buf [ bufPos ++ ] & 0xFF ;
553- str [ stringPos ++ ] = ( char ) ( b1 | b2 ) ;
554- }
555- while ( bufPos < remainingBytes ) ;
556- }
557-
558- if ( 0 != defIn . Remaining || str . Length != stringPos )
559- throw new InvalidOperationException ( ) ;
560- } ) ;
561- #else
562- char [ ] str = new char [ length ] ;
563- int stringPos = 0 ;
564-
565- byte [ ] buf = new byte [ 8 ] ;
566- while ( remainingBytes >= 8 )
567- {
568- if ( Streams . ReadFully ( defIn , buf , 0 , 8 ) != 8 )
569- throw new EndOfStreamException ( "EOF encountered in middle of BMPString" ) ;
570-
571- str [ stringPos ] = ( char ) ( ( buf [ 0 ] << 8 ) | ( buf [ 1 ] & 0xFF ) ) ;
572- str [ stringPos + 1 ] = ( char ) ( ( buf [ 2 ] << 8 ) | ( buf [ 3 ] & 0xFF ) ) ;
573- str [ stringPos + 2 ] = ( char ) ( ( buf [ 4 ] << 8 ) | ( buf [ 5 ] & 0xFF ) ) ;
574- str [ stringPos + 3 ] = ( char ) ( ( buf [ 6 ] << 8 ) | ( buf [ 7 ] & 0xFF ) ) ;
575- stringPos += 4 ;
576- remainingBytes -= 8 ;
577- }
578- if ( remainingBytes > 0 )
579- {
580- if ( Streams . ReadFully ( defIn , buf , 0 , remainingBytes ) != remainingBytes )
581- throw new EndOfStreamException ( "EOF encountered in middle of BMPString" ) ;
582-
583- int bufPos = 0 ;
584- do
585- {
586- int b1 = buf [ bufPos ++ ] << 8 ;
587- int b2 = buf [ bufPos ++ ] & 0xFF ;
588- str [ stringPos ++ ] = ( char ) ( b1 | b2 ) ;
589- }
590- while ( bufPos < remainingBytes ) ;
591- }
592-
593- if ( 0 != defIn . Remaining || str . Length != stringPos )
594- throw new InvalidOperationException ( ) ;
595-
596- return DerBmpString . CreatePrimitive ( str ) ;
597- #endif
598- }
599467 }
600468}
0 commit comments