Skip to content

Commit 7872f84

Browse files
committed
Updating IdFIPS unit in main Indy library to allow IndyTLSOpenSSL package to use OpenSSL when creating NTLM challenge responses.
Trimming IdCompilerDefines.inc to remove things IndyTLSOpenSSL doesn't use.
1 parent 8a1aee0 commit 7872f84

30 files changed

+195
-1056
lines changed

IdCompilerDefines.inc

Lines changed: 2 additions & 906 deletions
Large diffs are not rendered by default.

IdNTLMOpenSSL.pas

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
{
2+
This file is part of the Indy (Internet Direct) project, and is offered
3+
under the dual-licensing agreement described on the Indy website.
4+
(http://www.indyproject.org/)
5+
6+
Copyright:
7+
(c) 1993-2024, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
8+
}
9+
10+
unit IdNTLMOpenSSL;
11+
12+
interface
13+
14+
implementation
15+
16+
uses
17+
IdGlobal, IdFIPS, IdSSLOpenSSLHeaders, IdHashMessageDigest,
18+
SysUtils;
19+
20+
{$I IdCompilerDefines.inc}
21+
22+
function LoadOpenSSL: Boolean;
23+
begin
24+
Result := IdSSLOpenSSLHeaders.Load;
25+
end;
26+
27+
function IsNTLMFuncsAvail: Boolean;
28+
begin
29+
Result := Assigned(DES_set_odd_parity) and
30+
Assigned(DES_set_key) and
31+
Assigned(DES_ecb_encrypt);
32+
end;
33+
34+
type
35+
Pdes_key_schedule = ^des_key_schedule;
36+
37+
{/*
38+
* turns a 56 bit key into the 64 bit, odd parity key and sets the key.
39+
* The key schedule ks is also set.
40+
*/}
41+
procedure setup_des_key(key_56: des_cblock; Var ks: des_key_schedule);
42+
Var
43+
key: des_cblock;
44+
begin
45+
key[0] := key_56[0];
46+
47+
key[1] := ((key_56[0] SHL 7) and $FF) or (key_56[1] SHR 1);
48+
key[2] := ((key_56[1] SHL 6) and $FF) or (key_56[2] SHR 2);
49+
key[3] := ((key_56[2] SHL 5) and $FF) or (key_56[3] SHR 3);
50+
key[4] := ((key_56[3] SHL 4) and $FF) or (key_56[4] SHR 4);
51+
key[5] := ((key_56[4] SHL 3) and $FF) or (key_56[5] SHR 5);
52+
key[6] := ((key_56[5] SHL 2) and $FF) or (key_56[6] SHR 6);
53+
key[7] := (key_56[6] SHL 1) and $FF;
54+
55+
DES_set_odd_parity(@key);
56+
DES_set_key(@key, ks);
57+
end;
58+
59+
{/*
60+
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
61+
* 8 byte plaintext is encrypted with each key and the resulting 24
62+
* bytes are stored in the results array.
63+
*/}
64+
procedure calc_resp(keys: PDES_cblock; const ANonce: TIdBytes; results: Pdes_key_schedule);
65+
Var
66+
ks: des_key_schedule;
67+
nonce: des_cblock;
68+
begin
69+
setup_des_key(keys^, ks);
70+
Move(ANonce[0], nonce, 8);
71+
des_ecb_encrypt(@nonce, Pconst_DES_cblock(results), ks, DES_ENCRYPT);
72+
73+
setup_des_key(PDES_cblock(PtrUInt(keys) + 7)^, ks);
74+
des_ecb_encrypt(@nonce, Pconst_DES_cblock(PtrUInt(results) + 8), ks, DES_ENCRYPT);
75+
76+
setup_des_key(PDES_cblock(PtrUInt(keys) + 14)^, ks);
77+
des_ecb_encrypt(@nonce, Pconst_DES_cblock(PtrUInt(results) + 16), ks, DES_ENCRYPT);
78+
end;
79+
80+
Const
81+
Magic: des_cblock = ($4B, $47, $53, $21, $40, $23, $24, $25 );
82+
83+
//* setup LanManager password */
84+
function SetupLanManagerPassword(const APassword: String; const ANonce: TIdBytes): TIdBytes;
85+
var
86+
lm_hpw: array[0..20] of Byte;
87+
lm_pw: array[0..13] of Byte;
88+
idx, len: Integer;
89+
ks: des_key_schedule;
90+
lm_resp: array [0..23] of Byte;
91+
lPassword: {$IFDEF STRING_IS_UNICODE}TIdBytes{$ELSE}AnsiString{$ENDIF};
92+
begin
93+
{$IFDEF STRING_IS_UNICODE}
94+
lPassword := IndyTextEncoding_OSDefault.GetBytes(UpperCase(APassword));
95+
{$ELSE}
96+
lPassword := UpperCase(APassword);
97+
{$ENDIF}
98+
99+
len := IndyMin(Length(lPassword), 14);
100+
if len > 0 then begin
101+
Move(lPassword[{$IFDEF STRING_IS_UNICODE}0{$ELSE}1{$ENDIF}], lm_pw[0], len);
102+
end;
103+
if len < 14 then begin
104+
for idx := len to 13 do begin
105+
lm_pw[idx] := $0;
106+
end;
107+
end;
108+
109+
//* create LanManager hashed password */
110+
111+
setup_des_key(pdes_cblock(@lm_pw[0])^, ks);
112+
des_ecb_encrypt(@magic, Pconst_DES_cblock(@lm_hpw[0]), ks, DES_ENCRYPT);
113+
114+
setup_des_key(pdes_cblock(PtrUInt(@lm_pw[0]) + 7)^, ks);
115+
des_ecb_encrypt(@magic, Pconst_DES_cblock(PtrUInt(@lm_hpw[0]) + 8), ks, DES_ENCRYPT);
116+
117+
FillChar(lm_hpw[16], 5, 0);
118+
119+
calc_resp(PDes_cblock(@lm_hpw[0]), ANonce, Pdes_key_schedule(@lm_resp[0]));
120+
121+
SetLength(Result, SizeOf(lm_resp));
122+
Move(lm_resp[0], Result[0], SizeOf(lm_resp));
123+
end;
124+
125+
//* create NT hashed password */
126+
function CreateNTPassword(const APassword: String; const ANonce: TIdBytes): TIdBytes;
127+
var
128+
nt_hpw: array [1..21] of Byte;
129+
nt_hpw128: TIdBytes;
130+
nt_resp: array [1..24] of Byte;
131+
LMD4: TIdHashMessageDigest4;
132+
begin
133+
CheckMD4Permitted;
134+
LMD4 := TIdHashMessageDigest4.Create;
135+
try
136+
{$IFDEF STRING_IS_UNICODE}
137+
nt_hpw128 := LMD4.HashString(APassword, IndyTextEncoding_UTF16LE);
138+
{$ELSE}
139+
nt_hpw128 := LMD4.HashBytes(BuildUnicode(APassword));
140+
{$ENDIF}
141+
finally
142+
LMD4.Free;
143+
end;
144+
145+
Move(nt_hpw128[0], nt_hpw[1], 16);
146+
FillChar(nt_hpw[17], 5, 0);
147+
148+
calc_resp(pdes_cblock(@nt_hpw[1]), ANonce, Pdes_key_schedule(@nt_resp[1]));
149+
150+
SetLength(Result, SizeOf(nt_resp));
151+
Move(nt_resp[1], Result[0], SizeOf(nt_resp));
152+
end;
153+
154+
initialization
155+
IdFIPS.LoadNTLMLibrary := LoadOpenSSL;
156+
IdFIPS.IsNTLMFuncsAvail := IsNTLMFuncsAvail;
157+
IdFIPS.NTLMGetLmChallengeResponse := SetupLanManagerPassword;
158+
IdFIPS.NTLMGetNtChallengeResponse := CreateNTPassword;
159+
160+
end.

IdSSLOpenSSL.pas

Lines changed: 1 addition & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,10 @@
11
{
2-
$Project$
3-
$Workfile$
4-
$Revision$
5-
$DateUTC$
6-
$Id$
7-
82
This file is part of the Indy (Internet Direct) project, and is offered
93
under the dual-licensing agreement described on the Indy website.
104
(http://www.indyproject.org/)
115
126
Copyright:
13-
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
14-
}
15-
{
16-
$Log$
17-
}
18-
{
19-
Rev 1.40 03/11/2009 09:04:00 AWinkelsdorf
20-
Implemented fix for Vista+ SSL_Read and SSL_Write to allow connection
21-
timeout.
22-
23-
Rev 1.39 16/02/2005 23:26:08 CCostelloe
24-
Changed OnVerifyPeer. Breaks existing implementation of OnVerifyPeer. See
25-
long comment near top of file.
26-
27-
Rev 1.38 1/31/05 6:02:28 PM RLebeau
28-
Updated _GetThreadId() callback to reflect changes in IdGlobal unit
29-
30-
Rev 1.37 7/27/2004 1:54:26 AM JPMugaas
31-
Now should use the Intercept property for sends.
32-
33-
Rev 1.36 2004-05-18 21:38:36 Mattias
34-
Fixed unload bug
35-
36-
Rev 1.35 2004-05-07 16:34:26 Mattias
37-
Implemented OpenSSL locking callbacks
38-
39-
Rev 1.34 27/04/2004 9:38:48 HHariri
40-
Added compiler directive so it works in BCB
41-
42-
Rev 1.33 4/26/2004 12:41:10 AM BGooijen
43-
Fixed WriteDirect
44-
45-
Rev 1.32 2004.04.08 10:55:30 PM czhower
46-
IOHandler changes.
47-
48-
Rev 1.31 3/7/2004 9:02:58 PM JPMugaas
49-
Fixed compiler warning about visibility.
50-
51-
Rev 1.30 2004.03.07 11:46:40 AM czhower
52-
Flushbuffer fix + other minor ones found
53-
54-
Rev 1.29 2/7/2004 5:50:50 AM JPMugaas
55-
Fixed Copyright.
56-
57-
Rev 1.28 2/6/2004 3:45:56 PM JPMugaas
58-
Only a start on NET porting. This is not finished and will not compile on
59-
DotNET>
60-
61-
Rev 1.27 2004.02.03 5:44:24 PM czhower
62-
Name changes
63-
64-
Rev 1.26 1/21/2004 4:03:48 PM JPMugaas
65-
InitComponent
66-
67-
Rev 1.25 1/14/2004 11:39:10 AM JPMugaas
68-
Server IOHandler now works. Accept was commented out.
69-
70-
Rev 1.24 2003.11.29 10:19:28 AM czhower
71-
Updated for core change to InputBuffer.
72-
73-
Rev 1.23 10/21/2003 10:09:14 AM JPMugaas
74-
Intercept enabled.
75-
76-
Rev 1.22 10/21/2003 09:41:38 AM JPMugaas
77-
Updated for new API. Verified with TIdFTP with active and passive transfers
78-
as well as clear and protected data channels.
79-
80-
Rev 1.21 10/21/2003 07:32:38 AM JPMugaas
81-
Checked in what I have. Porting still continues.
82-
83-
Rev 1.20 10/17/2003 1:08:08 AM DSiders
84-
Added localization comments.
85-
86-
Rev 1.19 2003.10.12 6:36:44 PM czhower
87-
Now compiles.
88-
89-
Rev 1.18 9/19/2003 11:24:58 AM JPMugaas
90-
Should compile.
91-
92-
Rev 1.17 9/18/2003 10:20:32 AM JPMugaas
93-
Updated for new API.
94-
95-
Rev 1.16 2003.07.16 3:26:52 PM czhower
96-
Fixed for a core change.
97-
98-
Rev 1.15 6/30/2003 1:52:22 PM BGooijen
99-
Changed for new buffer interface
100-
101-
Rev 1.14 6/29/2003 5:42:02 PM BGooijen
102-
fixed problem in TIdSSLIOHandlerSocketOpenSSL.SetPassThrough that Henrick
103-
Hellstrom reported
104-
105-
Rev 1.13 5/7/2003 7:13:00 PM BGooijen
106-
changed Connected to BindingAllocated in ReadFromSource
107-
108-
Rev 1.12 3/30/2003 12:16:40 AM BGooijen
109-
bugfixed+ added MakeFTPSvrPort/MakeFTPSvrPasv
110-
111-
Rev 1.11 3/14/2003 06:56:08 PM JPMugaas
112-
Added a clone method to the SSLContext.
113-
114-
Rev 1.10 3/14/2003 05:29:10 PM JPMugaas
115-
Change to prevent an AV when shutting down the FTP Server.
116-
117-
Rev 1.9 3/14/2003 10:00:38 PM BGooijen
118-
Removed TIdServerIOHandlerSSLBase.PeerPassthrough, the ssl is now enabled in
119-
the server-protocol-files
120-
121-
Rev 1.8 3/13/2003 11:55:38 AM JPMugaas
122-
Updated registration framework to give more information.
123-
124-
Rev 1.7 3/13/2003 11:07:14 AM JPMugaas
125-
OpenSSL classes renamed.
126-
127-
Rev 1.6 3/13/2003 10:28:16 AM JPMugaas
128-
Forgot the reegistration - OOPS!!!
129-
130-
Rev 1.5 3/13/2003 09:49:42 AM JPMugaas
131-
Now uses an abstract SSL base class instead of OpenSSL so 3rd-party vendors
132-
can plug-in their products.
133-
134-
Rev 1.4 3/13/2003 10:20:08 AM BGooijen
135-
Server side fibers
136-
137-
Rev 1.3 2003.02.25 3:56:22 AM czhower
138-
139-
Rev 1.2 2/5/2003 10:27:46 PM BGooijen
140-
Fixed bug in OpenEncodedConnection
141-
142-
Rev 1.1 2/4/2003 6:31:22 PM BGooijen
143-
Fixed for Indy 10
144-
145-
Rev 1.0 11/13/2002 08:01:24 AM JPMugaas
7+
(c) 1993-2024, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
1468
}
1479
unit IdSSLOpenSSL;
14810
{
@@ -201,10 +63,6 @@ interface
20163

20264
{$I IdCompilerDefines.inc}
20365

204-
{$IFNDEF USE_OPENSSL}
205-
{$message error Should not compile if USE_OPENSSL is not defined!!!}
206-
{$ENDIF}
207-
20866
{$TYPEDADDRESS OFF}
20967

21068
uses
@@ -4274,13 +4132,10 @@ function TIdSSLCipher.GetVersion:String;
42744132
Result := String(SSL_CIPHER_get_version(SSL_get_current_cipher(FSSLSocket.fSSL)));
42754133
end;
42764134

4277-
{$I IdSymbolDeprecatedOff.inc}
4278-
42794135
initialization
42804136
Assert(SSLIsLoaded=nil);
42814137
SSLIsLoaded := TIdThreadSafeBoolean.Create;
42824138

4283-
{$I IdSymbolDeprecatedOff.inc}
42844139
RegisterSSL('OpenSSL','Indy Pit Crew', {do not localize}
42854140
'Copyright '+Char(169)+' 1993 - 2023'#10#13 + {do not localize}
42864141
'Chad Z. Hower (Kudzu) and the Indy Pit Crew. All rights reserved.', {do not localize}
@@ -4289,7 +4144,6 @@ initialization
42894144
'Original Author - Gregor Ibic', {do not localize}
42904145
TIdSSLIOHandlerSocketOpenSSL,
42914146
TIdServerIOHandlerSSLOpenSSL);
4292-
{$I IdSymbolDeprecatedOn.inc}
42934147

42944148
TIdSSLIOHandlerSocketOpenSSL.RegisterIOHandler;
42954149
finalization

IdSSLOpenSSLHeaders.pas

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,6 @@ interface
155155

156156
{$I IdCompilerDefines.inc}
157157

158-
{$IFNDEF USE_OPENSSL}
159-
{$message error Should not compile if USE_OPENSSL is not defined!!!}
160-
{$ENDIF}
161158
{$WRITEABLECONST OFF}
162159

163160
{$IFNDEF FPC}
@@ -19392,6 +19389,11 @@ function OpenSSLFinalHMACInst(ACtx: TIdHMACIntCtx): TIdBytes;
1939219389
FreeMem(ACtx,SizeOf(HMAC_CTX));
1939319390
end;
1939419391

19392+
function LoadOpenSSL: Boolean;
19393+
begin
19394+
Result := Load;
19395+
end;
19396+
1939519397
//****************************************************
1939619398
function FIPS_mode_set(onoff : TIdC_INT) : TIdC_INT; {$IFDEF INLINE}inline;{$ENDIF}
1939719399
begin
@@ -26965,6 +26967,7 @@ initialization
2696526967
GetHMACSHA512HashInst:= OpenSSLGetHMACSHA512Inst;
2696626968
UpdateHMACInst := OpenSSLUpdateHMACInst;
2696726969
FinalHMACInst := OpenSSLFinalHMACInst;
26970+
LoadHashLibrary := LoadOpenSSL;
2696826971
{$IFNDEF STATICLOAD_OPENSSL}
2696926972
finalization
2697026973
FreeAndNil(FFailedLoadList);

IndyTLSOpenSSL100.dpk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ requires
2828

2929
contains
3030
IdResourceStringsOpenSSL in 'IdResourceStringsOpenSSL.pas',
31+
IdNTLMOpenSSL in 'IdNTLMOpenSSL.pas',
3132
IdSSLOpenSSL in 'IdSSLOpenSSL.pas',
3233
IdSSLOpenSSLHeaders in 'IdSSLOpenSSLHeaders.pas';
3334

IndyTLSOpenSSL110.dpk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ requires
2828

2929
contains
3030
IdResourceStringsOpenSSL in 'IdResourceStringsOpenSSL.pas',
31+
IdNTLMOpenSSL in 'IdNTLMOpenSSL.pas',
3132
IdSSLOpenSSL in 'IdSSLOpenSSL.pas',
3233
IdSSLOpenSSLHeaders in 'IdSSLOpenSSLHeaders.pas';
3334

IndyTLSOpenSSL120.dpk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ requires
2828

2929
contains
3030
IdResourceStringsOpenSSL in 'IdResourceStringsOpenSSL.pas',
31+
IdNTLMOpenSSL in 'IdNTLMOpenSSL.pas',
3132
IdSSLOpenSSL in 'IdSSLOpenSSL.pas',
3233
IdSSLOpenSSLHeaders in 'IdSSLOpenSSLHeaders.pas';
3334

0 commit comments

Comments
 (0)