Bugfixes in OpenSSL, enhanced OpenSSL support, enhanced binary MIME (all by Petr Fejfar)
git-svn-id: https://svn.code.sf.net/p/synalist/code/trunk@147 7c85be65-684b-0410-a082-b2ed4fbef004
This commit is contained in:
parent
f5be030c70
commit
3caad66c4b
27
blcksock.pas
27
blcksock.pas
@ -1,9 +1,9 @@
|
|||||||
{==============================================================================|
|
{==============================================================================|
|
||||||
| Project : Ararat Synapse | 009.008.004 |
|
| Project : Ararat Synapse | 009.008.005 |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Content: Library base |
|
| Content: Library base |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Copyright (c)1999-2011, Lukas Gebauer |
|
| Copyright (c)1999-2012, Lukas Gebauer |
|
||||||
| All rights reserved. |
|
| All rights reserved. |
|
||||||
| |
|
| |
|
||||||
| Redistribution and use in source and binary forms, with or without |
|
| Redistribution and use in source and binary forms, with or without |
|
||||||
@ -33,7 +33,7 @@
|
|||||||
| DAMAGE. |
|
| DAMAGE. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
||||||
| Portions created by Lukas Gebauer are Copyright (c)1999-2011. |
|
| Portions created by Lukas Gebauer are Copyright (c)1999-2012. |
|
||||||
| All Rights Reserved. |
|
| All Rights Reserved. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Contributor(s): |
|
| Contributor(s): |
|
||||||
@ -81,6 +81,8 @@ Core with implementation basic socket classes.
|
|||||||
{$Q-}
|
{$Q-}
|
||||||
{$H+}
|
{$H+}
|
||||||
{$M+}
|
{$M+}
|
||||||
|
{$TYPEDADDRESS OFF}
|
||||||
|
|
||||||
|
|
||||||
//old Delphi does not have MSWINDOWS define.
|
//old Delphi does not have MSWINDOWS define.
|
||||||
{$IFDEF WIN32}
|
{$IFDEF WIN32}
|
||||||
@ -1297,6 +1299,9 @@ type
|
|||||||
{:Return subject of remote SSL peer.}
|
{:Return subject of remote SSL peer.}
|
||||||
function GetPeerSubject: string; virtual;
|
function GetPeerSubject: string; virtual;
|
||||||
|
|
||||||
|
{:Return Serial number if remote X509 certificate.}
|
||||||
|
function GetPeerSerialNo: integer; virtual;
|
||||||
|
|
||||||
{:Return issuer certificate of remote SSL peer.}
|
{:Return issuer certificate of remote SSL peer.}
|
||||||
function GetPeerIssuer: string; virtual;
|
function GetPeerIssuer: string; virtual;
|
||||||
|
|
||||||
@ -1304,6 +1309,10 @@ type
|
|||||||
if certificate is generated for remote side IP name.}
|
if certificate is generated for remote side IP name.}
|
||||||
function GetPeerName: string; virtual;
|
function GetPeerName: string; virtual;
|
||||||
|
|
||||||
|
{:Returns has of peer name from remote side certificate. This is good
|
||||||
|
for fast remote side authentication.}
|
||||||
|
function GetPeerNameHash: cardinal; virtual;
|
||||||
|
|
||||||
{:Return fingerprint of remote SSL peer.}
|
{:Return fingerprint of remote SSL peer.}
|
||||||
function GetPeerFingerprint: string; virtual;
|
function GetPeerFingerprint: string; virtual;
|
||||||
|
|
||||||
@ -2682,7 +2691,7 @@ end;
|
|||||||
|
|
||||||
function TBlockSocket.ResolveIPToName(IP: string): string;
|
function TBlockSocket.ResolveIPToName(IP: string): string;
|
||||||
begin
|
begin
|
||||||
if not IsIP(IP) or not IsIp6(IP) then
|
if not IsIP(IP) and not IsIp6(IP) then
|
||||||
IP := ResolveName(IP);
|
IP := ResolveName(IP);
|
||||||
Result := synsock.ResolveIPToName(IP, FamilyToAF(FFamily), GetSocketProtocol, GetSocketType);
|
Result := synsock.ResolveIPToName(IP, FamilyToAF(FFamily), GetSocketProtocol, GetSocketType);
|
||||||
end;
|
end;
|
||||||
@ -4224,11 +4233,21 @@ begin
|
|||||||
Result := '';
|
Result := '';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCustomSSL.GetPeerSerialNo: integer;
|
||||||
|
begin
|
||||||
|
Result := -1;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCustomSSL.GetPeerName: string;
|
function TCustomSSL.GetPeerName: string;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCustomSSL.GetPeerNameHash: cardinal;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCustomSSL.GetPeerIssuer: string;
|
function TCustomSSL.GetPeerIssuer: string;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
|
@ -52,6 +52,9 @@ Used RFC: RFC-959, RFC-2228, RFC-2428
|
|||||||
{$MODE DELPHI}
|
{$MODE DELPHI}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$H+}
|
{$H+}
|
||||||
|
{$TYPEINFO ON}// Borland changed defualt Visibility from Public to Published
|
||||||
|
// and it requires RTTI to be generated $M+
|
||||||
|
{$M+}
|
||||||
|
|
||||||
{$IFDEF UNICODE}
|
{$IFDEF UNICODE}
|
||||||
{$WARN IMPLICIT_STRING_CAST OFF}
|
{$WARN IMPLICIT_STRING_CAST OFF}
|
||||||
|
33
mimemess.pas
33
mimemess.pas
@ -1,9 +1,9 @@
|
|||||||
{==============================================================================|
|
{==============================================================================|
|
||||||
| Project : Ararat Synapse | 002.005.002 |
|
| Project : Ararat Synapse | 002.006.000 |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Content: MIME message object |
|
| Content: MIME message object |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Copyright (c)1999-2006, Lukas Gebauer |
|
| Copyright (c)1999-2012, Lukas Gebauer |
|
||||||
| All rights reserved. |
|
| All rights reserved. |
|
||||||
| |
|
| |
|
||||||
| Redistribution and use in source and binary forms, with or without |
|
| Redistribution and use in source and binary forms, with or without |
|
||||||
@ -33,7 +33,8 @@
|
|||||||
| DAMAGE. |
|
| DAMAGE. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
||||||
| Portions created by Lukas Gebauer are Copyright (c)2000-2006. |
|
| Portions created by Lukas Gebauer are Copyright (c)2000-2012. |
|
||||||
|
| Portions created by Petr Fejfar are Copyright (c)2011-2012. |
|
||||||
| All Rights Reserved. |
|
| All Rights Reserved. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Contributor(s): |
|
| Contributor(s): |
|
||||||
@ -50,6 +51,7 @@ Classes for easy handling with e-mail message.
|
|||||||
{$MODE DELPHI}
|
{$MODE DELPHI}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$H+}
|
{$H+}
|
||||||
|
{$M+}
|
||||||
|
|
||||||
unit mimemess;
|
unit mimemess;
|
||||||
|
|
||||||
@ -269,6 +271,20 @@ type
|
|||||||
{:Decode message from @link(Lines) to @link(MessagePart). Massage headers
|
{:Decode message from @link(Lines) to @link(MessagePart). Massage headers
|
||||||
are parsed into @link(Header) object.}
|
are parsed into @link(Header) object.}
|
||||||
procedure DecodeMessage;
|
procedure DecodeMessage;
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
{: HTTP message is received by @link(THTTPSend) component in two parts:
|
||||||
|
headers are stored in @link(THTTPSend.Headers) and a body in memory stream
|
||||||
|
@link(THTTPSend.Document).
|
||||||
|
|
||||||
|
On the top of it, HTTP connections are always 8-bit, hence data are
|
||||||
|
transferred in native format i.e. no transfer encoding is applied.
|
||||||
|
|
||||||
|
This method operates the similiar way and produces the same
|
||||||
|
result as @link(DecodeMessage).
|
||||||
|
}
|
||||||
|
procedure DecodeMessageBinary(AHeader:TStrings; AData:TMemoryStream);
|
||||||
|
{/pf}
|
||||||
published
|
published
|
||||||
{:@link(TMimePart) object with decoded MIME message. This object can handle
|
{:@link(TMimePart) object with decoded MIME message. This object can handle
|
||||||
any number of nested @link(TMimePart) objects itself. It is used for handle
|
any number of nested @link(TMimePart) objects itself. It is used for handle
|
||||||
@ -821,4 +837,15 @@ begin
|
|||||||
FMessagePart.DecomposeParts;
|
FMessagePart.DecomposeParts;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
procedure TMimeMess.DecodeMessageBinary(AHeader:TStrings; AData:TMemoryStream);
|
||||||
|
begin
|
||||||
|
FHeader.Clear;
|
||||||
|
FLines.Clear;
|
||||||
|
FLines.Assign(AHeader);
|
||||||
|
FHeader.DecodeHeaders(FLines);
|
||||||
|
FMessagePart.DecomposePartsBinary(AHeader,PANSIChar(AData.Memory),PANSIChar(AData.Memory)+AData.Size);
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
141
mimepart.pas
141
mimepart.pas
@ -1,10 +1,9 @@
|
|||||||
{==============================================================================|
|
{==============================================================================|
|
||||||
| Project : Ararat Synapse | 002.008.000 |
|
| Project : Ararat Synapse | 002.009.000 |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Content: MIME support procedures and functions |
|
| Content: MIME support procedures and functions |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Copyright (c)1999-2008, Lukas Gebauer |
|
| Copyright (c)1999-200812 |
|
||||||
| All rights reserved. |
|
|
||||||
| |
|
| |
|
||||||
| Redistribution and use in source and binary forms, with or without |
|
| Redistribution and use in source and binary forms, with or without |
|
||||||
| modification, are permitted provided that the following conditions are met: |
|
| modification, are permitted provided that the following conditions are met: |
|
||||||
@ -33,7 +32,8 @@
|
|||||||
| DAMAGE. |
|
| DAMAGE. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
||||||
| Portions created by Lukas Gebauer are Copyright (c)2000-2008. |
|
| Portions created by Lukas Gebauer are Copyright (c)2000-2012. |
|
||||||
|
| Portions created by Petr Fejfar are Copyright (c)2011-2012. |
|
||||||
| All Rights Reserved. |
|
| All Rights Reserved. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Contributor(s): |
|
| Contributor(s): |
|
||||||
@ -54,6 +54,7 @@ Used RFC: RFC-2045
|
|||||||
{$H+}
|
{$H+}
|
||||||
{$Q-}
|
{$Q-}
|
||||||
{$R-}
|
{$R-}
|
||||||
|
{$M+}
|
||||||
|
|
||||||
{$IFDEF UNICODE}
|
{$IFDEF UNICODE}
|
||||||
{$WARN IMPLICIT_STRING_CAST OFF}
|
{$WARN IMPLICIT_STRING_CAST OFF}
|
||||||
@ -137,6 +138,7 @@ type
|
|||||||
FAttachInside: boolean;
|
FAttachInside: boolean;
|
||||||
FConvertCharset: Boolean;
|
FConvertCharset: Boolean;
|
||||||
FForcedHTMLConvert: Boolean;
|
FForcedHTMLConvert: Boolean;
|
||||||
|
FBinaryDecomposer: boolean;
|
||||||
procedure SetPrimary(Value: string);
|
procedure SetPrimary(Value: string);
|
||||||
procedure SetEncoding(Value: string);
|
procedure SetEncoding(Value: string);
|
||||||
procedure SetCharset(Value: string);
|
procedure SetCharset(Value: string);
|
||||||
@ -204,6 +206,20 @@ type
|
|||||||
method @link(GetSubPart)).}
|
method @link(GetSubPart)).}
|
||||||
procedure DecomposeParts;
|
procedure DecomposeParts;
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
{: HTTP message is received by @link(THTTPSend) component in two parts:
|
||||||
|
headers are stored in @link(THTTPSend.Headers) and a body in memory stream
|
||||||
|
@link(THTTPSend.Document).
|
||||||
|
|
||||||
|
On the top of it, HTTP connections are always 8-bit, hence data are
|
||||||
|
transferred in native format i.e. no transfer encoding is applied.
|
||||||
|
|
||||||
|
This method operates the similiar way and produces the same
|
||||||
|
result as @link(DecomposeParts).
|
||||||
|
}
|
||||||
|
procedure DecomposePartsBinary(AHeader:TStrings; AStx,AEtx:PANSIChar);
|
||||||
|
{/pf}
|
||||||
|
|
||||||
{:This part and all subparts is composed into one MIME message stored in
|
{:This part and all subparts is composed into one MIME message stored in
|
||||||
@link(Lines) property.}
|
@link(Lines) property.}
|
||||||
procedure ComposeParts;
|
procedure ComposeParts;
|
||||||
@ -535,6 +551,7 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
FBinaryDecomposer := false;
|
||||||
x := 0;
|
x := 0;
|
||||||
Clear;
|
Clear;
|
||||||
//extract headers
|
//extract headers
|
||||||
@ -624,6 +641,95 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TMIMEPart.DecomposePartsBinary(AHeader:TStrings; AStx,AEtx:PANSIChar);
|
||||||
|
var
|
||||||
|
x: integer;
|
||||||
|
s: ANSIString;
|
||||||
|
Mime: TMimePart;
|
||||||
|
BOP: PANSIChar; // Beginning of Part
|
||||||
|
EOP: PANSIChar; // End of Part
|
||||||
|
|
||||||
|
function ___HasUUCode(ALines:TStrings): boolean;
|
||||||
|
var
|
||||||
|
x: integer;
|
||||||
|
begin
|
||||||
|
Result := FALSE;
|
||||||
|
for x:=0 to ALines.Count-1 do
|
||||||
|
if IsUUcode(ALInes[x]) then
|
||||||
|
begin
|
||||||
|
Result := TRUE;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
FBinaryDecomposer := true;
|
||||||
|
Clear;
|
||||||
|
// Parse passed headers (THTTPSend returns HTTP headers and body separately)
|
||||||
|
x := 0;
|
||||||
|
while x<AHeader.Count do
|
||||||
|
begin
|
||||||
|
s := NormalizeHeader(AHeader,x);
|
||||||
|
if s = '' then
|
||||||
|
Break;
|
||||||
|
FHeaders.Add(s);
|
||||||
|
end;
|
||||||
|
DecodePartHeader;
|
||||||
|
// Extract prepart
|
||||||
|
if FPrimaryCode=MP_MULTIPART then
|
||||||
|
begin
|
||||||
|
CopyLinesFromStreamUntilBoundary(AStx,AEtx,FPrePart,FBoundary);
|
||||||
|
FAttachInside := FAttachInside or ___HasUUCode(FPrePart);
|
||||||
|
end;
|
||||||
|
// Extract body part
|
||||||
|
if FPrimaryCode=MP_MULTIPART then
|
||||||
|
begin
|
||||||
|
repeat
|
||||||
|
if CanSubPart then
|
||||||
|
begin
|
||||||
|
Mime := AddSubPart;
|
||||||
|
BOP := AStx;
|
||||||
|
EOP := SearchForBoundary(AStx,AEtx,FBoundary);
|
||||||
|
CopyLinesFromStreamUntilNullLine(BOP,EOP,Mime.Lines);
|
||||||
|
Mime.DecomposePartsBinary(Mime.Lines,BOP,EOP);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
EOP := SearchForBoundary(AStx,AEtx,FBoundary);
|
||||||
|
FPartBody.Add(BuildStringFromBuffer(AStx,EOP));
|
||||||
|
end;
|
||||||
|
//
|
||||||
|
BOP := MatchLastBoundary(EOP,AEtx,FBoundary);
|
||||||
|
if Assigned(BOP) then
|
||||||
|
begin
|
||||||
|
AStx := BOP;
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
until FALSE;
|
||||||
|
end;
|
||||||
|
// Extract nested MIME message
|
||||||
|
if (FPrimaryCode=MP_MESSAGE) and CanSubPart then
|
||||||
|
begin
|
||||||
|
Mime := AddSubPart;
|
||||||
|
SkipNullLines(AStx,AEtx);
|
||||||
|
CopyLinesFromStreamUntilNullLine(AStx,AEtx,Mime.Lines);
|
||||||
|
Mime.DecomposePartsBinary(Mime.Lines,AStx,AEtx);
|
||||||
|
end
|
||||||
|
// Extract body of single part
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
FPartBody.Add(BuildStringFromBuffer(AStx,AEtx));
|
||||||
|
FAttachInside := FAttachInside or ___HasUUCode(FPartBody);
|
||||||
|
end;
|
||||||
|
// Extract postpart
|
||||||
|
if FPrimaryCode=MP_MULTIPART then
|
||||||
|
begin
|
||||||
|
CopyLinesFromStreamUntilBoundary(AStx,AEtx,FPostPart,'');
|
||||||
|
FAttachInside := FAttachInside or ___HasUUCode(FPostPart);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
{==============================================================================}
|
{==============================================================================}
|
||||||
|
|
||||||
procedure TMIMEPart.ComposeParts;
|
procedure TMIMEPart.ComposeParts;
|
||||||
@ -713,6 +819,33 @@ var
|
|||||||
b: Boolean;
|
b: Boolean;
|
||||||
begin
|
begin
|
||||||
FDecodedLines.Clear;
|
FDecodedLines.Clear;
|
||||||
|
{pf}
|
||||||
|
// The part decomposer passes data via TStringList which appends trailing line
|
||||||
|
// break inherently. But in a case of native 8-bit data transferred withouth
|
||||||
|
// encoding (default e.g. for HTTP protocol), the redundant line terminators
|
||||||
|
// has to be removed
|
||||||
|
if FBinaryDecomposer and (FPartBody.Count=1) then
|
||||||
|
begin
|
||||||
|
case FEncodingCode of
|
||||||
|
ME_QUOTED_PRINTABLE:
|
||||||
|
s := DecodeQuotedPrintable(FPartBody[0]);
|
||||||
|
ME_BASE64:
|
||||||
|
s := DecodeBase64(FPartBody[0]);
|
||||||
|
ME_UU, ME_XX:
|
||||||
|
begin
|
||||||
|
s := '';
|
||||||
|
for n := 0 to FPartBody.Count - 1 do
|
||||||
|
if FEncodingCode = ME_UU then
|
||||||
|
s := s + DecodeUU(FPartBody[n])
|
||||||
|
else
|
||||||
|
s := s + DecodeXX(FPartBody[n]);
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
s := FPartBody[0];
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{/pf}
|
||||||
case FEncodingCode of
|
case FEncodingCode of
|
||||||
ME_QUOTED_PRINTABLE:
|
ME_QUOTED_PRINTABLE:
|
||||||
s := DecodeQuotedPrintable(FPartBody.Text);
|
s := DecodeQuotedPrintable(FPartBody.Text);
|
||||||
|
@ -372,7 +372,6 @@ function TSMTPSend.AuthPlain: Boolean;
|
|||||||
var
|
var
|
||||||
s: ansistring;
|
s: ansistring;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
|
||||||
s := ansichar(0) + FUsername + ansichar(0) + FPassword;
|
s := ansichar(0) + FUsername + ansichar(0) + FPassword;
|
||||||
FSock.SendString('AUTH PLAIN ' + EncodeBase64(s) + CRLF);
|
FSock.SendString('AUTH PLAIN ' + EncodeBase64(s) + CRLF);
|
||||||
Result := ReadResult = 235;
|
Result := ReadResult = 235;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Content: SSL/SSH support by Peter Gutmann's CryptLib |
|
| Content: SSL/SSH support by Peter Gutmann's CryptLib |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Copyright (c)1999-2005, Lukas Gebauer |
|
| Copyright (c)1999-2012, Lukas Gebauer |
|
||||||
| All rights reserved. |
|
| All rights reserved. |
|
||||||
| |
|
| |
|
||||||
| Redistribution and use in source and binary forms, with or without |
|
| Redistribution and use in source and binary forms, with or without |
|
||||||
@ -33,7 +33,7 @@
|
|||||||
| DAMAGE. |
|
| DAMAGE. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
||||||
| Portions created by Lukas Gebauer are Copyright (c)2005. |
|
| Portions created by Lukas Gebauer are Copyright (c)2005-2012. |
|
||||||
| All Rights Reserved. |
|
| All Rights Reserved. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Contributor(s): |
|
| Contributor(s): |
|
||||||
@ -84,6 +84,7 @@ unit ssl_cryptlib;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
Windows,
|
||||||
SysUtils,
|
SysUtils,
|
||||||
blcksock, synsock, synautil, synacode,
|
blcksock, synsock, synautil, synacode,
|
||||||
cryptlib;
|
cryptlib;
|
||||||
@ -233,7 +234,6 @@ var
|
|||||||
cert: CRYPT_CERTIFICATE;
|
cert: CRYPT_CERTIFICATE;
|
||||||
publicKey: CRYPT_CONTEXT;
|
publicKey: CRYPT_CONTEXT;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
|
||||||
if FPrivatekeyFile = '' then
|
if FPrivatekeyFile = '' then
|
||||||
FPrivatekeyFile := GetTempFile('', 'key');
|
FPrivatekeyFile := GetTempFile('', 'key');
|
||||||
cryptCreateContext(privateKey, CRYPT_UNUSED, CRYPT_ALGO_RSA);
|
cryptCreateContext(privateKey, CRYPT_UNUSED, CRYPT_ALGO_RSA);
|
||||||
@ -402,7 +402,7 @@ begin
|
|||||||
FcryptSession := CRYPT_SESSION(CRYPT_SESSION_NONE);
|
FcryptSession := CRYPT_SESSION(CRYPT_SESSION_NONE);
|
||||||
FSSLEnabled := False;
|
FSSLEnabled := False;
|
||||||
if FDelCert then
|
if FDelCert then
|
||||||
Deletefile(FPrivatekeyFile);
|
SysUtils.DeleteFile(FPrivatekeyFile);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSSLCryptLib.Prepare(server:Boolean): Boolean;
|
function TSSLCryptLib.Prepare(server:Boolean): Boolean;
|
||||||
@ -459,8 +459,8 @@ end;
|
|||||||
|
|
||||||
function TSSLCryptLib.BiShutdown: boolean;
|
function TSSLCryptLib.BiShutdown: boolean;
|
||||||
begin
|
begin
|
||||||
// if FcryptSession <> CRYPT_SESSION(CRYPT_SESSION_NONE) then
|
if FcryptSession <> CRYPT_SESSION(CRYPT_SESSION_NONE) then
|
||||||
// cryptSetAttribute(FCryptSession, CRYPT_SESSINFO_ACTIVE, 0); //no-op
|
cryptSetAttribute(FCryptSession, CRYPT_SESSINFO_ACTIVE, 0);
|
||||||
DeInit;
|
DeInit;
|
||||||
FReadBuffer := '';
|
FReadBuffer := '';
|
||||||
Result := True;
|
Result := True;
|
||||||
@ -478,8 +478,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TSSLCryptLib.RecvBuffer(Buffer: TMemory; Len: Integer): Integer;
|
function TSSLCryptLib.RecvBuffer(Buffer: TMemory; Len: Integer): Integer;
|
||||||
var
|
|
||||||
l: integer;
|
|
||||||
begin
|
begin
|
||||||
FLastError := 0;
|
FLastError := 0;
|
||||||
FLastErrorDesc := '';
|
FLastErrorDesc := '';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{==============================================================================|
|
{==============================================================================|
|
||||||
| Project : Ararat Synapse | 001.001.001 |
|
| Project : Ararat Synapse | 001.002.000 |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Content: SSL support by OpenSSL |
|
| Content: SSL support by OpenSSL |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
@ -33,7 +33,8 @@
|
|||||||
| DAMAGE. |
|
| DAMAGE. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
||||||
| Portions created by Lukas Gebauer are Copyright (c)2005-2008. |
|
| Portions created by Lukas Gebauer are Copyright (c)2005-2012. |
|
||||||
|
| Portions created by Petr Fejfar are Copyright (c)2011-2012. |
|
||||||
| All Rights Reserved. |
|
| All Rights Reserved. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Contributor(s): |
|
| Contributor(s): |
|
||||||
@ -139,10 +140,14 @@ type
|
|||||||
{:See @inherited}
|
{:See @inherited}
|
||||||
function GetPeerSubject: string; override;
|
function GetPeerSubject: string; override;
|
||||||
{:See @inherited}
|
{:See @inherited}
|
||||||
|
function GetPeerSerialNo: integer; override; {pf}
|
||||||
|
{:See @inherited}
|
||||||
function GetPeerIssuer: string; override;
|
function GetPeerIssuer: string; override;
|
||||||
{:See @inherited}
|
{:See @inherited}
|
||||||
function GetPeerName: string; override;
|
function GetPeerName: string; override;
|
||||||
{:See @inherited}
|
{:See @inherited}
|
||||||
|
function GetPeerNameHash: cardinal; override; {pf}
|
||||||
|
{:See @inherited}
|
||||||
function GetPeerFingerprint: string; override;
|
function GetPeerFingerprint: string; override;
|
||||||
{:See @inherited}
|
{:See @inherited}
|
||||||
function GetCertInfo: string; override;
|
function GetCertInfo: string; override;
|
||||||
@ -331,10 +336,18 @@ begin
|
|||||||
cert := nil;
|
cert := nil;
|
||||||
pkey := nil;
|
pkey := nil;
|
||||||
ca := nil;
|
ca := nil;
|
||||||
|
try {pf}
|
||||||
if PKCS12parse(p12, FKeyPassword, pkey, cert, ca) > 0 then
|
if PKCS12parse(p12, FKeyPassword, pkey, cert, ca) > 0 then
|
||||||
if SSLCTXusecertificate(Fctx, cert) > 0 then
|
if SSLCTXusecertificate(Fctx, cert) > 0 then
|
||||||
if SSLCTXusePrivateKey(Fctx, pkey) > 0 then
|
if SSLCTXusePrivateKey(Fctx, pkey) > 0 then
|
||||||
Result := True;
|
Result := True;
|
||||||
|
{pf}
|
||||||
|
finally
|
||||||
|
EvpPkeyFree(pkey);
|
||||||
|
X509free(cert);
|
||||||
|
SkX509PopFree(ca,_X509Free); // for ca=nil a new STACK was allocated...
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
finally
|
finally
|
||||||
PKCS12free(p12);
|
PKCS12free(p12);
|
||||||
end;
|
end;
|
||||||
@ -622,8 +635,11 @@ begin
|
|||||||
err := SslGetError(FSsl, Result);
|
err := SslGetError(FSsl, Result);
|
||||||
until (err <> SSL_ERROR_WANT_READ) and (err <> SSL_ERROR_WANT_WRITE);
|
until (err <> SSL_ERROR_WANT_READ) and (err <> SSL_ERROR_WANT_WRITE);
|
||||||
if err = SSL_ERROR_ZERO_RETURN then
|
if err = SSL_ERROR_ZERO_RETURN then
|
||||||
Result := 0;
|
Result := 0
|
||||||
if (err <> 0) then
|
{pf}// Verze 1.1.0 byla s else tak jak to ted mam,
|
||||||
|
// ve verzi 1.1.1 bylo ELSE zruseno, ale pak je SSL_ERROR_ZERO_RETURN
|
||||||
|
// propagovano jako Chyba.
|
||||||
|
{pf} else {/pf} if (err <> 0) then
|
||||||
FLastError := err;
|
FLastError := err;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -669,6 +685,31 @@ begin
|
|||||||
X509Free(cert);
|
X509Free(cert);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TSSLOpenSSL.GetPeerSerialNo: integer; {pf}
|
||||||
|
var
|
||||||
|
cert: PX509;
|
||||||
|
SN: PASN1_INTEGER;
|
||||||
|
begin
|
||||||
|
if not assigned(FSsl) then
|
||||||
|
begin
|
||||||
|
Result := -1;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
cert := SSLGetPeerCertificate(Fssl);
|
||||||
|
try
|
||||||
|
if not assigned(cert) then
|
||||||
|
begin
|
||||||
|
Result := -1;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
SN := X509GetSerialNumber(cert);
|
||||||
|
Result := Asn1IntegerGet(SN);
|
||||||
|
finally
|
||||||
|
X509Free(cert);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TSSLOpenSSL.GetPeerName: string;
|
function TSSLOpenSSL.GetPeerName: string;
|
||||||
var
|
var
|
||||||
s: ansistring;
|
s: ansistring;
|
||||||
@ -678,6 +719,28 @@ begin
|
|||||||
Result := Trim(SeparateLeft(s, '/'));
|
Result := Trim(SeparateLeft(s, '/'));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TSSLOpenSSL.GetPeerNameHash: cardinal; {pf}
|
||||||
|
var
|
||||||
|
cert: PX509;
|
||||||
|
begin
|
||||||
|
if not assigned(FSsl) then
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
cert := SSLGetPeerCertificate(Fssl);
|
||||||
|
try
|
||||||
|
if not assigned(cert) then
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
Result := X509NameHash(X509GetSubjectName(cert));
|
||||||
|
finally
|
||||||
|
X509Free(cert);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TSSLOpenSSL.GetPeerIssuer: string;
|
function TSSLOpenSSL.GetPeerIssuer: string;
|
||||||
var
|
var
|
||||||
cert: PX509;
|
cert: PX509;
|
||||||
@ -760,11 +823,12 @@ begin
|
|||||||
Result := '';
|
Result := '';
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
try {pf}
|
||||||
b := BioNew(BioSMem);
|
b := BioNew(BioSMem);
|
||||||
try
|
try
|
||||||
X509Print(b, cert);
|
X509Print(b, cert);
|
||||||
x := bioctrlpending(b);
|
x := bioctrlpending(b);
|
||||||
{$IFDEF CIL}
|
{$IFDEF CIL}
|
||||||
sb := StringBuilder.Create(x);
|
sb := StringBuilder.Create(x);
|
||||||
y := bioread(b, sb, x);
|
y := bioread(b, sb, x);
|
||||||
if y > 0 then
|
if y > 0 then
|
||||||
@ -772,16 +836,21 @@ begin
|
|||||||
sb.Length := y;
|
sb.Length := y;
|
||||||
s := sb.ToString;
|
s := sb.ToString;
|
||||||
end;
|
end;
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
setlength(s,x);
|
setlength(s,x);
|
||||||
y := bioread(b,s,x);
|
y := bioread(b,s,x);
|
||||||
if y > 0 then
|
if y > 0 then
|
||||||
setlength(s, y);
|
setlength(s, y);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Result := ReplaceString(s, LF, CRLF);
|
Result := ReplaceString(s, LF, CRLF);
|
||||||
finally
|
finally
|
||||||
BioFreeAll(b);
|
BioFreeAll(b);
|
||||||
end;
|
end;
|
||||||
|
{pf}
|
||||||
|
finally
|
||||||
|
X509Free(cert);
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSSLOpenSSL.GetCipherName: string;
|
function TSSLOpenSSL.GetCipherName: string;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{==============================================================================|
|
{==============================================================================|
|
||||||
| Project : Ararat Synapse | 003.006.003 |
|
| Project : Ararat Synapse | 003.007.000 |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Content: SSL support by OpenSSL |
|
| Content: SSL support by OpenSSL |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Copyright (c)1999-2011, Lukas Gebauer |
|
| Copyright (c)1999-2012, Lukas Gebauer |
|
||||||
| All rights reserved. |
|
| All rights reserved. |
|
||||||
| |
|
| |
|
||||||
| Redistribution and use in source and binary forms, with or without |
|
| Redistribution and use in source and binary forms, with or without |
|
||||||
@ -33,7 +33,8 @@
|
|||||||
| DAMAGE. |
|
| DAMAGE. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
||||||
| Portions created by Lukas Gebauer are Copyright (c)2002-2011. |
|
| Portions created by Lukas Gebauer are Copyright (c)2002-2012. |
|
||||||
|
| Portions created by Petr Fejfar are Copyright (c)2011-2012. |
|
||||||
| All Rights Reserved. |
|
| All Rights Reserved. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Contributor(s): |
|
| Contributor(s): |
|
||||||
@ -143,6 +144,9 @@ type
|
|||||||
PASN1_INTEGER = SslPtr;
|
PASN1_INTEGER = SslPtr;
|
||||||
PPasswdCb = SslPtr;
|
PPasswdCb = SslPtr;
|
||||||
PFunction = procedure;
|
PFunction = procedure;
|
||||||
|
PSTACK = SslPtr; {pf}
|
||||||
|
TSkPopFreeFunc = procedure(p:SslPtr); cdecl; {pf}
|
||||||
|
TX509Free = procedure(x: PX509); cdecl; {pf}
|
||||||
|
|
||||||
DES_cblock = array[0..7] of Byte;
|
DES_cblock = array[0..7] of Byte;
|
||||||
PDES_cblock = ^DES_cblock;
|
PDES_cblock = ^DES_cblock;
|
||||||
@ -770,7 +774,13 @@ var
|
|||||||
function Asn1UtctimeNew: PASN1_UTCTIME;
|
function Asn1UtctimeNew: PASN1_UTCTIME;
|
||||||
procedure Asn1UtctimeFree(a: PASN1_UTCTIME);
|
procedure Asn1UtctimeFree(a: PASN1_UTCTIME);
|
||||||
function Asn1IntegerSet(a: PASN1_INTEGER; v: integer): integer;
|
function Asn1IntegerSet(a: PASN1_INTEGER; v: integer): integer;
|
||||||
|
function Asn1IntegerGet(a: PASN1_INTEGER): integer; {pf}
|
||||||
function i2dX509bio(b: PBIO; x: PX509): integer;
|
function i2dX509bio(b: PBIO; x: PX509): integer;
|
||||||
|
function d2iX509bio(b:PBIO; x:PX509): PX509; {pf}
|
||||||
|
function PEMReadBioX509(b:PBIO; {var x:PX509;}x:PSslPtr; callback:PFunction; cb_arg: SslPtr): PX509; {pf}
|
||||||
|
procedure SkX509PopFree(st: PSTACK; func: TSkPopFreeFunc); {pf}
|
||||||
|
|
||||||
|
|
||||||
function i2dPrivateKeyBio(b: PBIO; pkey: EVP_PKEY): integer;
|
function i2dPrivateKeyBio(b: PBIO; pkey: EVP_PKEY): integer;
|
||||||
|
|
||||||
// 3DES functions
|
// 3DES functions
|
||||||
@ -784,6 +794,9 @@ function IsSSLloaded: Boolean;
|
|||||||
function InitSSLInterface: Boolean;
|
function InitSSLInterface: Boolean;
|
||||||
function DestroySSLInterface: Boolean;
|
function DestroySSLInterface: Boolean;
|
||||||
|
|
||||||
|
var
|
||||||
|
_X509Free: TX509Free = nil; {pf}
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses SyncObjs;
|
uses SyncObjs;
|
||||||
@ -836,7 +849,6 @@ type
|
|||||||
|
|
||||||
// libeay.dll
|
// libeay.dll
|
||||||
TX509New = function: PX509; cdecl;
|
TX509New = function: PX509; cdecl;
|
||||||
TX509Free = procedure(x: PX509); cdecl;
|
|
||||||
TX509NameOneline = function(a: PX509_NAME; buf: PAnsiChar; size: Integer):PAnsiChar; cdecl;
|
TX509NameOneline = function(a: PX509_NAME; buf: PAnsiChar; size: Integer):PAnsiChar; cdecl;
|
||||||
TX509GetSubjectName = function(a: PX509):PX509_NAME; cdecl;
|
TX509GetSubjectName = function(a: PX509):PX509_NAME; cdecl;
|
||||||
TX509GetIssuerName = function(a: PX509):PX509_NAME; cdecl;
|
TX509GetIssuerName = function(a: PX509):PX509_NAME; cdecl;
|
||||||
@ -880,7 +892,11 @@ type
|
|||||||
TAsn1UtctimeNew = function: PASN1_UTCTIME; cdecl;
|
TAsn1UtctimeNew = function: PASN1_UTCTIME; cdecl;
|
||||||
TAsn1UtctimeFree = procedure(a: PASN1_UTCTIME); cdecl;
|
TAsn1UtctimeFree = procedure(a: PASN1_UTCTIME); cdecl;
|
||||||
TAsn1IntegerSet = function(a: PASN1_INTEGER; v: integer): integer; cdecl;
|
TAsn1IntegerSet = function(a: PASN1_INTEGER; v: integer): integer; cdecl;
|
||||||
|
TAsn1IntegerGet = function(a: PASN1_INTEGER): integer; cdecl; {pf}
|
||||||
Ti2dX509bio = function(b: PBIO; x: PX509): integer; cdecl;
|
Ti2dX509bio = function(b: PBIO; x: PX509): integer; cdecl;
|
||||||
|
Td2iX509bio = function(b:PBIO; x:PX509): PX509; cdecl; {pf}
|
||||||
|
TPEMReadBioX509 = function(b:PBIO; {var x:PX509;}x:PSslPtr; callback:PFunction; cb_arg:SslPtr): PX509; cdecl; {pf}
|
||||||
|
TSkX509PopFree = procedure(st: PSTACK; func: TSkPopFreeFunc); cdecl; {pf}
|
||||||
Ti2dPrivateKeyBio= function(b: PBIO; pkey: EVP_PKEY): integer; cdecl;
|
Ti2dPrivateKeyBio= function(b: PBIO; pkey: EVP_PKEY): integer; cdecl;
|
||||||
|
|
||||||
// 3DES functions
|
// 3DES functions
|
||||||
@ -936,7 +952,6 @@ var
|
|||||||
|
|
||||||
// libeay.dll
|
// libeay.dll
|
||||||
_X509New: TX509New = nil;
|
_X509New: TX509New = nil;
|
||||||
_X509Free: TX509Free = nil;
|
|
||||||
_X509NameOneline: TX509NameOneline = nil;
|
_X509NameOneline: TX509NameOneline = nil;
|
||||||
_X509GetSubjectName: TX509GetSubjectName = nil;
|
_X509GetSubjectName: TX509GetSubjectName = nil;
|
||||||
_X509GetIssuerName: TX509GetIssuerName = nil;
|
_X509GetIssuerName: TX509GetIssuerName = nil;
|
||||||
@ -979,7 +994,11 @@ var
|
|||||||
_Asn1UtctimeNew: TAsn1UtctimeNew = nil;
|
_Asn1UtctimeNew: TAsn1UtctimeNew = nil;
|
||||||
_Asn1UtctimeFree: TAsn1UtctimeFree = nil;
|
_Asn1UtctimeFree: TAsn1UtctimeFree = nil;
|
||||||
_Asn1IntegerSet: TAsn1IntegerSet = nil;
|
_Asn1IntegerSet: TAsn1IntegerSet = nil;
|
||||||
|
_Asn1IntegerGet: TAsn1IntegerGet = nil; {pf}
|
||||||
_i2dX509bio: Ti2dX509bio = nil;
|
_i2dX509bio: Ti2dX509bio = nil;
|
||||||
|
_d2iX509bio: Td2iX509bio = nil; {pf}
|
||||||
|
_PEMReadBioX509: TPEMReadBioX509 = nil; {pf}
|
||||||
|
_SkX509PopFree: TSkX509PopFree = nil; {pf}
|
||||||
_i2dPrivateKeyBio: Ti2dPrivateKeyBio = nil;
|
_i2dPrivateKeyBio: Ti2dPrivateKeyBio = nil;
|
||||||
|
|
||||||
// 3DES functions
|
// 3DES functions
|
||||||
@ -1640,6 +1659,28 @@ begin
|
|||||||
Result := 0;
|
Result := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function d2iX509bio(b: PBIO; x: PX509): PX509; {pf}
|
||||||
|
begin
|
||||||
|
if InitSSLInterface and Assigned(_d2iX509bio) then
|
||||||
|
Result := _d2iX509bio(x,b)
|
||||||
|
else
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function PEMReadBioX509(b:PBIO; {var x:PX509;}x:PSslPtr; callback:PFunction; cb_arg: SslPtr): PX509; {pf}
|
||||||
|
begin
|
||||||
|
if InitSSLInterface and Assigned(_PEMReadBioX509) then
|
||||||
|
Result := _PEMReadBioX509(b,x,callback,cb_arg)
|
||||||
|
else
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SkX509PopFree(st: PSTACK; func:TSkPopFreeFunc); {pf}
|
||||||
|
begin
|
||||||
|
if InitSSLInterface and Assigned(_SkX509PopFree) then
|
||||||
|
_SkX509PopFree(st,func);
|
||||||
|
end;
|
||||||
|
|
||||||
function i2dPrivateKeyBio(b: PBIO; pkey: EVP_PKEY): integer;
|
function i2dPrivateKeyBio(b: PBIO; pkey: EVP_PKEY): integer;
|
||||||
begin
|
begin
|
||||||
if InitSSLInterface and Assigned(_i2dPrivateKeyBio) then
|
if InitSSLInterface and Assigned(_i2dPrivateKeyBio) then
|
||||||
@ -1664,6 +1705,14 @@ begin
|
|||||||
Result := 0;
|
Result := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function Asn1IntegerGet(a: PASN1_INTEGER): integer; {pf}
|
||||||
|
begin
|
||||||
|
if InitSSLInterface and Assigned(_Asn1IntegerGet) then
|
||||||
|
Result := _Asn1IntegerGet(a)
|
||||||
|
else
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
function X509GetSerialNumber(x: PX509): PASN1_INTEGER;
|
function X509GetSerialNumber(x: PX509): PASN1_INTEGER;
|
||||||
begin
|
begin
|
||||||
if InitSSLInterface and Assigned(_X509GetSerialNumber) then
|
if InitSSLInterface and Assigned(_X509GetSerialNumber) then
|
||||||
@ -1748,6 +1797,13 @@ var
|
|||||||
s: string;
|
s: string;
|
||||||
x: integer;
|
x: integer;
|
||||||
begin
|
begin
|
||||||
|
{pf}
|
||||||
|
if SSLLoaded then
|
||||||
|
begin
|
||||||
|
Result := TRUE;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
SSLCS.Enter;
|
SSLCS.Enter;
|
||||||
try
|
try
|
||||||
if not IsSSLloaded then
|
if not IsSSLloaded then
|
||||||
@ -1853,7 +1909,11 @@ begin
|
|||||||
_Asn1UtctimeNew := GetProcAddr(SSLUtilHandle, 'ASN1_UTCTIME_new');
|
_Asn1UtctimeNew := GetProcAddr(SSLUtilHandle, 'ASN1_UTCTIME_new');
|
||||||
_Asn1UtctimeFree := GetProcAddr(SSLUtilHandle, 'ASN1_UTCTIME_free');
|
_Asn1UtctimeFree := GetProcAddr(SSLUtilHandle, 'ASN1_UTCTIME_free');
|
||||||
_Asn1IntegerSet := GetProcAddr(SSLUtilHandle, 'ASN1_INTEGER_set');
|
_Asn1IntegerSet := GetProcAddr(SSLUtilHandle, 'ASN1_INTEGER_set');
|
||||||
|
_Asn1IntegerGet := GetProcAddr(SSLUtilHandle, 'ASN1_INTEGER_get'); {pf}
|
||||||
_i2dX509bio := GetProcAddr(SSLUtilHandle, 'i2d_X509_bio');
|
_i2dX509bio := GetProcAddr(SSLUtilHandle, 'i2d_X509_bio');
|
||||||
|
_d2iX509bio := GetProcAddr(SSLUtilHandle, 'd2i_X509_bio'); {pf}
|
||||||
|
_PEMReadBioX509 := GetProcAddr(SSLUtilHandle, 'PEM_read_bio_X509'); {pf}
|
||||||
|
_SkX509PopFree := GetProcAddr(SSLUtilHandle, 'SK_X509_POP_FREE'); {pf}
|
||||||
_i2dPrivateKeyBio := GetProcAddr(SSLUtilHandle, 'i2d_PrivateKey_bio');
|
_i2dPrivateKeyBio := GetProcAddr(SSLUtilHandle, 'i2d_PrivateKey_bio');
|
||||||
|
|
||||||
// 3DES functions
|
// 3DES functions
|
||||||
@ -2038,6 +2098,8 @@ begin
|
|||||||
_Asn1UtctimeNew := nil;
|
_Asn1UtctimeNew := nil;
|
||||||
_Asn1UtctimeFree := nil;
|
_Asn1UtctimeFree := nil;
|
||||||
_Asn1IntegerSet := nil;
|
_Asn1IntegerSet := nil;
|
||||||
|
_Asn1IntegerGet := nil; {pf}
|
||||||
|
_SkX509PopFree := nil; {pf}
|
||||||
_i2dX509bio := nil;
|
_i2dX509bio := nil;
|
||||||
_i2dPrivateKeyBio := nil;
|
_i2dPrivateKeyBio := nil;
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Content: Coding and decoding support |
|
| Content: Coding and decoding support |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Copyright (c)1999-2010, Lukas Gebauer |
|
| Copyright (c)1999-2012, Lukas Gebauer |
|
||||||
| All rights reserved. |
|
| All rights reserved. |
|
||||||
| |
|
| |
|
||||||
| Redistribution and use in source and binary forms, with or without |
|
| Redistribution and use in source and binary forms, with or without |
|
||||||
@ -33,7 +33,7 @@
|
|||||||
| DAMAGE. |
|
| DAMAGE. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
||||||
| Portions created by Lukas Gebauer are Copyright (c)2000-2010. |
|
| Portions created by Lukas Gebauer are Copyright (c)2000-2012. |
|
||||||
| All Rights Reserved. |
|
| All Rights Reserved. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Contributor(s): |
|
| Contributor(s): |
|
||||||
@ -49,6 +49,7 @@
|
|||||||
{$Q-}
|
{$Q-}
|
||||||
{$R-}
|
{$R-}
|
||||||
{$H+}
|
{$H+}
|
||||||
|
{$TYPEDADDRESS OFF}
|
||||||
|
|
||||||
{$IFDEF UNICODE}
|
{$IFDEF UNICODE}
|
||||||
{$WARN IMPLICIT_STRING_CAST OFF}
|
{$WARN IMPLICIT_STRING_CAST OFF}
|
||||||
|
@ -57,6 +57,8 @@
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$TYPEDADDRESS OFF}
|
||||||
|
|
||||||
{$IFDEF UNICODE}
|
{$IFDEF UNICODE}
|
||||||
{$WARN IMPLICIT_STRING_CAST OFF}
|
{$WARN IMPLICIT_STRING_CAST OFF}
|
||||||
{$WARN IMPLICIT_STRING_CAST_LOSS OFF}
|
{$WARN IMPLICIT_STRING_CAST_LOSS OFF}
|
||||||
|
236
synautil.pas
236
synautil.pas
@ -1,9 +1,9 @@
|
|||||||
{==============================================================================|
|
{==============================================================================|
|
||||||
| Project : Ararat Synapse | 004.014.001 |
|
| Project : Ararat Synapse | 004.015.000 |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Content: support procedures and functions |
|
| Content: support procedures and functions |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Copyright (c)1999-2010, Lukas Gebauer |
|
| Copyright (c)1999-2012, Lukas Gebauer |
|
||||||
| All rights reserved. |
|
| All rights reserved. |
|
||||||
| |
|
| |
|
||||||
| Redistribution and use in source and binary forms, with or without |
|
| Redistribution and use in source and binary forms, with or without |
|
||||||
@ -33,8 +33,9 @@
|
|||||||
| DAMAGE. |
|
| DAMAGE. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
||||||
| Portions created by Lukas Gebauer are Copyright (c) 1999-2010. |
|
| Portions created by Lukas Gebauer are Copyright (c) 1999-2012. |
|
||||||
| Portions created by Hernan Sanchez are Copyright (c) 2000. |
|
| Portions created by Hernan Sanchez are Copyright (c) 2000. |
|
||||||
|
| Portions created by Petr Fejfar are Copyright (c)2011-2012. |
|
||||||
| All Rights Reserved. |
|
| All Rights Reserved. |
|
||||||
|==============================================================================|
|
|==============================================================================|
|
||||||
| Contributor(s): |
|
| Contributor(s): |
|
||||||
@ -331,6 +332,34 @@ function XorString(Indata1, Indata2: AnsiString): AnsiString;
|
|||||||
is Splitted into multiple lines, then this procedure de-split it into one line.}
|
is Splitted into multiple lines, then this procedure de-split it into one line.}
|
||||||
function NormalizeHeader(Value: TStrings; var Index: Integer): string;
|
function NormalizeHeader(Value: TStrings; var Index: Integer): string;
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
{:Search for one of line terminators CR, LF or NUL. Return position of the
|
||||||
|
line beginning and length of text.}
|
||||||
|
procedure SearchForLineBreak(var APtr:PANSIChar; AEtx:PANSIChar; out ABol:PANSIChar; out ALength:integer);
|
||||||
|
{:Skip both line terminators CR LF (if any). Move APtr position forward.}
|
||||||
|
procedure SkipLineBreak(var APtr:PANSIChar; AEtx:PANSIChar);
|
||||||
|
{:Skip all blank lines in a buffer starting at APtr and move APtr position forward.}
|
||||||
|
procedure SkipNullLines (var APtr:PANSIChar; AEtx:PANSIChar);
|
||||||
|
{:Copy all lines from a buffer starting at APtr to ALines until empty line
|
||||||
|
or end of the buffer is reached. Move APtr position forward).}
|
||||||
|
procedure CopyLinesFromStreamUntilNullLine(var APtr:PANSIChar; AEtx:PANSIChar; ALines:TStrings);
|
||||||
|
{:Copy all lines from a buffer starting at APtr to ALines until ABoundary
|
||||||
|
or end of the buffer is reached. Move APtr position forward).}
|
||||||
|
procedure CopyLinesFromStreamUntilBoundary(var APtr:PANSIChar; AEtx:PANSIChar; ALines:TStrings; const ABoundary:ANSIString);
|
||||||
|
{:Search ABoundary in a buffer starting at APtr.
|
||||||
|
Return beginning of the ABoundary. Move APtr forward behind a trailing CRLF if any).}
|
||||||
|
function SearchForBoundary (var APtr:PANSIChar; AEtx:PANSIChar; const ABoundary:ANSIString): PANSIChar;
|
||||||
|
{:Compare a text at position ABOL with ABoundary and return position behind the
|
||||||
|
match (including a trailing CRLF if any).}
|
||||||
|
function MatchBoundary (ABOL,AETX:PANSIChar; const ABoundary:ANSIString): PANSIChar;
|
||||||
|
{:Compare a text at position ABOL with ABoundary + the last boundary suffix
|
||||||
|
and return position behind the match (including a trailing CRLF if any).}
|
||||||
|
function MatchLastBoundary (ABOL,AETX:PANSIChar; const ABoundary:ANSIString): PANSIChar;
|
||||||
|
{:Copy data from a buffer starting at position APtr and delimited by AEtx
|
||||||
|
position into ANSIString.}
|
||||||
|
function BuildStringFromBuffer (AStx,AEtx:PANSIChar): ANSIString;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
var
|
var
|
||||||
{:can be used for your own months strings for @link(getmonthnumber)}
|
{:can be used for your own months strings for @link(getmonthnumber)}
|
||||||
CustomMonthNames: array[1..12] of string;
|
CustomMonthNames: array[1..12] of string;
|
||||||
@ -1823,6 +1852,207 @@ begin
|
|||||||
Result := TrimRight(s);
|
Result := TrimRight(s);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{==============================================================================}
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
procedure SearchForLineBreak(var APtr:PANSIChar; AEtx:PANSIChar; out ABol:PANSIChar; out ALength:integer);
|
||||||
|
begin
|
||||||
|
ABol := APtr;
|
||||||
|
while (APtr<AEtx) and not (APtr^ in [#0,#10,#13]) do
|
||||||
|
inc(APtr);
|
||||||
|
ALength := APtr-ABol;
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
procedure SkipLineBreak(var APtr:PANSIChar; AEtx:PANSIChar);
|
||||||
|
begin
|
||||||
|
if (APtr<AEtx) and (APtr^=#13) then
|
||||||
|
inc(APtr);
|
||||||
|
if (APtr<AEtx) and (APtr^=#10) then
|
||||||
|
inc(APtr);
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
procedure SkipNullLines(var APtr:PANSIChar; AEtx:PANSIChar);
|
||||||
|
var
|
||||||
|
bol: PANSIChar;
|
||||||
|
lng: integer;
|
||||||
|
begin
|
||||||
|
while (APtr<AEtx) do
|
||||||
|
begin
|
||||||
|
SearchForLineBreak(APtr,AEtx,bol,lng);
|
||||||
|
SkipLineBreak(APtr,AEtx);
|
||||||
|
if lng>0 then
|
||||||
|
begin
|
||||||
|
APtr := bol;
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
procedure CopyLinesFromStreamUntilNullLine(var APtr:PANSIChar; AEtx:PANSIChar; ALines:TStrings);
|
||||||
|
var
|
||||||
|
bol: PANSIChar;
|
||||||
|
lng: integer;
|
||||||
|
s: ANSIString;
|
||||||
|
begin
|
||||||
|
// Copying until body separator will be reached
|
||||||
|
while (APtr<AEtx) and (APtr^<>#0) do
|
||||||
|
begin
|
||||||
|
SearchForLineBreak(APtr,AEtx,bol,lng);
|
||||||
|
SkipLineBreak(APtr,AEtx);
|
||||||
|
if lng=0 then
|
||||||
|
Break;
|
||||||
|
SetString(s,bol,lng);
|
||||||
|
ALines.Add(s);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
procedure CopyLinesFromStreamUntilBoundary(var APtr:PANSIChar; AEtx:PANSIChar; ALines:TStrings; const ABoundary:ANSIString);
|
||||||
|
var
|
||||||
|
bol: PANSIChar;
|
||||||
|
lng: integer;
|
||||||
|
s: ANSIString;
|
||||||
|
BackStop: ANSIString;
|
||||||
|
eob1: PANSIChar;
|
||||||
|
eob2: PANSIChar;
|
||||||
|
begin
|
||||||
|
BackStop := '--'+ABoundary;
|
||||||
|
eob2 := nil;
|
||||||
|
// Copying until Boundary will be reached
|
||||||
|
while (APtr<AEtx) do
|
||||||
|
begin
|
||||||
|
SearchForLineBreak(APtr,AEtx,bol,lng);
|
||||||
|
SkipLineBreak(APtr,AEtx);
|
||||||
|
eob1 := MatchBoundary(bol,APtr,ABoundary);
|
||||||
|
if Assigned(eob1) then
|
||||||
|
eob2 := MatchLastBoundary(bol,AEtx,ABoundary);
|
||||||
|
if Assigned(eob2) then
|
||||||
|
begin
|
||||||
|
APtr := eob2;
|
||||||
|
Break;
|
||||||
|
end
|
||||||
|
else if Assigned(eob1) then
|
||||||
|
begin
|
||||||
|
APtr := eob1;
|
||||||
|
Break;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
SetString(s,bol,lng);
|
||||||
|
ALines.Add(s);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
function SearchForBoundary(var APtr:PANSIChar; AEtx:PANSIChar; const ABoundary:ANSIString): PANSIChar;
|
||||||
|
var
|
||||||
|
eob: PANSIChar;
|
||||||
|
Step: integer;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
// Moving Aptr position forward until boundary will be reached
|
||||||
|
while (APtr<AEtx) do
|
||||||
|
begin
|
||||||
|
if strlcomp(APtr,#13#10'--',4)=0 then
|
||||||
|
begin
|
||||||
|
eob := MatchBoundary(APtr,AEtx,ABoundary);
|
||||||
|
Step := 4;
|
||||||
|
end
|
||||||
|
else if strlcomp(APtr,'--',2)=0 then
|
||||||
|
begin
|
||||||
|
eob := MatchBoundary(APtr,AEtx,ABoundary);
|
||||||
|
Step := 2;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
eob := nil;
|
||||||
|
Step := 1;
|
||||||
|
end;
|
||||||
|
if Assigned(eob) then
|
||||||
|
begin
|
||||||
|
Result := APtr; // boundary beginning
|
||||||
|
APtr := eob; // boundary end
|
||||||
|
exit;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
inc(APtr,Step);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
function MatchBoundary(ABol,AEtx:PANSIChar; const ABoundary:ANSIString): PANSIChar;
|
||||||
|
var
|
||||||
|
MatchPos: PANSIChar;
|
||||||
|
Lng: integer;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
MatchPos := ABol;
|
||||||
|
Lng := length(ABoundary);
|
||||||
|
if (MatchPos+2+Lng)>AETX then
|
||||||
|
exit;
|
||||||
|
if strlcomp(MatchPos,#13#10,2)=0 then
|
||||||
|
inc(MatchPos,2);
|
||||||
|
if (MatchPos+2+Lng)>AETX then
|
||||||
|
exit;
|
||||||
|
if strlcomp(MatchPos,'--',2)<>0 then
|
||||||
|
exit;
|
||||||
|
inc(MatchPos,2);
|
||||||
|
if strlcomp(MatchPos,PANSIChar(ABoundary),Lng)<>0 then
|
||||||
|
exit;
|
||||||
|
inc(MatchPos,Lng);
|
||||||
|
if ((MatchPos+2)<=AEtx) and (strlcomp(MatchPos,#13#10,2)=0) then
|
||||||
|
inc(MatchPos,2);
|
||||||
|
Result := MatchPos;
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
function MatchLastBoundary(ABOL,AETX:PANSIChar; const ABoundary:ANSIString): PANSIChar;
|
||||||
|
var
|
||||||
|
MatchPos: PANSIChar;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
MatchPos := MatchBoundary(ABOL,AETX,ABoundary);
|
||||||
|
if not Assigned(MatchPos) then
|
||||||
|
exit;
|
||||||
|
if strlcomp(MatchPos,'--',2)<>0 then
|
||||||
|
exit;
|
||||||
|
inc(MatchPos,2);
|
||||||
|
if (MatchPos+2<=AEtx) and (strlcomp(MatchPos,#13#10,2)=0) then
|
||||||
|
inc(MatchPos,2);
|
||||||
|
Result := MatchPos;
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
|
{pf}
|
||||||
|
function BuildStringFromBuffer(AStx,AEtx:PANSIChar): ANSIString;
|
||||||
|
var
|
||||||
|
lng: integer;
|
||||||
|
begin
|
||||||
|
Lng := 0;
|
||||||
|
if Assigned(AStx) and Assigned(AEtx) then
|
||||||
|
begin
|
||||||
|
Lng := AEtx-AStx;
|
||||||
|
if Lng<0 then
|
||||||
|
Lng := 0;
|
||||||
|
end;
|
||||||
|
SetString(Result,AStx,lng);
|
||||||
|
end;
|
||||||
|
{/pf}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{==============================================================================}
|
{==============================================================================}
|
||||||
var
|
var
|
||||||
n: integer;
|
n: integer;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user