@@ -493,7 +493,10 @@ private bool CheckHash(bool compatMode)
493
493
Debug . Assert ( _signatureAlgorithm == Oids . NoSignature ) ;
494
494
495
495
// The signature is a hash of the message or signed attributes.
496
- return VerifyHashedMessage ( compatMode , contentToVerify => _signature . Span . SequenceEqual ( contentToVerify ) ) ;
496
+ return VerifyHashedMessage (
497
+ compatMode ,
498
+ _signature ,
499
+ static ( signature , contentToVerify ) => signature . Span . SequenceEqual ( contentToVerify ) ) ;
497
500
}
498
501
499
502
private X509Certificate2 ? FindSignerCertificate ( )
@@ -604,12 +607,13 @@ private CmsHash GetContentHash(ReadOnlyMemory<byte> content, ReadOnlyMemory<byte
604
607
return hasher ;
605
608
}
606
609
607
- private static bool VerifyAttributes (
610
+ private static bool VerifyAttributes < TState > (
608
611
ReadOnlySpan < byte > digest ,
609
612
AttributeAsn [ ] signedAttributes ,
610
613
bool compatMode ,
611
614
bool needsContentAttr ,
612
- VerifyCallback verify )
615
+ TState state ,
616
+ VerifyCallback < TState > verify )
613
617
{
614
618
bool hasMatchingDigestAttr = false ;
615
619
bool hasContentAttr = false ;
@@ -663,23 +667,40 @@ private static bool VerifyAttributes(
663
667
664
668
if ( compatMode )
665
669
{
666
- byte [ ] encoded = writer . Encode ( ) ;
667
- encoded [ 0 ] = 0x31 ;
668
- return verify ( encoded ) ;
670
+ int encodedLength = writer . GetEncodedLength ( ) ;
671
+ byte [ ] ? rented = null ;
672
+ Span < byte > encoded = encodedLength <= 256
673
+ ? stackalloc byte [ 256 ]
674
+ : ( rented = CryptoPool . Rent ( encodedLength ) ) ;
675
+
676
+ try
677
+ {
678
+ encoded = encoded . Slice ( 0 , encodedLength ) ;
679
+ writer . Encode ( encoded ) ;
680
+ encoded [ 0 ] = 0x31 ;
681
+ return verify ( state , encoded ) ;
682
+ }
683
+ finally
684
+ {
685
+ if ( rented != null )
686
+ {
687
+ CryptoPool . Return ( rented ) ;
688
+ }
689
+ }
669
690
}
670
691
else
671
692
{
672
693
#if NET9_0_OR_GREATER
673
- return writer . Encode ( verify , static ( verify , encoded ) => verify ( encoded ) ) ;
694
+ return writer . Encode ( ( state , verify ) , static ( state , encoded ) => state . verify ( state . state , encoded ) ) ;
674
695
#else
675
- return verify ( writer . Encode ( ) ) ;
696
+ return verify ( state , writer . Encode ( ) ) ;
676
697
#endif
677
698
}
678
699
}
679
700
680
- private delegate bool VerifyCallback ( ReadOnlySpan < byte > contentToVerify ) ;
701
+ private delegate bool VerifyCallback < TState > ( TState state , ReadOnlySpan < byte > contentToVerify ) ;
681
702
682
- private bool VerifyHashedMessage ( bool compatMode , VerifyCallback verify )
703
+ private bool VerifyHashedMessage < TState > ( bool compatMode , TState state , VerifyCallback < TState > verify )
683
704
{
684
705
ReadOnlyMemory < byte > content = GetContentForVerification ( out ReadOnlyMemory < byte > ? additionalContent ) ;
685
706
@@ -710,7 +731,7 @@ private bool VerifyHashedMessage(bool compatMode, VerifyCallback verify)
710
731
throw new CryptographicException ( SR . Cryptography_Cms_MissingAuthenticatedAttribute ) ;
711
732
}
712
733
713
- return verify ( contentHash ) ;
734
+ return verify ( state , contentHash ) ;
714
735
}
715
736
716
737
// Since there are signed attributes, we need to verify those instead.
@@ -720,8 +741,10 @@ private bool VerifyHashedMessage(bool compatMode, VerifyCallback verify)
720
741
_signedAttributes ,
721
742
compatMode ,
722
743
needsContentAttr : false ,
723
- span =>
744
+ ( state , hasher , verify ) ,
745
+ static ( state , span ) =>
724
746
{
747
+ CmsHash hasher = state . hasher ;
725
748
hasher . AppendData ( span ) ;
726
749
727
750
#if NET || NETSTANDARD2_1
@@ -740,12 +763,12 @@ private bool VerifyHashedMessage(bool compatMode, VerifyCallback verify)
740
763
byte [ ] attrHash = hasher . GetHashAndReset ( ) ;
741
764
#endif
742
765
743
- return verify ( attrHash ) ;
766
+ return state . verify ( state . state , attrHash ) ;
744
767
} ) ;
745
768
}
746
769
}
747
770
748
- private bool VerifyPureMessage ( bool compatMode , VerifyCallback verify )
771
+ private bool VerifyPureMessage < TState > ( bool compatMode , TState state , VerifyCallback < TState > verify )
749
772
{
750
773
ReadOnlyMemory < byte > content = GetContentForVerification ( out ReadOnlyMemory < byte > ? additionalContent ) ;
751
774
@@ -760,7 +783,7 @@ private bool VerifyPureMessage(bool compatMode, VerifyCallback verify)
760
783
761
784
if ( ! additionalContent . HasValue )
762
785
{
763
- return verify ( content . Span ) ;
786
+ return verify ( state , content . Span ) ;
764
787
}
765
788
766
789
// If there are multiple pieces of content, concatenate them and verify.
@@ -770,7 +793,7 @@ private bool VerifyPureMessage(bool compatMode, VerifyCallback verify)
770
793
{
771
794
additionalContent . Value . Span . CopyTo ( rented ) ;
772
795
content . Span . CopyTo ( rented . AsSpan ( additionalContent . Value . Length ) ) ;
773
- return verify ( rented . AsSpan ( 0 , contentToVerifyLength ) ) ;
796
+ return verify ( state , rented . AsSpan ( 0 , contentToVerifyLength ) ) ;
774
797
}
775
798
finally
776
799
{
@@ -806,7 +829,8 @@ private bool VerifyPureMessage(bool compatMode, VerifyCallback verify)
806
829
// it is invalid for countersigners. We'll just ignore it for now, but if we decide to
807
830
// allow countersigners to omit the content type, we should check that `this` is a countersigner.
808
831
needsContentAttr : false ,
809
- verify ) ;
832
+ ( state , verify ) ,
833
+ static ( state , span ) => state . verify ( state . state , span ) ) ;
810
834
}
811
835
}
812
836
@@ -896,19 +920,42 @@ private bool VerifySignature(
896
920
return false ;
897
921
}
898
922
899
- Func < bool , VerifyCallback , bool > verifier = signatureProcessor . NeedsHashedMessage ? VerifyHashedMessage : VerifyPureMessage ;
900
- return verifier ( compatMode , contentToVerify =>
901
- signatureProcessor . VerifySignature (
923
+ if ( signatureProcessor . NeedsHashedMessage )
924
+ {
925
+ return VerifyHashedMessage (
926
+ compatMode ,
927
+ ( @this : this , signatureProcessor , certificate ) ,
928
+ static ( state , contentToVerify ) =>
929
+ state . signatureProcessor . VerifySignature (
930
+ #if NET || NETSTANDARD2_1
931
+ contentToVerify ,
932
+ state . @this . _signature ,
933
+ #else
934
+ contentToVerify . ToArray ( ) ,
935
+ state . @this . _signature . ToArray ( ) ,
936
+ #endif
937
+ state . @this . DigestAlgorithm . Value ,
938
+ state . @this . _signatureAlgorithmParameters ,
939
+ state . certificate ) ) ;
940
+ }
941
+ else
942
+ {
943
+ return VerifyPureMessage (
944
+ compatMode ,
945
+ ( @this : this , signatureProcessor , certificate ) ,
946
+ static ( state , contentToVerify ) =>
947
+ state . signatureProcessor . VerifySignature (
902
948
#if NET || NETSTANDARD2_1
903
- contentToVerify ,
904
- _signature ,
949
+ contentToVerify ,
950
+ state . @this . _signature ,
905
951
#else
906
- contentToVerify . ToArray ( ) ,
907
- _signature . ToArray ( ) ,
952
+ contentToVerify . ToArray ( ) ,
953
+ state . @this . _signature . ToArray ( ) ,
908
954
#endif
909
- DigestAlgorithm . Value ,
910
- _signatureAlgorithmParameters ,
911
- certificate ) ) ;
955
+ state . @this . DigestAlgorithm . Value ,
956
+ state . @this . _signatureAlgorithmParameters ,
957
+ state . certificate ) ) ;
958
+ }
912
959
}
913
960
914
961
private static int FindAttributeIndexByOid ( AttributeAsn [ ] attributes , Oid oid , int startIndex = 0 )
0 commit comments