@@ -2578,8 +2578,12 @@ Meta = class sealed(TAsn1UniversalType, IAsn1UniversalType)
25782578 // / </summary>
25792579 function GetValue (): TBigInteger;
25802580 // / <summary>
2581- // / Get the positive BigInteger value .
2581+ // / Force the ASN.1 INTEGER encoding to be interpreted as unsigned .
25822582 // / </summary>
2583+ // / <remarks>
2584+ // / In some cases positive values get crammed into a space that's not quite big enough...
2585+ // / NB: The BigInteger constructor tolerates any redundant sign bytes (per 'AllowUnsafeInteger').
2586+ // / </remarks>
25832587 function GetPositiveValue (): TBigInteger;
25842588 // / <summary>
25852589 // / Check if this integer has a specific Int32 value.
@@ -2598,26 +2602,50 @@ Meta = class sealed(TAsn1UniversalType, IAsn1UniversalType)
25982602 // / </summary>
25992603 function GetIntValueExact (): Int32;
26002604 // / <summary>
2601- // / Get positive Int32 value, throwing if out of range .
2605+ // / Force the ASN.1 INTEGER encoding to be interpreted as unsigned .
26022606 // / </summary>
2607+ // / <remarks>
2608+ // / In some cases positive values get crammed into a space that's not quite big enough...
2609+ // / </remarks>
26032610 function GetIntPositiveValueExact (): Int32;
26042611 // / <summary>
26052612 // / Get Int64 value, throwing if out of range.
26062613 // / </summary>
26072614 function GetLongValueExact (): Int64;
26082615 // / <summary>
2616+ // / Force the ASN.1 INTEGER encoding to be interpreted as unsigned.
2617+ // / </summary>
2618+ // / <remarks>
2619+ // / In some cases positive values get crammed into a space that's not quite big enough...
2620+ // / </remarks>
2621+ function GetLongPositiveValueExact (): Int64;
2622+ // / <summary>
26092623 // / Try to get Int32 value, returning false if out of range.
26102624 // / </summary>
26112625 function TryGetIntValueExact (out AValue: Int32): Boolean;
26122626 // / <summary>
2613- // / Try to get positive Int32 value, returning false if out of range .
2627+ // / Force the ASN.1 INTEGER encoding to be interpreted as unsigned .
26142628 // / </summary>
2629+ // / <remarks>
2630+ // / In some cases positive values get crammed into a space that's not quite big enough...
2631+ // / </remarks>
26152632 function TryGetIntPositiveValueExact (out AValue: Int32): Boolean;
26162633 // / <summary>
26172634 // / Try to get Int64 value, returning false if out of range.
26182635 // / </summary>
26192636 function TryGetLongValueExact (out AValue: Int64): Boolean;
26202637 // / <summary>
2638+ // / Force the ASN.1 INTEGER encoding to be interpreted as unsigned.
2639+ // / </summary>
2640+ // / <remarks>
2641+ // / In some cases positive values get crammed into a space that's not quite big enough...
2642+ // / </remarks>
2643+ function TryGetLongPositiveValueExact (out AValue: Int64): Boolean;
2644+ // / <summary>
2645+ // / Whether the first significant encoding byte has the sign bit set.
2646+ // / </summary>
2647+ function GetIsNegative (): Boolean;
2648+ // / <summary>
26212649 // / Check if bytes are malformed (invalid INTEGER encoding).
26222650 // / </summary>
26232651 class function IsMalformed (const ABytes: TCryptoLibByteArray): Boolean; static;
@@ -2642,6 +2670,8 @@ Meta = class sealed(TAsn1UniversalType, IAsn1UniversalType)
26422670 property IntValueExact: Int32 read GetIntValueExact;
26432671 property IntPositiveValueExact: Int32 read GetIntPositiveValueExact;
26442672 property LongValueExact: Int64 read GetLongValueExact;
2673+ property LongPositiveValueExact: Int64 read GetLongPositiveValueExact;
2674+ property IsNegative: Boolean read GetIsNegative;
26452675 end ;
26462676
26472677 // / <summary>
@@ -12659,33 +12689,27 @@ function TDerInteger.HasValue(const AX: TBigInteger): Boolean;
1265912689end ;
1266012690
1266112691function TDerInteger.GetIntValueExact (): Int32;
12662- var
12663- LCount: Int32;
1266412692begin
12665- LCount := System.Length(FBytes) - FStart;
12666- if LCount > 4 then
12693+ if not TryGetIntValueExact(Result) then
1266712694 raise EArithmeticCryptoLibException.Create(' ASN.1 Integer out of int range' );
12668- Result := TDerInteger.IntValue(FBytes, FStart, SignExtSigned);
1266912695end ;
1267012696
1267112697function TDerInteger.GetIntPositiveValueExact (): Int32;
12672- var
12673- LCount: Int32;
1267412698begin
12675- LCount := System.Length(FBytes) - FStart;
12676- if (LCount > 4 ) or ((LCount = 4 ) and ((FBytes[FStart] and $80 ) <> 0 )) then
12699+ if not TryGetIntPositiveValueExact(Result) then
1267712700 raise EArithmeticCryptoLibException.Create(' ASN.1 Integer out of positive int range' );
12678- Result := TDerInteger.IntValue(FBytes, FStart, SignExtUnsigned);
1267912701end ;
1268012702
1268112703function TDerInteger.GetLongValueExact (): Int64;
12682- var
12683- LCount: Int32;
1268412704begin
12685- LCount := System.Length(FBytes) - FStart;
12686- if LCount > 8 then
12705+ if not TryGetLongValueExact(Result) then
1268712706 raise EArithmeticCryptoLibException.Create(' ASN.1 Integer out of long range' );
12688- Result := TDerInteger.LongValue(FBytes, FStart, SignExtSigned);
12707+ end ;
12708+
12709+ function TDerInteger.GetLongPositiveValueExact (): Int64;
12710+ begin
12711+ if not TryGetLongPositiveValueExact(Result) then
12712+ raise EArithmeticCryptoLibException.Create(' ASN.1 Integer out of positive long range' );
1268912713end ;
1269012714
1269112715function TDerInteger.TryGetIntValueExact (out AValue: Int32): Boolean;
@@ -12708,7 +12732,7 @@ function TDerInteger.TryGetIntPositiveValueExact(out AValue: Int32): Boolean;
1270812732 LCount: Int32;
1270912733begin
1271012734 LCount := System.Length(FBytes) - FStart;
12711- if (LCount > 4 ) or ((LCount = 4 ) and ((FBytes[FStart] and $ 80 ) <> 0 ) ) then
12735+ if (LCount > 4 ) or ((LCount = 4 ) and IsNegative ) then
1271212736 begin
1271312737 AValue := 0 ;
1271412738 Result := False;
@@ -12718,6 +12742,21 @@ function TDerInteger.TryGetIntPositiveValueExact(out AValue: Int32): Boolean;
1271812742 Result := True;
1271912743end ;
1272012744
12745+ function TDerInteger.TryGetLongPositiveValueExact (out AValue: Int64): Boolean;
12746+ var
12747+ LCount: Int32;
12748+ begin
12749+ LCount := System.Length(FBytes) - FStart;
12750+ if (LCount > 8 ) or ((LCount = 8 ) and IsNegative) then
12751+ begin
12752+ AValue := 0 ;
12753+ Result := False;
12754+ Exit;
12755+ end ;
12756+ AValue := TDerInteger.LongValue(FBytes, FStart, SignExtSigned);
12757+ Result := True;
12758+ end ;
12759+
1272112760function TDerInteger.TryGetLongValueExact (out AValue: Int64): Boolean;
1272212761var
1272312762 LCount: Int32;
@@ -12733,6 +12772,11 @@ function TDerInteger.TryGetLongValueExact(out AValue: Int64): Boolean;
1273312772 Result := True;
1273412773end ;
1273512774
12775+ function TDerInteger.GetIsNegative (): Boolean;
12776+ begin
12777+ Result := (FBytes[FStart] and $80 ) <> 0 ;
12778+ end ;
12779+
1273612780function TDerInteger.GetEncoding (AEncoding: Int32): IAsn1Encoding;
1273712781begin
1273812782 Result := TPrimitiveEncoding.Create(TAsn1Tags.Universal, TAsn1Tags.Integer, FBytes);
0 commit comments