⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asn1.pas

📁 cipher 5.1。一个几乎包含了所有常见的加密算法的控件
💻 PAS
字号:
{Copyright:      Hagen Reddmann  HaReddmann at T-Online dot de
 Author:         Hagen Reddmann
 Remarks:        Shareware, this Copyright must be included
 known Problems: none
 Version:        5.1, Delphi Encryption Compendium
                 Delphi 2-6, BCB 3-4, designed and testet under D3-6
 Description:    ASN.1 protocoll base routines

 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 }
{$I VER.INC}
unit ASN1;

interface

uses Classes, SysUtils;

type
  EASN1 = class(Exception);

procedure ASN1_ChangeEndian(var Buffer; Size: LongInt);
function  ASN1_SwapEndian(Value: Integer): Integer; overload;
function  ASN1_SwapEndian(Value: Cardinal): Cardinal; overload;
function  ASN1_SwapEndian(Value: Word): Word; overload;
function  ASN1_CalcLen(var Len: LongInt): Byte;
function  ASN1_WriteLen(Stream: TStream; Len: LongInt): LongInt;
function  ASN1_ReadLen(Stream: TStream): LongInt;
function  ASN1_WriteStr(Stream: TStream; const Value: String): LongInt;
function  ASN1_ReadStr(Stream: TStream): String;
function  ASN1_WriteWStr(Stream: TStream; const Value: WideString): LongInt;
function  ASN1_ReadWStr(Stream: TStream): WideString;
function  ASN1_WriteBuf(Stream: TStream; const Buffer; Size: LongInt): LongInt;
function  ASN1_ReadBuf(Stream: TStream; var Buffer; Size: LongInt): LongInt;

var
  ASN1_Integer: Byte = $02;  // Tag for asn1 integer

implementation

// only <= 4 Bytes asn1 Length are supported
// we follow Borland Style and use LongInt for compatibility to TStream

procedure ASN1_ChangeEndian(var Buffer; Size: Integer); assembler; register;
// not fast, but easy
asm
       CMP    EDX,1
       JLE    @@3
       AND    EAX,EAX
       JZ     @@3
       PUSH   EBX
       MOV    ECX,EDX
       LEA    EDX,[EAX + ECX -1]
       SHR    ECX,1
@@1:   MOV    BL,[EAX]
       XCHG   BL,[EDX]
       DEC    EDX
       MOV    [EAX],BL
       INC    EAX
       DEC    ECX
       JNZ    @@1
@@2:   POP    EBX
@@3:
end;

function ASN1_SwapEndian(Value: Integer): Integer;
asm
       BSWAP  EAX
end;

function ASN1_SwapEndian(Value: Cardinal): Cardinal;
asm
       BSWAP  EAX
end;

function ASN1_SwapEndian(Value: Word): Word;
asm
       XCHG   AL,AH
end;

procedure ASN1_Raise(Msg: PResStringRec);
resourcestring
  sASN1LenCoding = 'Invalid ASN1 Length encoded Tag detected.';
var
  ErrorAddr: Pointer;
begin
  asm
       MOV   EAX,[EBP + 8]
       SUB   EAX,4
       MOV   ErrorAddr,EAX
  end;
  raise EASN1.Create(LoadResString(Msg)) at ErrorAddr;
end;

procedure ASN1_RaiseLen;
resourcestring
  sASN1LenCoding = 'Invalid ASN1 Length encoded Tag detected';
begin
  ASN1_Raise(@sASN1LenCoding);
end;

procedure ASN1_RaiseWrite;
resourcestring
  sASN1Writing = 'ASN1 stream write error';
begin
  ASN1_Raise(@sASN1Writing);
end;

procedure ASN1_RaiseRead;
resourcestring
  sASN1Reading = 'ASN1 stream read error';
begin
  ASN1_Raise(@sASN1Reading);
end;

function ASN1_CalcLen(var Len: LongInt): Byte;
begin
  if Len < 0 then ASN1_RaiseLen;
  if Len > $7F then
  begin
    if Len and $FFFFFF00 = 0 then Result := 1 else
      if Len and $FFFF0000 = 0 then Result := 2 else
        if Len and $FF000000 = 0 then Result := 3
          else Result := 4;
    ASN1_ChangeEndian(Len, Result);
    Result := Result or $80;
  end else Result := Len;
end;

function ASN1_WriteLen(Stream: TStream; Len: LongInt): LongInt;
var
  B: Byte;
begin
  B := ASN1_CalcLen(Len);
  if Stream.Write(B, SizeOf(B)) <> SizeOf(B) then ASN1_RaiseWrite;
  if B and $80 <> 0 then
  begin
    B := B and $7F;
    if Stream.Write(Len, B) <> B then ASN1_RaiseWrite;
    Result := B + SizeOf(B);
  end else Result := SizeOf(B);
end;

function ASN1_ReadLen(Stream: TStream): LongInt;
var
  B: Byte;
begin
  Result := 0;
  if Stream.Read(B, SizeOf(B)) <> SizeOf(B) then ASN1_RaiseRead;
  if B and $80 <> 0 then
  begin
    B := B and $7F;
    if B > 4 then ASN1_RaiseLen;
    if B > 0 then
    begin
      if Stream.Read(Result, B) <> B then ASN1_RaiseRead;
      ASN1_ChangeEndian(Result, B);
      if Result < 0 then ASN1_RaiseLen;
    end else Result := Stream.Size - Stream.Position;
  end else Result := B;
end;

function ASN1_WriteStr(Stream: TStream; const Value: String): LongInt;
var
  I: LongInt;
begin
  I := Length(Value);
  Result := ASN1_WriteLen(Stream, I) + I;
  if Stream.Write(PChar(Value)^, I) <> I then ASN1_RaiseWrite;
end;

function ASN1_ReadStr(Stream: TStream): String;
var
  I: LongInt;
begin
  I := ASN1_ReadLen(Stream);
  SetLength(Result, I);
  if Stream.Read(PChar(Result)^, I) <> I then ASN1_RaiseRead;
end;

function ASN1_WriteWStr(Stream: TStream; const Value: WideString): LongInt;
var
  I: LongInt;
begin
  I := Length(Value) * 2;
  Result := ASN1_WriteLen(Stream, I) + I;
  if Stream.Write(Pointer(Value)^, I) <> I then ASN1_RaiseWrite;
end;

function ASN1_ReadWStr(Stream: TStream): WideString;
var
  I: LongInt;
begin
  I := ASN1_ReadLen(Stream);
  SetLength(Result, I);
  if Stream.Read(Pointer(Result)^, I) <> I then ASN1_RaiseRead;
end;

function ASN1_WriteBuf(Stream: TStream; const Buffer; Size: LongInt): LongInt;
begin
  Result := ASN1_WriteLen(Stream, Size) + Size;
  if Stream.Write(Buffer, Size) <> Size then ASN1_RaiseWrite;
end;

function ASN1_ReadBuf(Stream: TStream; var Buffer; Size: LongInt): LongInt;
begin
  Result := ASN1_ReadLen(Stream);
  if Result > Size then ASN1_RaiseRead;
  if Stream.Read(Buffer, Result) <> Result then ASN1_RaiseRead;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -