"Fossies" - the Fresh Open Source Software Archive

Member "src/Volume/Keyfile.cpp" (10 Oct 2018, 4639 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Keyfile.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2  Derived from source code of TrueCrypt 7.1a, which is
    3  Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
    4  by the TrueCrypt License 3.0.
    5 
    6  Modifications and additions to the original source code (contained in this file)
    7  and all other portions of this file are Copyright (c) 2013-2017 IDRIX
    8  and are governed by the Apache License 2.0 the full text of which is
    9  contained in the file License.txt included in VeraCrypt binary and source
   10  code distribution packages.
   11 */
   12 
   13 #include "Platform/Serializer.h"
   14 #include "Common/SecurityToken.h"
   15 #include "Crc32.h"
   16 #include "Keyfile.h"
   17 #include "VolumeException.h"
   18 
   19 namespace VeraCrypt
   20 {
   21     void Keyfile::Apply (const BufferPtr &pool) const
   22     {
   23         if (Path.IsDirectory())
   24             throw ParameterIncorrect (SRC_POS);
   25 
   26         File file;
   27 
   28         Crc32 crc32;
   29         size_t poolPos = 0;
   30         uint64 totalLength = 0;
   31         uint64 readLength;
   32 
   33         SecureBuffer keyfileBuf (File::GetOptimalReadSize());
   34 
   35         if (SecurityToken::IsKeyfilePathValid (Path))
   36         {
   37             // Apply keyfile generated by a security token
   38             vector <byte> keyfileData;
   39             SecurityToken::GetKeyfileData (SecurityTokenKeyfile (wstring (Path)), keyfileData);
   40 
   41             if (keyfileData.size() < MinProcessedLength)
   42                 throw InsufficientData (SRC_POS, Path);
   43 
   44             for (size_t i = 0; i < keyfileData.size(); i++)
   45             {
   46                 uint32 crc = crc32.Process (keyfileData[i]);
   47 
   48                 pool[poolPos++] += (byte) (crc >> 24);
   49                 pool[poolPos++] += (byte) (crc >> 16);
   50                 pool[poolPos++] += (byte) (crc >> 8);
   51                 pool[poolPos++] += (byte) crc;
   52 
   53                 if (poolPos >= pool.Size())
   54                     poolPos = 0;
   55 
   56                 if (++totalLength >= MaxProcessedLength)
   57                     break;
   58             }
   59 
   60             Memory::Erase (&keyfileData.front(), keyfileData.size());
   61             goto done;
   62         }
   63 
   64         file.Open (Path, File::OpenRead, File::ShareRead);
   65 
   66         while ((readLength = file.Read (keyfileBuf)) > 0)
   67         {
   68             for (size_t i = 0; i < readLength; i++)
   69             {
   70                 uint32 crc = crc32.Process (keyfileBuf[i]);
   71 
   72                 pool[poolPos++] += (byte) (crc >> 24);
   73                 pool[poolPos++] += (byte) (crc >> 16);
   74                 pool[poolPos++] += (byte) (crc >> 8);
   75                 pool[poolPos++] += (byte) crc;
   76 
   77                 if (poolPos >= pool.Size())
   78                     poolPos = 0;
   79 
   80                 if (++totalLength >= MaxProcessedLength)
   81                     goto done;
   82             }
   83         }
   84 done:
   85         if (totalLength < MinProcessedLength)
   86             throw InsufficientData (SRC_POS, Path);
   87     }
   88 
   89     shared_ptr <VolumePassword> Keyfile::ApplyListToPassword (shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> password)
   90     {
   91         if (!password)
   92             password.reset (new VolumePassword);
   93 
   94         if (!keyfiles || keyfiles->size() < 1)
   95             return password;
   96 
   97         KeyfileList keyfilesExp;
   98         HiddenFileWasPresentInKeyfilePath = false;
   99 
  100         // Enumerate directories
  101         foreach (shared_ptr <Keyfile> keyfile, *keyfiles)
  102         {
  103             if (FilesystemPath (*keyfile).IsDirectory())
  104             {
  105                 size_t keyfileCount = 0;
  106                 foreach_ref (const FilePath &path, Directory::GetFilePaths (*keyfile))
  107                 {
  108 #ifdef TC_UNIX
  109                     // Skip hidden files
  110                     if (wstring (path.ToBaseName()).find (L'.') == 0)
  111                     {
  112                         HiddenFileWasPresentInKeyfilePath = true;
  113                         continue;
  114                     }
  115 #endif
  116                     keyfilesExp.push_back (make_shared <Keyfile> (path));
  117                     ++keyfileCount;
  118                 }
  119 
  120                 if (keyfileCount == 0)
  121                     throw KeyfilePathEmpty (SRC_POS, FilesystemPath (*keyfile));
  122             }
  123             else
  124             {
  125                 keyfilesExp.push_back (keyfile);
  126             }
  127         }
  128 
  129         make_shared_auto (VolumePassword, newPassword);
  130 
  131         if (keyfilesExp.size() < 1)
  132         {
  133             newPassword->Set (*password);
  134         }
  135         else
  136         {
  137             SecureBuffer keyfilePool (VolumePassword::MaxSize);
  138 
  139             // Pad password with zeros if shorter than max length
  140             keyfilePool.Zero();
  141             keyfilePool.CopyFrom (ConstBufferPtr (password->DataPtr(), password->Size()));
  142 
  143             // Apply all keyfiles
  144             foreach_ref (const Keyfile &k, keyfilesExp)
  145             {
  146                 k.Apply (keyfilePool);
  147             }
  148 
  149             newPassword->Set (keyfilePool);
  150         }
  151 
  152         return newPassword;
  153     }
  154 
  155     shared_ptr <KeyfileList> Keyfile::DeserializeList (shared_ptr <Stream> stream, const string &name)
  156     {
  157         shared_ptr <KeyfileList> keyfiles;
  158         Serializer sr (stream);
  159 
  160         if (!sr.DeserializeBool (name + "Null"))
  161         {
  162             keyfiles.reset (new KeyfileList);
  163             foreach (const wstring &k, sr.DeserializeWStringList (name))
  164                 keyfiles->push_back (make_shared <Keyfile> (k));
  165         }
  166         return keyfiles;
  167     }
  168 
  169     void Keyfile::SerializeList (shared_ptr <Stream> stream, const string &name, shared_ptr <KeyfileList> keyfiles)
  170     {
  171         Serializer sr (stream);
  172         sr.Serialize (name + "Null", keyfiles == nullptr);
  173         if (keyfiles)
  174         {
  175             list <wstring> sl;
  176 
  177             foreach_ref (const Keyfile &k, *keyfiles)
  178                 sl.push_back (FilesystemPath (k));
  179 
  180             sr.Serialize (name, sl);
  181         }
  182     }
  183 
  184     bool Keyfile::HiddenFileWasPresentInKeyfilePath = false;
  185 }