1 /*
2 * h235auth.h
3 *
4 * H.235 authorisation PDU's
5 *
6 * H323Plus Library
7 *
8 * Copyright (c) 1998-2001 Equivalence Pty. Ltd.
9 *
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
14 *
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * The Original Code is Open H323 Library.
21 *
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23 *
24 * Contributor(s): F�rbass Franz <franz.fuerbass@infonova.at>
25 *
26 * $Id$
27 *
28 */
29
30 #ifndef __OPAL_H235AUTH_H
31 #define __OPAL_H235AUTH_H
32
33 #ifdef P_USE_PRAGMA
34 #pragma interface
35 #endif
36
37 class H323TransactionPDU;
38 class H225_CryptoH323Token;
39 class H225_ArrayOf_AuthenticationMechanism;
40 class H225_ArrayOf_PASN_ObjectId;
41 class H235_ClearToken;
42 class H235_AuthenticationMechanism;
43 class PASN_ObjectId;
44 class PASN_Sequence;
45 class PASN_Array;
46
47 class H323SignalPDU;
48 class H323Connection;
49 class PSSLCertificate;
50
51 #include "ptlib_extras.h"
52 #include <ptlib/pluginmgr.h>
53 #include <list>
54
55 /** This abstract class embodies an H.235 authentication mechanism.
56 NOTE: descendants must have a Clone() function for correct operation.
57 */
58 #ifdef H323_H235
59 class H235_DiffieHellman;
60 #endif
61 class H235Authenticator : public PObject
62 {
63 PCLASSINFO(H235Authenticator, PObject);
64 public:
65 H235Authenticator();
66
67 virtual void PrintOn(
68 ostream & strm
69 ) const;
70
71 static H235Authenticator * CreateAuthenticator(const PString & authname, ///< Feature Name Expression
72 PPluginManager * pluginMgr = NULL ///< Plugin Manager
73 );
74 #if PTLIB_VER >= 2110
75
76 struct Capability {
77 const char * m_identifier;
78 const char * m_cipher;
79 const char * m_description;
80 };
81
82 typedef struct {
83 std::list<Capability> capabilityList;
84 } Capabilities;
85
86 static H235Authenticator * CreateAuthenticatorByID(const PString & identifier
87 );
88
89 static PBoolean GetAuthenticatorCapabilities(const PString & deviceName,
90 Capabilities * caps,
91 PPluginManager * pluginMgr = NULL);
92 #endif
93
94 #ifdef H323_H235
95
96 virtual PBoolean GetMediaSessionInfo(PString & algorithmOID, PBYTEArray & sessionKey);
97 #endif
98
99 virtual const char * GetName() const = 0;
100
101 static PStringArray GetAuthenticatorList();
102
IsMatch(const PString &)103 virtual PBoolean IsMatch(const PString & /*identifier*/) const { return false; }
104
105 virtual PBoolean PrepareTokens(
106 PASN_Array & clearTokens,
107 PASN_Array & cryptoTokens
108 );
109
110 virtual PBoolean PrepareTokens(
111 PASN_Array & clearTokens,
112 PASN_Array & cryptoTokens,
113 PINDEX max_cipherSize
114 );
115
116 virtual H235_ClearToken * CreateClearToken();
117 virtual H225_CryptoH323Token * CreateCryptoToken();
118
119 virtual PBoolean Finalise(
120 PBYTEArray & rawPDU
121 );
122
123 enum ValidationResult {
124 e_OK = 0, ///< Security parameters and Msg are ok, no security attacks
125 e_Absent, ///< Security parameters are expected but absent
126 e_Error, ///< Security parameters are present but incorrect
127 e_InvalidTime,///< Security parameters indicate peer has bad real time clock
128 e_BadPassword,///< Security parameters indicate bad password in token
129 e_ReplyAttack,///< Security parameters indicate an attack was made
130 e_Disabled, ///< Security is disabled by local system
131 e_Failed ///< Security has Failed
132 };
133
134 virtual ValidationResult ValidateTokens(
135 const PASN_Array & clearTokens,
136 const PASN_Array & cryptoTokens,
137 const PBYTEArray & rawPDU
138 );
139
140 virtual ValidationResult ValidateClearToken(
141 const H235_ClearToken & clearToken
142 );
143
144 virtual ValidationResult ValidateCryptoToken(
145 const H225_CryptoH323Token & cryptoToken,
146 const PBYTEArray & rawPDU
147 );
148
149 virtual PBoolean IsCapability(
150 const H235_AuthenticationMechanism & mechansim,
151 const PASN_ObjectId & algorithmOID
152 ) = 0;
153
154 virtual PBoolean SetCapability(
155 H225_ArrayOf_AuthenticationMechanism & mechansims,
156 H225_ArrayOf_PASN_ObjectId & algorithmOIDs
157 ) = 0;
158
159 virtual PBoolean UseGkAndEpIdentifiers() const;
160
161 virtual PBoolean IsSecuredPDU(unsigned rasPDU, PBoolean received) const;
162
163 virtual PBoolean IsSecuredSignalPDU(unsigned signalPDU, PBoolean received) const;
164
165 virtual PBoolean IsSecuredSignalPDU(
166 unsigned signalPDU,
167 PBoolean received,
168 PINDEX max_keyLength
169 ) const;
170
171 virtual PBoolean IsActive() const;
172
173 virtual void Enable(PBoolean enab = true) { enabled = enab; }
Disable()174 virtual void Disable() { enabled = false; }
175
GetRemoteId()176 virtual const PString & GetRemoteId() const { return remoteId; }
SetRemoteId(const PString & id)177 virtual void SetRemoteId(const PString & id) { remoteId = id; }
178
GetLocalId()179 virtual const PString & GetLocalId() const { return localId; }
SetLocalId(const PString & id)180 virtual void SetLocalId(const PString & id) { localId = id; }
181
GetPassword()182 virtual const PString & GetPassword() const { return password; }
SetPassword(const PString & pw)183 virtual void SetPassword(const PString & pw) { password = pw; }
184
GetTimestampGracePeriod()185 virtual int GetTimestampGracePeriod() const { return timestampGracePeriod; }
SetTimestampGracePeriod(int grace)186 virtual void SetTimestampGracePeriod(int grace) { timestampGracePeriod = grace; }
187
188 enum Application {
189 GKAdmission, ///< To Be Used for GK Admission
190 EPAuthentication, ///< To Be Used for EP Authentication
191 LRQOnly, ///< To Be Used for Location Request Authentication
192 MediaEncryption, ///< To Be Used for MediaEncryption
193 AnyApplication, ///< To Be Used for Any Application
194 };
195
GetApplication()196 Application GetApplication() { return usage; } // Get Authentication Application
197
198 virtual void SetConnection(H323Connection * con); // Set the connection for EPAuthentication
199
200 virtual PBoolean GetAlgorithms(PStringList & algorithms) const; // Get the supported Algorithm OIDs
201
202 virtual PBoolean GetAlgorithmDetails(const PString & algorithm, ///< Algorithm OID
203 PString & sslName, ///< SSL Description
204 PString & description ///< Human Description
205 );
206
ExportParameters(const PFilePath &)207 virtual void ExportParameters(const PFilePath & /*path*/) { } // export Parameters to file
208
209
210 protected:
211 PBoolean AddCapability(
212 unsigned mechanism,
213 const PString & oid,
214 H225_ArrayOf_AuthenticationMechanism & mechansims,
215 H225_ArrayOf_PASN_ObjectId & algorithmOIDs
216 );
217
218 PBoolean enabled;
219
220 PString remoteId; // ID of remote entity
221 PString localId; // ID of local entity
222 PString password; // shared secret
223
224 unsigned sentRandomSequenceNumber;
225 unsigned lastRandomSequenceNumber;
226 unsigned lastTimestamp;
227 int timestampGracePeriod;
228
229 Application usage; ///* Authenticator's Application
230 H323Connection * connection; ///* CallToken of the Connection for EP Authentication
231 PMutex mutex;
232 };
233
234
PDECLARE_LIST(H235Authenticators,H235Authenticator)235 PDECLARE_LIST(H235Authenticators, H235Authenticator)
236 #ifdef DOC_PLUS_PLUS
237 {
238 #endif
239 public:
240 // GKAdmission
241 void PreparePDU(
242 H323TransactionPDU & pdu,
243 PASN_Array & clearTokens,
244 unsigned clearOptionalField,
245 PASN_Array & cryptoTokens,
246 unsigned cryptoOptionalField
247 ) const;
248
249 H235Authenticator::ValidationResult ValidatePDU(
250 const H323TransactionPDU & pdu,
251 const PASN_Array & clearTokens,
252 unsigned clearOptionalField,
253 const PASN_Array & cryptoTokens,
254 unsigned cryptoOptionalField,
255 const PBYTEArray & rawPDU
256 ) const;
257
258 // EPAuthentication
259 void PrepareSignalPDU(
260 unsigned code,
261 PASN_Array & clearTokens,
262 PASN_Array & cryptoTokens,
263 PINDEX max_keyLength = P_MAX_INDEX
264 ) const;
265
266 H235Authenticator::ValidationResult ValidateSignalPDU(
267 unsigned code,
268 const PASN_Array & clearTokens,
269 const PASN_Array & cryptoTokens,
270 const PBYTEArray & rawPDU
271 ) const;
272
273 #ifdef H323_H235
274 struct DH_Data {
275 DH_Data()
276 : m_gData(0) { };
277
278 PString m_OID;
279 PBYTEArray m_pData;
280 PBYTEArray m_gData;
281 };
282 typedef list<DH_Data> DH_DataList;
283
284 PBoolean CreateAuthenticators(const PASN_Array & clearTokens, const PASN_Array & cryptoTokens);
285 PBoolean CreateAuthenticators(H235Authenticator::Application usage);
286 PBoolean CreateAuthenticator(const PString & name);
287 PBoolean SupportsEncryption(PStringArray & list) const;
288 PBoolean SupportsEncryption() const;
289 PBoolean GetAlgorithms(PStringList & algorithms) const;
290 PBoolean GetAlgorithmDetails(const PString & algorithm, PString & sslName, PString & description);
291 PBoolean GetMediaSessionInfo(PString & algorithmOID, PBYTEArray & sessionKey);
292
293 // Media Encryption Settings
294 static void SetEncryptionPolicy(PINDEX policy);
295 static PINDEX GetEncryptionPolicy();
296
297 // maximum cipher length in bits
298 static void SetMaxCipherLength(PINDEX cipher);
299 static PINDEX GetMaxCipherLength();
300
301 // maximum token length in bits
302 static void SetMaxTokenLength(PINDEX len);
303 static PINDEX GetMaxTokenLength();
304
305 static PString & GetDHParameterFile();
306 static void SetDHParameterFile(const PString & filePaths);
307
308 static void LoadDHData(const PString & oid, const PBYTEArray & pData, const PBYTEArray & gData);
309 static DH_DataList & GetDHDataList();
310
311 protected:
312 void CreateAuthenticatorsByID(const PStringArray & identifiers);
313
314 static PINDEX m_encryptionPolicy;
315 static PINDEX m_cipherLength;
316 static PINDEX m_maxTokenLength;
317 static PString m_dhFile;
318 static DH_DataList m_dhData;
319 #endif
320
321 };
322
323 class H235AuthenticatorInfo : public PObject
324 {
325 PCLASSINFO(H235AuthenticatorInfo, PObject);
326 public:
327 H235AuthenticatorInfo(PString username,PString password,PBoolean ishashed);
328 H235AuthenticatorInfo(PSSLCertificate * cert);
329 PString UserName;
330 PString Password;
331 PBoolean isHashed;
332 PSSLCertificate * Certificate;
333 };
334
H323_DECLARELIST(H235AuthenticatorList,H235AuthenticatorInfo)335 H323_DECLARELIST(H235AuthenticatorList, H235AuthenticatorInfo)
336 #ifdef DOC_PLUS_PLUS
337 {
338 #endif
339 PBoolean HasUserName(PString UserName) const;
340 void LoadPassword(PString UserName, PString & pass) const;
341 void Add(PString username, PString password, PBoolean isHashed = FALSE);
342 PString PasswordEncrypt(const PString &clear) const;
343 PString PasswordDecrypt(const PString &encrypt) const;
344 };
345
346 /** Dictionary of Addresses and Associated Security Info */
347 H323DICTIONARY(H235AuthenticatorDict,PString,H235AuthenticatorInfo);
348
349
350 /* This class is a device independent Time class that is used with H.235 Authentication mechanisms
351 It replaces the local time function to support remote gatekeeper synchronisation and ensures security
352 is not effected if the user changes the local device time while the application is running. */
353
354 class H235AuthenticatorTime : public PObject
355 {
356 PCLASSINFO(H235AuthenticatorTime, PObject);
357
358 public:
359 H235AuthenticatorTime();
360
361 /* GetLocalTime : Returns the local calculated time */
362 PUInt32b GetLocalTime();
363
364 /* GetTime : Returns the calculated synchronised time */
365 PUInt32b GetTime();
366
367 /* GetTime : Adjust the time to synchronise with remote time */
368 void SetAdjustedTime(time_t remoteTime);
369
370 protected:
371 time_t m_localTimeStart; ///< Local time at class instance.
372 clock_t m_localStartTick; ///< Local Tick count at class instance.
373 PInt64 m_adjustedTime; ///< Adjusted time for remote synchronisation.
374
375 };
376
377
378 /** This class embodies a simple MD5 based authentication.
379 The users password is concatenated with the 4 byte timestamp and 4 byte
380 random fields and an MD5 generated and sent/verified
381 */
382 class H235AuthSimpleMD5 : public H235Authenticator
383 {
384 PCLASSINFO(H235AuthSimpleMD5, H235Authenticator);
385 public:
386 H235AuthSimpleMD5();
387
388 PObject * Clone() const;
389
390 virtual const char * GetName() const;
391
392 static PStringArray GetAuthenticatorNames();
393 #if PTLIB_VER >= 2110
394 static PBoolean GetAuthenticationCapabilities(Capabilities * ids);
395 #endif
396 virtual PBoolean IsMatch(const PString & identifier) const;
397
398 virtual H225_CryptoH323Token * CreateCryptoToken();
399
400 virtual ValidationResult ValidateCryptoToken(
401 const H225_CryptoH323Token & cryptoToken,
402 const PBYTEArray & rawPDU
403 );
404
405 virtual PBoolean IsCapability(
406 const H235_AuthenticationMechanism & mechansim,
407 const PASN_ObjectId & algorithmOID
408 );
409
410 virtual PBoolean SetCapability(
411 H225_ArrayOf_AuthenticationMechanism & mechansim,
412 H225_ArrayOf_PASN_ObjectId & algorithmOIDs
413 );
414
415 virtual PBoolean IsSecuredPDU(
416 unsigned rasPDU,
417 PBoolean received
418 ) const;
419
420 virtual PBoolean IsSecuredSignalPDU(
421 unsigned rasPDU,
422 PBoolean received
423 ) const;
424 };
425
426 ////////////////////////////////////////////////////
427
428
429 #if PTLIB_VER >= 2110
430 /// PFactory Loader
431 typedef H235AuthSimpleMD5 H235AuthenticatorMD5;
432 #ifndef _WIN32_WCE
433 PPLUGIN_STATIC_LOAD(MD5,H235Authenticator);
434 #endif
435 #endif
436
437
438 /** This class embodies a RADIUS compatible based authentication (aka Cisco
439 Access Token or CAT).
440 The users password is concatenated with the 4 byte timestamp and 1 byte
441 random fields and an MD5 generated and sent/verified via the challenge
442 field.
443 */
444 class H235AuthCAT : public H235Authenticator
445 {
446 PCLASSINFO(H235AuthCAT, H235Authenticator);
447 public:
448 H235AuthCAT();
449
450 PObject * Clone() const;
451
452 virtual const char * GetName() const;
453
454 static PStringArray GetAuthenticatorNames();
455 #if PTLIB_VER >= 2110
456 static PBoolean GetAuthenticationCapabilities(Capabilities * ids);
457 #endif
458
459 virtual H235_ClearToken * CreateClearToken();
460
461 virtual ValidationResult ValidateClearToken(
462 const H235_ClearToken & clearToken
463 );
464
465 virtual PBoolean IsCapability(
466 const H235_AuthenticationMechanism & mechansim,
467 const PASN_ObjectId & algorithmOID
468 );
469
470 virtual PBoolean SetCapability(
471 H225_ArrayOf_AuthenticationMechanism & mechansim,
472 H225_ArrayOf_PASN_ObjectId & algorithmOIDs
473 );
474
475 virtual PBoolean IsSecuredPDU(unsigned rasPDU, PBoolean received) const;
476 };
477
478 #if PTLIB_VER >= 2110
479 // PFactory Loader
480 typedef H235AuthCAT H235AuthenticatorCAT;
481 #ifndef _WIN32_WCE
482 PPLUGIN_STATIC_LOAD(CAT,H235Authenticator);
483 #endif
484 #endif
485
486 //////////////////////////////////////////////////////////////////////////////
487
488 /** This class is used for Time Stamp Synchronisation between the gatekeeper
489 and the endpoint
490 */
491 class H235AuthenticatorTSS : public H235Authenticator
492 {
493 PCLASSINFO(H235AuthenticatorTSS, H235Authenticator);
494 public:
495 H235AuthenticatorTSS();
496
497 PObject * Clone() const;
498
499 virtual const char * GetName() const;
500
501 static PStringArray GetAuthenticatorNames();
502 #if PTLIB_VER >= 2110
503 static PBoolean GetAuthenticationCapabilities(Capabilities * ids);
504 #endif
505
506 virtual H235_ClearToken * CreateClearToken();
507
508 virtual ValidationResult ValidateClearToken(
509 const H235_ClearToken & clearToken
510 );
511
512 virtual PBoolean IsCapability(
513 const H235_AuthenticationMechanism & mechansim,
514 const PASN_ObjectId & algorithmOID
515 );
516
517 virtual PBoolean SetCapability(
518 H225_ArrayOf_AuthenticationMechanism & mechansim,
519 H225_ArrayOf_PASN_ObjectId & algorithmOIDs
520 );
521
522 virtual PBoolean IsSecuredPDU(
523 unsigned rasPDU,
524 PBoolean received
525 ) const;
526 };
527
528 #if PTLIB_VER >= 2110
529 #ifndef _WIN32_WCE
530 PPLUGIN_STATIC_LOAD(TSS,H235Authenticator);
531 #endif
532 #endif
533
534 //////////////////////////////////////////////////////////////////////////////
535 #if H323_SSL
536
537 /** This class embodies the H.235 "base line" from H235.1.
538 */
539
540 class H2351_Authenticator : public H235Authenticator
541 {
542 PCLASSINFO(H2351_Authenticator, H235Authenticator);
543 public:
544 H2351_Authenticator();
545
546 PObject * Clone() const;
547
548 virtual const char * GetName() const;
549
550 static PStringArray GetAuthenticatorNames();
551 #if PTLIB_VER >= 2110
552 static PBoolean GetAuthenticationCapabilities(Capabilities * ids);
553 #endif
554 virtual PBoolean IsMatch(const PString & identifier) const;
555
556 virtual H225_CryptoH323Token * CreateCryptoToken();
557
558 virtual PBoolean Finalise(PBYTEArray & rawPDU);
559
560 virtual ValidationResult ValidateCryptoToken(
561 const H225_CryptoH323Token & cryptoToken,
562 const PBYTEArray & rawPDU
563 );
564
565 virtual PBoolean IsCapability(
566 const H235_AuthenticationMechanism & mechansim,
567 const PASN_ObjectId & algorithmOID
568 );
569
570 virtual PBoolean SetCapability(
571 H225_ArrayOf_AuthenticationMechanism & mechansim,
572 H225_ArrayOf_PASN_ObjectId & algorithmOIDs
573 );
574
575 virtual PBoolean IsSecuredPDU(unsigned rasPDU, PBoolean received) const;
576
577 virtual PBoolean IsSecuredSignalPDU(unsigned rasPDU, PBoolean received) const;
578
579 virtual PBoolean UseGkAndEpIdentifiers() const;
580
RequireGeneralID(bool value)581 virtual void RequireGeneralID(bool value) { m_requireGeneralID = value; }
CheckSendersID(bool value)582 virtual void CheckSendersID(bool value) { m_checkSendersID = value; }
FullQ931Checking(bool value)583 virtual void FullQ931Checking(bool value) { m_fullQ931Checking = value; }
VerifyRandomNumber(bool value)584 virtual void VerifyRandomNumber(bool value) { m_verifyRandomNumber = value; }
585
586 protected:
587 PBoolean m_requireGeneralID;
588 PBoolean m_checkSendersID;
589 PBoolean m_fullQ931Checking;
590 PBoolean m_verifyRandomNumber;
591 };
592
593 typedef H2351_Authenticator H235AuthProcedure1; // Backwards interoperability
594
595 #endif
596
597 //////////////////////////////////////////////////////////////////////////////
598
599 #if PTLIB_VER >= 2130
600
601 PCREATE_PLUGIN_DEVICE(H235Authenticator);
602 #define H235SECURITY_EX(name,extra) \
603 PCREATE_PLUGIN(name, H235Authenticator, H235Authenticator##name, PPlugin_H235Authenticator, \
604 virtual PStringArray GetDeviceNames(P_INT_PTR /*userData*/) const { return H235Authenticator##name::GetAuthenticatorNames(); } \
605 virtual bool ValidateDeviceName(const PString & deviceName, int /*userData*/) const \
606 { return (deviceName == H235Authenticator##name::GetAuthenticatorNames()[0]); } \
607 virtual bool GetDeviceCapabilities(const PString & /*deviceName*/, void * caps) const \
608 { return H235Authenticator##name::GetAuthenticationCapabilities((H235Authenticator::Capabilities *)caps); } \
609 extra)
610 #define H235SECURITY(name) H235SECURITY_EX(name, )
611
612 #else
613
614 template <class className> class H235PluginServiceDescriptor : public PDevicePluginServiceDescriptor
615 {
616 public:
CreateInstance(int)617 virtual PObject * CreateInstance(int /*userData*/) const { return new className; }
GetDeviceNames(int)618 virtual PStringArray GetDeviceNames(int /*userData*/) const {
619 return className::GetAuthenticatorNames();
620 }
ValidateDeviceName(const PString & deviceName,int)621 virtual bool ValidateDeviceName(const PString & deviceName, int /*userData*/) const {
622 return (deviceName == className::GetAuthenticatorNames()[0]);
623 }
624 #if PTLIB_VER >= 2110
GetDeviceCapabilities(const PString &,void * capabilities)625 virtual bool GetDeviceCapabilities(const PString & /*deviceName*/, void * capabilities) const {
626 return className::GetAuthenticationCapabilities((H235Authenticator::Capabilities *)capabilities);
627 }
628 #endif
629 };
630
631 #define H235SECURITY(name) \
632 static H235PluginServiceDescriptor<H235Authenticator##name> H235Authenticator##name##_descriptor; \
633 PCREATE_PLUGIN(name, H235Authenticator, &H235Authenticator##name##_descriptor);
634 #endif
635
636
637 #endif //__H323_H235AUTH_H
638
639
640 /////////////////////////////////////////////////////////////////////////////
641