PTLib  Version 2.14.3
 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  * $Revision: 31268 $
27  * $Author: rjongbloed $
28  * $Date: 2014-01-27 11:43:30 +1100 (Mon, 27 Jan 2014) $
29  */
30 
31 
32 #ifndef PTLIB_CYPHER_H
33 #define PTLIB_CYPHER_H
34 
35 #ifdef P_USE_PRAGMA
36 #pragma interface
37 #endif
38 
39 
45 class PSASLString : public PString
46 {
47  PCLASSINFO(PSASLString, PString);
48  public:
50  PSASLString(const char * str) { Prepare(str); }
51  PSASLString(const PString & str) { Prepare(str); }
52  PSASLString(const PSASLString & str) : PString(str) { }
53 
54  PSASLString & operator=(char c) { MakeEmpty(); AppendValidated(c); return *this; }
55  PSASLString & operator=(wchar_t c) { MakeEmpty(); AppendValidated(c); return *this; }
56  PSASLString & operator=(const char * str) { Prepare(str); return *this; }
57  PSASLString & operator=(const PString & str) { Prepare(str); return *this; }
58  PSASLString & operator=(const PSASLString & str) { PString::operator=(str); return *this; }
59 
60  PSASLString & operator+=(char c) { AppendValidated(c); return *this; }
61  PSASLString & operator+=(wchar_t c) { AppendValidated(c); return *this; }
62  PSASLString & operator+=(const char * str) { Prepare(str); return *this; }
63  PSASLString & operator+=(const PString & str) { Prepare(str); return *this; }
64  PSASLString & operator+=(const PSASLString & str) { PString::operator=(str); return *this; }
65 
66  protected:
67  void Prepare(const char *);
68  void AppendValidated(wchar_t c);
69 };
70 
71 
102 class PBase64 : public PObject
103 {
104  PCLASSINFO(PBase64, PObject);
105 
106  public:
110  PBase64();
111 
112  void StartEncoding(
113  bool useCRLFs = true,
114  PINDEX width = 76
115  );
116  void StartEncoding(
117  const char * endOfLine,
118  PINDEX width = 76
119  );
120  // Begin a base 64 encoding operation, initialising the object instance.
121 
122  void ProcessEncoding(
123  const PString & str // String to be encoded
124  );
125  void ProcessEncoding(
126  const char * cstr // C String to be encoded
127  );
128  void ProcessEncoding(
129  const PBYTEArray & data // Data block to be encoded
130  );
131  void ProcessEncoding(
132  const void * dataBlock, // Pointer to data to be encoded
133  PINDEX length // Length of the data block.
134  );
135  // Incorporate the specified data into the base 64 encoding.
136 
143 
151 
152 
153  static PString Encode(
154  const PString & str,
155  const char * endOfLine = "\n",
156  PINDEX width = 76
157  );
158  static PString Encode(
159  const char * cstr,
160  const char * endOfLine = "\n",
161  PINDEX width = 76
162  );
163  static PString Encode(
164  const PBYTEArray & data,
165  const char * endOfLine = "\n",
166  PINDEX width = 76
167  );
168  static PString Encode(
169  const void * dataBlock,
170  PINDEX length,
171  const char * endOfLine = "\n",
172  PINDEX width = 76
173  );
174  // Encode the data in memory to Base 64 data returnin the string.
175 
176 
177  void StartDecoding();
178  // Begin a base 64 decoding operation, initialising the object instance.
179 
186  const PString & str // String to be encoded
187  );
189  const char * cstr // C String to be encoded
190  );
191 
198  void * dataBlock, // Pointer to data to be decoded from base64
199  PINDEX length // Length of the data block.
200  );
202 
210  PBoolean IsDecodeOK() { return perfectDecode; }
211 
212 
224  static PString Decode(
225  const PString & str // Encoded base64 string to be decoded.
226  );
227  static PBoolean Decode(
228  const PString & str, // Encoded base64 string to be decoded.
229  PBYTEArray & data // Converted binary data from base64.
230  );
231  static PBoolean Decode(
232  const PString & str, // Encoded base64 string to be decoded.
233  void * dataBlock, // Pointer to data to be decoded from base64
234  PINDEX length // Length of the data block.
235  );
236 
237 
238 
239  private:
240  void OutputBase64(const BYTE * data);
241 
242  PString encodedString;
243  BYTE saveTriple[3];
244  PINDEX saveCount;
245  PString endOfLine;
246  PINDEX maxLineLength;
247  PINDEX currentLineLength;
248 
249  bool perfectDecode;
250  PINDEX quadPosition;
251  PBYTEArray decodedData;
252  PINDEX decodeSize;
253 };
254 
255 class PMessageDigest : public PObject
256 {
258 
259  public:
261  PMessageDigest();
262 
263  class Result : public PBYTEArray {
264  public:
265  virtual void PrintOn(ostream & strm) const;
266 
267  PString AsBase64() const { return PBase64::Encode(*this, ""); }
268  PString AsHex() const;
269  };
270 
272  virtual void Start() = 0;
273 
274  virtual void Process(
275  const void * dataBlock,
276  PINDEX length
277  );
278 
280  virtual void Process(
281  const PString & str
282  );
284  virtual void Process(
285  const char * cstr
286  );
288  virtual void Process(
289  const PBYTEArray & data
290  );
291 
299  virtual PString CompleteDigest();
300  virtual void CompleteDigest(
301  Result & result
302  );
303 
304  protected:
305  virtual void InternalProcess(
306  const void * dataBlock,
307  PINDEX length
308  ) = 0;
309 
310  virtual void InternalCompleteDigest(
311  Result & result
312  ) = 0;
313 };
314 
315 
320 class PHMAC : public PObject
321 {
322  public:
323  enum { KeyLength = 20 };
324  enum { BlockSize = 64 };
325 
327  virtual void Hash(const BYTE * data, PINDEX len, Result & result) = 0;
328 
329  virtual PString Encode(const BYTE * data, PINDEX len);
330  virtual PString Encode(const PBYTEArray & data);
331  virtual PString Encode(const PString & str);
332 
333  virtual void Process(const BYTE * data, PINDEX len, Result & result);
334  virtual void Process(const PBYTEArray & data, Result & result);
335  virtual void Process(const PString & str, Result & result);
336 
337  protected:
338  virtual PINDEX GetL() const { return KeyLength; };
339  virtual PINDEX GetB() const { return BlockSize; }
340  virtual void Initialise(const BYTE * key, PINDEX len);
341  virtual void InternalProcess(const BYTE * data, PINDEX len, PHMAC::Result & result);
342 
344 };
345 
346 template <class hash_class>
347 class PHMACTemplate : public PHMAC
348 {
349  public:
350  PHMACTemplate(const PString & key) { Initialise((const BYTE *)(const char *)key, key.GetLength()); }
351  PHMACTemplate(const PBYTEArray & key) { Initialise((const BYTE *)key, key.GetSize()); }
352  PHMACTemplate(const BYTE * key, PINDEX len) { Initialise(key, len); }
353 
354  virtual void Hash(const BYTE * data, PINDEX len, Result & result)
355  { hash_class::Encode(data, len, result); }
356 };
357 
364 {
366 
367  public:
368  enum { DigestLength = 16 };
369 
371  PMessageDigest5();
372 
374  void Start();
375 
377  static PString Encode(
378  const PString & str
379  );
381  static void Encode(
382  const PString & str,
383  Result & result
384  );
386  static PString Encode(
387  const char * cstr
388  );
390  static void Encode(
391  const char * cstr,
392  Result & result
393  );
395  static PString Encode(
396  const PBYTEArray & data
397  );
399  static void Encode(
400  const PBYTEArray & data,
401  Result & result
402  );
404  static PString Encode(
405  const void * dataBlock,
406  PINDEX length
407  );
413  static void Encode(
414  const void * dataBlock,
415  PINDEX length,
416  Result & result
417  );
418 
419  // backwards compatibility functions
420  class Code {
421  private:
422  PUInt32l value[4];
423  friend class PMessageDigest5;
424  };
425 
427  static void Encode(
428  const PString & str,
429  Code & result
430  );
432  static void Encode(
433  const char * cstr,
434  Code & result
435  );
437  static void Encode(
438  const PBYTEArray & data,
439  Code & result
440  );
446  static void Encode(
447  const void * dataBlock,
448  PINDEX length,
449  Code & result
450  );
451  virtual void Complete(
452  Code & result
453  );
454  virtual PString Complete();
455 
456  protected:
457  virtual void InternalProcess(
458  const void * dataBlock,
459  PINDEX length
460  );
461 
462  virtual void InternalCompleteDigest(
463  Result & result
464  );
465 
466  private:
467  void Transform(const BYTE * block);
468 
470  BYTE buffer[64];
472  DWORD state[4];
474  PUInt64 count;
475 };
476 
478 
479 #if P_SSL
480 
485 class PMessageDigestSHA1 : public PMessageDigest
486 {
487  PCLASSINFO(PMessageDigestSHA1, PMessageDigest)
488 
489  public:
490  enum { DigestLength = 20 };
491 
493  PMessageDigestSHA1();
494  ~PMessageDigestSHA1();
495 
497  void Start();
498 
500  static PString Encode(
501  const PString & str
502  );
504  static void Encode(
505  const PString & str,
506  Result & result
507  );
509  static PString Encode(
510  const char * cstr
511  );
513  static void Encode(
514  const char * cstr,
515  Result & result
516  );
518  static PString Encode(
519  const PBYTEArray & data
520  );
522  static void Encode(
523  const PBYTEArray & data,
524  Result & result
525  );
527  static PString Encode(
528  const void * dataBlock,
529  PINDEX length
530  );
536  static void Encode(
537  const void * dataBlock,
538  PINDEX length,
539  Result & result
540  );
541 
542  protected:
543  virtual void InternalProcess(
544  const void * dataBlock,
545  PINDEX length
546  );
547 
549  Result & result
550  );
551 
552  private:
553  void * shaContext;
554 };
555 
556 typedef PHMACTemplate<PMessageDigestSHA1> PHMAC_SHA1;
557 
558 #endif
559 
563 class PCypher : public PObject
564 {
566 
567  public:
579  };
580 
581  // New functions for class
583  PString Encode(
584  const PString & str
585  );
587  PString Encode(
588  const PBYTEArray & clear
589  );
591  PString Encode(
592  const void * data,
593  PINDEX length
594  );
596  void Encode(
597  const PBYTEArray & clear,
598  PBYTEArray & coded
599  );
615  void Encode(
616  const void * data, // Clear text binary data to be encoded.
617  PINDEX length, // Number of bytes of data to be encoded.
618  PBYTEArray & coded // Encoded data.
619  );
620 
622  PString Decode(
623  const PString & cypher
624  );
627  const PString & cypher,
628  PString & clear
629  );
632  const PString & cypher,
633  PBYTEArray & clear
634  );
636  PINDEX Decode(
637  const PString & cypher,
638  void * data,
639  PINDEX length
640  );
642  PINDEX Decode(
643  const PBYTEArray & coded,
644  void * data,
645  PINDEX length
646  );
663  const PBYTEArray & coded,
664  PBYTEArray & clear
665  );
666 
667 
668  protected:
672  PCypher(
673  PINDEX blockSize,
675  );
676  PCypher(
677  const void * keyData,
678  PINDEX keyLength,
679  PINDEX blockSize,
681  );
682 
683 
685  virtual void Initialise(
686  PBoolean encoding
687  ) = 0;
688 
690  virtual void EncodeBlock(
691  const void * in,
692  void * out
693  ) = 0;
694 
695 
697  virtual void DecodeBlock(
698  const void * in,
699  void * out
700  ) = 0;
701 
702 
706  PINDEX blockSize;
709 };
710 
711 
719 class PTEACypher : public PCypher
720 {
722 
723  public:
724  struct Key {
725  BYTE value[16];
726  };
727 
732  PTEACypher(
734  );
735  PTEACypher(
736  const Key & keyData,
738  );
739 
740 
742  void SetKey(
743  const Key & newKey
744  );
745 
747  void GetKey(
748  Key & newKey
749  ) const;
750 
751 
753  static void GenerateKey(
754  Key & newKey
755  );
756 
757 
758  protected:
760  virtual void Initialise(
761  PBoolean encoding
762  );
763 
765  virtual void EncodeBlock(
766  const void * in,
767  void * out
768  );
769 
771  virtual void DecodeBlock(
772  const void * in,
773  void * out
774  );
775 
776  private:
777  DWORD k0, k1, k2, k3;
778 };
779 
780 
781 #ifdef P_CONFIG_FILE
782 
783 class PSecureConfig : public PConfig
784 {
786 /* This class defines a set of configuration keys which may be secured by an
787  encrypted hash function. Thus values contained in keys specified by this
788  class cannot be changed without invalidating the hash function.
789  */
790 
791  public:
793  const PTEACypher::Key & productKey, // Key to decrypt validation code.
794  const PStringArray & securedKeys, // List of secured keys.
795  Source src = Application // Standard source for the configuration.
796  );
798  const PTEACypher::Key & productKey, // Key to decrypt validation code.
799  const char * const * securedKeyArray, // List of secured keys.
800  PINDEX count, // Number of secured keys in list.
801  Source src = Application // Standard source for the configuration.
802  );
803  /* Create a secured configuration. The default section for the
804  configuration keys is "Secured Options", the default security key is
805  "Validation" and the defualt prefix string is "Pending:".
806 
807  The user can descend from this class and change any of the member
808  variable for the names of keys or the configuration file section.
809  */
810 
811 
812  // New functions for class
813  const PStringArray & GetSecuredKeys() const { return securedKeys; }
814  /* Get the list of secured keys in the configuration file section.
815 
816  @return
817  Array of strings for the secured keys.
818  */
819 
820  const PString & GetSecurityKey() const { return securityKey; }
821  /* Get the security keys name in the configuration file section.
822 
823  @return
824  String for the security values key.
825  */
826 
827  const PString & GetExpiryDateKey() const { return expiryDateKey; }
828  /* Get the expiry date keys name in the configuration file section.
829 
830  @return
831  String for the expiry date values key.
832  */
833 
834  const PString & GetOptionBitsKey() const { return optionBitsKey; }
835  /* Get the Option Bits keys name in the configuration file section.
836 
837  @return
838  String for the Option Bits values key.
839  */
840 
841  const PString & GetPendingPrefix() const { return pendingPrefix; }
842  /* Get the pending prefix name in the configuration file section.
843 
844  @return
845  String for the pending prefix.
846  */
847 
848  void GetProductKey(
849  PTEACypher::Key & productKey // Variable to receive the product key.
850  ) const;
851  /* Get the pending prefix name in the configuration file section.
852 
853  @return
854  String for the pending prefix.
855  */
856 
857 
864  };
866  /* Check the current values attached to the keys specified in the
867  constructor against an encoded validation key.
868 
869  @return
870  State of the validation keys.
871  */
872 
874  /* Validate a pending secured option list for the product. All secured
875  keys with the <CODE>pendingPrefix</CODE> name will be checked against
876  the value of the field <CODE>securityKey</CODE>. If they match then
877  they are copied to the secured variables.
878 
879  @return
880  true if secure key values are valid.
881  */
882 
883  void ResetPending();
884  /* "Unvalidate" a security configuration going back to a pending state,
885  usually used after an <CODE>Invalid</CODE> response was recieved from
886  the <A>GetValidation()</A> function.
887  */
888 
889 
890  protected:
897 };
898 
899 #endif // P_CONFIG_FILE
900 
901 #endif // PTLIB_CYPHER_H
902 
903 
904 // End Of File ///////////////////////////////////////////////////////////////