PTLib  Version 2.18.8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cypher.h
Go to the documentation of this file.
1 /*
2  * cypher.h
3  *
4  * Encryption support classes.
5  *
6  * Portable Windows Library
7  *
8  * Copyright (c) 1993-2002 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 Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Contributor(s): ______________________________________.
25  */
26 
27 
28 #ifndef PTLIB_CYPHER_H
29 #define PTLIB_CYPHER_H
30 
31 #ifdef P_USE_PRAGMA
32 #pragma interface
33 #endif
34 
35 #if P_CYPHER
36 
42 class PSASLString : public PString
43 {
44  PCLASSINFO(PSASLString, PString);
45  public:
46  PSASLString() { }
47  PSASLString(const char * str) { AppendValidated(str); }
48  PSASLString(const PString & str) { AppendValidated(str); }
49  PSASLString(const PSASLString & str) : PString(str) { }
50 
51  PSASLString & operator=(char ch) { MakeEmpty(); AppendValidated(ch); return *this; }
52  PSASLString & operator=(wchar_t ch) { MakeEmpty(); AppendValidated(ch); return *this; }
53  PSASLString & operator=(const char * str) { MakeEmpty(); AppendValidated(str); return *this; }
54  PSASLString & operator=(const PString & str) { MakeEmpty(); AppendValidated(str); return *this; }
55  PSASLString & operator=(const PSASLString & str) { PString::operator=(str); return *this; }
56 
57  PSASLString & operator+=(char ch) { AppendValidated(ch); return *this; }
58  PSASLString & operator+=(wchar_t ch) { AppendValidated(ch); return *this; }
59  PSASLString & operator+=(const char * str) { AppendValidated(str); return *this; }
60  PSASLString & operator+=(const PString & str) { AppendValidated(str); return *this; }
61  PSASLString & operator+=(const PSASLString & str) { PString::operator=(str); return *this; }
62 
63  protected:
64  void AppendValidated(const char * str);
65  void AppendValidated(wchar_t ch);
66 };
67 
68 
99 class PBase64 : public PObject
100 {
101  PCLASSINFO(PBase64, PObject);
102 
103  public:
105  enum Options {
106  e_CRLF,
107  e_LF,
108  e_NoLF,
109  e_URL
110  };
111 
115  explicit PBase64(
116  Options options = e_CRLF,
117  PINDEX width = 76
118  );
119 
121  void StartEncoding(
122  Options options = e_CRLF,
123  PINDEX width = 76
124  );
125  void StartEncoding(
126  const char * endOfLine,
127  PINDEX width = 76
128  );
129  void StartEncoding(
130  bool useCRLFs,
131  PINDEX width = 76
132  ) { StartEncoding(useCRLFs ? e_CRLF : e_LF, width); }
133 
135  void ProcessEncoding(
136  const PString & str // String to be encoded
137  );
138  void ProcessEncoding(
139  const char * cstr // C String to be encoded
140  );
141  void ProcessEncoding(
142  const PBYTEArray & data // Data block to be encoded
143  );
144  void ProcessEncoding(
145  const void * dataBlock, // Pointer to data to be encoded
146  PINDEX length // Length of the data block.
147  );
148 
154  PString GetEncodedString();
155 
162  PString CompleteEncoding();
163 
164 
166  static PString Encode(
167  const PString & str,
168  Options options = e_LF,
169  PINDEX width = 76
170  );
171  static PString Encode(
172  const PString & str,
173  const char * endOfLine,
174  PINDEX width = 76
175  );
176  static PString Encode(
177  const char * cstr,
178  Options options = e_LF,
179  PINDEX width = 76
180  );
181  static PString Encode(
182  const char * cstr,
183  const char * endOfLine,
184  PINDEX width = 76
185  );
186  static PString Encode(
187  const PBYTEArray & data,
188  Options options = e_LF,
189  PINDEX width = 76
190  );
191  static PString Encode(
192  const PBYTEArray & data,
193  const char * endOfLine,
194  PINDEX width = 76
195  );
196  static PString Encode(
197  const void * dataBlock,
198  PINDEX length,
199  Options options = e_LF,
200  PINDEX width = 76
201  );
202  static PString Encode(
203  const void * dataBlock,
204  PINDEX length,
205  const char * endOfLine,
206  PINDEX width = 76
207  );
208 
209 
210  void StartDecoding();
211  // Begin a base 64 decoding operation, initialising the object instance.
212 
218  PBoolean ProcessDecoding(
219  const PString & str // String to be encoded
220  );
221  PBoolean ProcessDecoding(
222  const char * cstr // C String to be encoded
223  );
224 
230  PBoolean GetDecodedData(
231  void * dataBlock, // Pointer to data to be decoded from base64
232  PINDEX length // Length of the data block.
233  );
234  PBYTEArray GetDecodedData();
235 
243  PBoolean IsDecodeOK() { return m_perfectDecode; }
244 
245 
257  static PString Decode(
258  const PString & str // Encoded base64 string to be decoded.
259  );
260  static PBoolean Decode(
261  const PString & str, // Encoded base64 string to be decoded.
262  PBYTEArray & data // Converted binary data from base64.
263  );
264  static PBoolean Decode(
265  const PString & str, // Encoded base64 string to be decoded.
266  void * dataBlock, // Pointer to data to be decoded from base64
267  PINDEX length // Length of the data block.
268  );
269 
270 
271 
272  private:
273  void OutputBase64(const BYTE * data);
274 
275  PString m_encodedString;
276  BYTE m_saveTriple[3];
277  PINDEX m_saveCount;
278  PString m_endOfLine;
279  PINDEX m_maxLineLength;
280  PINDEX m_currentLineLength;
281  const char * m_alphabet;
282 
283  bool m_perfectDecode;
284  PINDEX m_quadPosition;
285  PBYTEArray m_decodedData;
286  PINDEX m_decodeSize;
287 };
288 
289 
292 class PMessageDigest : public PObject
293 {
294  PCLASSINFO(PMessageDigest, PObject)
295  public:
297  PMessageDigest();
298 
300  class Result : public PBYTEArray {
301  public:
302  virtual void PrintOn(ostream & strm) const;
303 
304  bool ConstantTimeCompare(const Result & other) const;
305 
306  PString AsBase64(PBase64::Options options = PBase64::e_NoLF) const { return PBase64::Encode(*this, options); }
307  PString AsHex() const;
308  };
309 
311  void Start() { InternalStart(); }
312 
313  void Process(
314  const void * dataBlock,
315  PINDEX length
316  );
317 
319  void Process(
320  const PString & str
321  );
323  void Process(
324  const char * cstr
325  );
327  void Process(
328  const PBYTEArray & data
329  );
330 
338  PString Complete();
339  void Complete(
340  Result & result
341  ) { InternalCompleteDigest(result); }
342 
343  protected:
344  virtual void InternalStart() = 0;
345  virtual void InternalProcess(const void * dataBlock, PINDEX length) = 0;
346  virtual void InternalCompleteDigest(Result & result) = 0;
347 };
348 
349 
350 template <class Digestor> struct PMessageDigestStatics
351 {
353  static PString Encode(
354  const PString & str
355  ) { return Encode(str.GetPointer(), str.GetLength()); }
356 
358  static void Encode(
359  const PString & str,
360  PMessageDigest::Result & result
361  ) { Encode(str.GetPointer(), str.GetLength(), result); }
362 
364  static PString Encode(
365  const char * cstr
366  ) { return Encode(cstr, (PINDEX)strlen(cstr)); }
367 
369  static void Encode(
370  const char * cstr,
371  PMessageDigest::Result & result
372  ) { Encode(cstr, (PINDEX)strlen(cstr), result); }
373 
375  static PString Encode(
376  const PBYTEArray & data
377  ) { return Encode(data, data.GetSize()); }
378 
380  static void Encode(
381  const PBYTEArray & data,
382  PMessageDigest::Result & result
383  ) { Encode(data, data.GetSize(), result); }
384 
386  static PString Encode(
387  const void * dataBlock,
388  PINDEX length
389  ) {
390  PMessageDigest::Result result;
391  Encode(dataBlock, length, result);
392  return result.AsBase64();
393  }
394 
397  static void Encode(
398  const void * dataBlock,
399  PINDEX length,
400  PMessageDigest::Result & result
401  ) {
402  Digestor stomach;
403  stomach.Process(dataBlock, length);
404  stomach.Complete(result);
405  }
406 };
407 
408 
413 class PHMAC : public PObject
414 {
415  PCLASSINFO(PHMAC, PObject);
416  public:
417  void SetKey(const char * key) { InitKey(key, strlen(key)); }
418  void SetKey(const PString & key) { InitKey(key.GetPointer(), key.GetLength()); }
419  void SetKey(const PBYTEArray & key) { InitKey((const BYTE *)key, key.GetSize()); }
420  void SetKey(const BYTE * key, PINDEX len) { InitKey(key, len); }
421 
422  PString Encode(const void * data, PINDEX len, PBase64::Options options = PBase64::e_NoLF);
423  PString Encode(const PBYTEArray & data, PBase64::Options options = PBase64::e_NoLF);
424  PString Encode(const PString & str, PBase64::Options options = PBase64::e_NoLF);
425 
426  typedef PMessageDigest::Result Result;
427  virtual void Process(const void * data, PINDEX len, Result & result);
428  virtual void Process(const PBYTEArray & data, Result & result);
429  virtual void Process(const PString & str, Result & result);
430 
431  protected:
432  virtual void InitKey(const void * key, PINDEX len);
433  virtual void InternalProcess(const void * data, PINDEX len, PHMAC::Result & result) = 0;
434 
435  PBYTEArray m_key;
436 };
437 
438 
444 class PMessageDigest5 : public PMessageDigest, public PMessageDigestStatics<PMessageDigest5>
445 {
446  PCLASSINFO(PMessageDigest5, PMessageDigest)
447  public:
448  enum { DigestLength = 16 };
449  typedef PMessageDigest::Result Code; // Backward compatibility
450 
452  PMessageDigest5();
453 
454  protected:
455  virtual void InternalStart();
456  virtual void InternalProcess(const void * dataBlock, PINDEX length);
457  virtual void InternalCompleteDigest(Result & result);
458 
459  private:
460  void Transform(const BYTE * block);
461 
463  BYTE buffer[64];
465  DWORD state[4];
467  PUInt64 count;
468 };
469 
470 
473 class PHMAC_MD5 : public PHMAC
474 {
475  PCLASSINFO(PHMAC_MD5, PHMAC)
476  public:
477  enum { BlockSize = 64 };
478 
479  protected:
480  virtual void InitKey(const void * key, PINDEX len);
481  virtual void InternalProcess(const void * data, PINDEX len, PHMAC::Result & result);
482 };
483 
484 
485 #if P_SSL
486 
487 class PMessageDigestSHA : public PMessageDigest
488 {
489  PCLASSINFO(PMessageDigestSHA, PMessageDigest)
490  public:
491  struct Context;
492 
493  protected:
495  explicit PMessageDigestSHA(Context * context);
496 
497  public:
498  ~PMessageDigestSHA();
499 
500  protected:
501  virtual void InternalStart();
502  virtual void InternalProcess(const void * dataBlock, PINDEX length);
503  virtual void InternalCompleteDigest(Result & result);
504  void Failed();
505 
506  Context * m_context;
507  enum {
508  e_Uninitialised,
509  e_Processing,
510  e_Failed
511  } m_state;
512 
513  private:
514  PMessageDigestSHA(const PMessageDigestSHA &) : m_context(), m_state() { }
515  void operator=(const PMessageDigestSHA &) { }
516 };
517 
518 
522 class PMessageDigestSHA1 : public PMessageDigestSHA, public PMessageDigestStatics<PMessageDigestSHA1>
523 {
524  PCLASSINFO(PMessageDigestSHA1, PMessageDigestSHA)
525  public:
526  enum { DigestLength = 20 };
527  PMessageDigestSHA1();
528 };
529 
530 
534 class PMessageDigestSHA256 : public PMessageDigestSHA, public PMessageDigestStatics<PMessageDigestSHA256>
535 {
536  PCLASSINFO(PMessageDigestSHA256, PMessageDigestSHA)
537  public:
538  PMessageDigestSHA256();
539 };
540 
541 
545 class PMessageDigestSHA384 : public PMessageDigestSHA, public PMessageDigestStatics<PMessageDigestSHA384>
546 {
547  PCLASSINFO(PMessageDigestSHA384, PMessageDigestSHA)
548  public:
549  PMessageDigestSHA384();
550 };
551 
552 
556 class PMessageDigestSHA512 : public PMessageDigestSHA, public PMessageDigestStatics<PMessageDigestSHA512>
557 {
558  PCLASSINFO(PMessageDigestSHA512, PMessageDigestSHA)
559  public:
560  PMessageDigestSHA512();
561 };
562 
563 
564 class PHMAC_SHA : public PHMAC
565 {
566  PCLASSINFO(PHMAC_SHA, PHMAC)
567  protected:
568  typedef struct evp_md_st const * Algorithm;
569 
570  explicit PHMAC_SHA(Algorithm algo);
571  virtual void InternalProcess(const void * data, PINDEX len, PHMAC::Result & result);
572 
573  Algorithm m_algorithm;
574 };
575 
576 
577 class PHMAC_SHA1 : public PHMAC_SHA
578 {
579  PCLASSINFO(PHMAC_SHA1, PHMAC_SHA)
580  public:
581  PHMAC_SHA1();
582 };
583 
584 
585 class PHMAC_SHA256 : public PHMAC_SHA
586 {
587  PCLASSINFO(PHMAC_SHA256, PHMAC_SHA)
588  public:
589  PHMAC_SHA256();
590 };
591 
592 
593 class PHMAC_SHA384 : public PHMAC_SHA
594 {
595  PCLASSINFO(PHMAC_SHA384, PHMAC_SHA)
596  public:
597  PHMAC_SHA384();
598 };
599 
600 
601 class PHMAC_SHA512 : public PHMAC_SHA
602 {
603  PCLASSINFO(PHMAC_SHA512, PHMAC_SHA)
604  public:
605  PHMAC_SHA512();
606 };
607 
608 #endif // P_SSL
609 
610 
614 class PCypher : public PObject
615 {
616  PCLASSINFO(PCypher, PObject)
617 
618  public:
620  enum BlockChainMode {
621  ElectronicCodebook,
622  ECB = ElectronicCodebook,
623  CypherBlockChaining,
624  CBC = CypherBlockChaining,
625  OutputFeedback,
626  OFB = OutputFeedback,
627  CypherFeedback,
628  CFB = CypherFeedback,
629  NumBlockChainModes
630  };
631 
632  // New functions for class
634  PString Encode(
635  const PString & str
636  );
638  PString Encode(
639  const PBYTEArray & clear
640  );
642  PString Encode(
643  const void * data,
644  PINDEX length
645  );
647  void Encode(
648  const PBYTEArray & clear,
649  PBYTEArray & coded
650  );
666  void Encode(
667  const void * data, // Clear text binary data to be encoded.
668  PINDEX length, // Number of bytes of data to be encoded.
669  PBYTEArray & coded // Encoded data.
670  );
671 
673  PString Decode(
674  const PString & cypher
675  );
677  PBoolean Decode(
678  const PString & cypher,
679  PString & clear
680  );
682  PBoolean Decode(
683  const PString & cypher,
684  PBYTEArray & clear
685  );
687  PINDEX Decode(
688  const PString & cypher,
689  void * data,
690  PINDEX length
691  );
693  PINDEX Decode(
694  const PBYTEArray & coded,
695  void * data,
696  PINDEX length
697  );
713  PBoolean Decode(
714  const PBYTEArray & coded,
715  PBYTEArray & clear
716  );
717 
718 
719  protected:
723  PCypher(
724  PINDEX blockSize,
725  BlockChainMode chainMode
726  );
727  PCypher(
728  const void * keyData,
729  PINDEX keyLength,
730  PINDEX blockSize,
731  BlockChainMode chainMode
732  );
733 
734 
736  virtual void Initialise(
737  PBoolean encoding
738  ) = 0;
739 
741  virtual void EncodeBlock(
742  const void * in,
743  void * out
744  ) = 0;
745 
746 
748  virtual void DecodeBlock(
749  const void * in,
750  void * out
751  ) = 0;
752 
753 
755  PBYTEArray key;
757  PINDEX blockSize;
759  BlockChainMode chainMode;
760 };
761 
762 
770 class PTEACypher : public PCypher
771 {
772  PCLASSINFO(PTEACypher, PCypher)
773 
774  public:
775  struct Key {
776  BYTE value[16];
777  };
778 
783  PTEACypher(
784  BlockChainMode chainMode = ElectronicCodebook
785  );
786  PTEACypher(
787  const Key & keyData,
788  BlockChainMode chainMode = ElectronicCodebook
789  );
790 
791 
793  void SetKey(
794  const Key & newKey
795  );
796 
798  void GetKey(
799  Key & newKey
800  ) const;
801 
802 
804  static void GenerateKey(
805  Key & newKey
806  );
807 
808 
809  protected:
811  virtual void Initialise(
812  PBoolean encoding
813  );
814 
816  virtual void EncodeBlock(
817  const void * in,
818  void * out
819  );
820 
822  virtual void DecodeBlock(
823  const void * in,
824  void * out
825  );
826 
827  private:
828  DWORD k0, k1, k2, k3;
829 };
830 
831 
832 #ifdef P_CONFIG_FILE
833 
834 class PSecureConfig : public PConfig
835 {
836  PCLASSINFO(PSecureConfig, PConfig)
837 /* This class defines a set of configuration keys which may be secured by an
838  encrypted hash function. Thus values contained in keys specified by this
839  class cannot be changed without invalidating the hash function.
840  */
841 
842  public:
843  PSecureConfig(
844  const PTEACypher::Key & productKey, // Key to decrypt validation code.
845  const PStringArray & securedKeys, // List of secured keys.
846  Source src = Application // Standard source for the configuration.
847  );
848  PSecureConfig(
849  const PTEACypher::Key & productKey, // Key to decrypt validation code.
850  const char * const * securedKeyArray, // List of secured keys.
851  PINDEX count, // Number of secured keys in list.
852  Source src = Application // Standard source for the configuration.
853  );
854  /* Create a secured configuration. The default section for the
855  configuration keys is "Secured Options", the default security key is
856  "Validation" and the defualt prefix string is "Pending:".
857 
858  The user can descend from this class and change any of the member
859  variable for the names of keys or the configuration file section.
860  */
861 
862 
863  // New functions for class
864  const PStringArray & GetSecuredKeys() const { return securedKeys; }
865  /* Get the list of secured keys in the configuration file section.
866 
867  @return
868  Array of strings for the secured keys.
869  */
870 
871  const PString & GetSecurityKey() const { return securityKey; }
872  /* Get the security keys name in the configuration file section.
873 
874  @return
875  String for the security values key.
876  */
877 
878  const PString & GetExpiryDateKey() const { return expiryDateKey; }
879  /* Get the expiry date keys name in the configuration file section.
880 
881  @return
882  String for the expiry date values key.
883  */
884 
885  const PString & GetOptionBitsKey() const { return optionBitsKey; }
886  /* Get the Option Bits keys name in the configuration file section.
887 
888  @return
889  String for the Option Bits values key.
890  */
891 
892  const PString & GetPendingPrefix() const { return pendingPrefix; }
893  /* Get the pending prefix name in the configuration file section.
894 
895  @return
896  String for the pending prefix.
897  */
898 
899  void GetProductKey(
900  PTEACypher::Key & productKey // Variable to receive the product key.
901  ) const;
902  /* Get the pending prefix name in the configuration file section.
903 
904  @return
905  String for the pending prefix.
906  */
907 
908 
909  enum ValidationState {
910  Defaults,
911  Pending,
912  IsValid,
913  Expired,
914  Invalid
915  };
916  ValidationState GetValidation() const;
917  /* Check the current values attached to the keys specified in the
918  constructor against an encoded validation key.
919 
920  @return
921  State of the validation keys.
922  */
923 
924  PBoolean ValidatePending();
925  /* Validate a pending secured option list for the product. All secured
926  keys with the <CODE>pendingPrefix</CODE> name will be checked against
927  the value of the field <CODE>securityKey</CODE>. If they match then
928  they are copied to the secured variables.
929 
930  @return
931  true if secure key values are valid.
932  */
933 
934  void ResetPending();
935  /* "Unvalidate" a security configuration going back to a pending state,
936  usually used after an <CODE>Invalid</CODE> response was recieved from
937  the <A>GetValidation()</A> function.
938  */
939 
940 
941  protected:
942  PTEACypher::Key productKey;
943  PStringArray securedKeys;
944  PString securityKey;
945  PString expiryDateKey;
946  PString optionBitsKey;
947  PString pendingPrefix;
948 };
949 
950 #endif // P_CONFIG_FILE
951 
952 #endif // P_CYPHER
953 
954 #endif // PTLIB_CYPHER_H
955 
956 
957 // End Of File ///////////////////////////////////////////////////////////////
PString & operator=(const PString &str)
Assign the string to the current object.
#define PCLASSINFO(cls, par)
Declare all the standard PTLib class information.
Definition: object.h:2164
virtual PString & MakeEmpty()
Make the current string empty.
A class representing a configuration for the application.
Definition: config.h:62
This is an array collection class of PString objects.
Definition: pstring.h:2365
PString & operator+=(const PString &str)
Concatenate a string to another string, modifiying that string.
Array of unsigned characters.
Definition: array.h:605
virtual PINDEX GetSize() const
Get the current size of the container.
bool PBoolean
Definition: object.h:174
The character string class.
Definition: pstring.h:108
virtual PINDEX GetLength() const
Determine the length of the null terminated string.
Definition: pstring.h:595
virtual const char * GetPointer(PINDEX=0) const
Get a const pointer to the buffer contents This function overrides the ancestor function that returns...
Definition: pstring.h:1877
Ultimate parent class for all objects in the class library.
Definition: object.h:2204
virtual void PrintOn(ostream &strm) const
Output the contents of the object to the stream.