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