Main Page | Data Structures | File List | Data Fields | Globals

example_restore.c File Reference


Detailed Description

The config.xml for the Linux restore client.

The restore client requires the RSA key information in addition to the contents from the escrow client config.xml file. All of the RSA data is in hex values. (This includes the public exponent: 65537 = 0x10001)

The following OpenSSL commands will create a suitable rsa public/private key pair.

  openssl genrsa -out genrsa.txt
  openssl rsa -in genrsa.txt -pubout -text

The contents from the "modulus", "publicExponent" and "privateExponent" are copied into the config file: RSA_MODULUS, RSA_PUBLIC and RSA_PRIVATE respectively. (Be sure the publicExponent is entered in hex.)

   <ESCROW>
 
       <RSA_MODULUS> 
           00:c6:83:9f:08:79:d0:60:66:dc:52:52:c1:52:f4:
           60:8d:6e:40:57:60:ee:5a:9c:f4:28:9c:30:ca:05:
           e9:f7:82:2e:53:48:15:3b:47:89:cd:76:de:04:09:
           fe:fb:b9:48:63:e8:5c:dd:2e:60:b7:d6:47:34:4e:
           9b:1f:9b:9d:77
       </RSA_MODULUS>

       <RSA_PUBLIC> 
           10001 
       </RSA_PUBLIC>

       <RSA_PRIVATE>     
           0a:77:e6:6b:0c:01:71:13:fb:8a:5b:d2:d6:0d:0d:
           0a:68:45:fc:55:a0:3c:27:0a:b9:19:83:79:23:d6:
           b2:b6:92:c5:e3:60:a0:34:69:1f:18:e3:28:09:5b:
           07:c7:74:7e:98:01:55:8e:2f:4b:44:85:ce:bc:e1:
           7c:f2:94:01
       </RSA_PRIVATE>

 

       <SSL_CLIENT_CERT> 

           /usr/share/ssl/certs/ca_cert.pem

       </SSL_CLIENT_CERT>

       <SERVER_NAME> 

           lagrange.wfunet.wfu.edu 

       </SERVER_NAME>

       <TCP_PORT> 

           1111 

       </TCP_PORT>

   </ESCROW>

Patch files

This is the patch to add the escrow ability to the Cli.c file.

To use this patch you will also need to include the escrow patch

 patch Common/Volumes.c    < ../linux/Volumes.patch
 patch Linux/Cli/Cli.c     < ../linux/Cli.restore_patch
 patch Linux/Cli/Cli.c     < ../linux/Cli.escrow_patch
 patch Linux/Cli/Makefile  < ../linux/Makefile.patch

Patch for Cli.c (Cli.restore_patch)

--- Cli_original.c      2007-08-08 20:52:40.000000000 -0400
+++ Cli_restore.c       2007-08-22 19:08:55.000000000 -0400
@@ -2941,8 +2941,444 @@
        error ("%s not mounted\n", text);
        return FALSE;
 }
 
+
+
+
+#define WFU_NORMAL 0
+
+
+#define WFU_HIDDEN 1
+
+#include "WFU.h"
+#include "libconfig.h"
+
+
+
+static int WFU_is_header_backup(char *volumePath)
+  {
+    struct stat volumeStat;
+    int ret = 0;
+
+    memset (&volumeStat, 0, sizeof (volumeStat));
+
+    /* stat 
+     * On success, zero is returned.  
+     * On error, -1 is returned, and errno is set appropriately.
+     */
+
+    ret = stat (volumePath, &volumeStat);
+
+    // check for stat error
+    if ( ret < 0) return -1;
+
+    // does it look like a header backup?
+    if (volumeStat.st_size == (2 * HEADER_SIZE)) return 1;
+
+    return 0;
+  }
+
+
+
+static char *WFU_ReadHeader(char *volumePath, int type, int is_header_backup)
+  {
+    struct stat volumeStat;
+    FILE *f = NULL;
+    static char header[PKCS5_SALT_SIZE];
+
+    memset (&volumeStat, 0, sizeof (volumeStat));
+    if ((!UpdateTime || ReadOnly) && IsFile (volumePath) && stat (volumePath, &volumeStat) != 0)
+      {
+        perror ("Cannot open volume");
+        volumeStat.st_ctime = 0;
+        goto err;
+      }
+
+    f = fopen (volumePath, "rb");
+    if (!f)
+      {
+        perror ("Cannot open volume");
+        goto err;
+      }
+
+    // Normal header
+    if (type == WFU_NORMAL)
+      {
+        fseek (f, 0, SEEK_SET);
+        //if (fread (header, 1, SECTOR_SIZE, f) != SECTOR_SIZE)
+        if (fread (header, 1, PKCS5_SALT_SIZE, f) != PKCS5_SALT_SIZE)
+          {
+            perror ("Cannot read volume header");
+            goto err;
+          }
+        fclose (f);
+        return header;
+      }
+    else if (type == WFU_HIDDEN)
+      {
+        // Hidden header
+        if (fseek (f, -(is_header_backup?HEADER_SIZE:HIDDEN_VOL_HEADER_OFFSET), SEEK_END) == -1
+                || fread (header, 1, PKCS5_SALT_SIZE, f) != PKCS5_SALT_SIZE)
+          {
+                perror ("Cannot read hidden volume header");
+                goto err;
+          }
+        fclose (f);
+        return header;
+      }
+
+    fclose (f);
+    return NULL;
+
+err:
+    if (f) fclose (f);
+
+    if (volumeStat.st_ctime != 0 && !UpdateTime)
+      RestoreFileTime (volumePath, volumeStat.st_mtime, volumeStat.st_atime);
+
+    return NULL;
+  }
+
+
+
+static BOOL WFU_Restore (char *username, char *volumePath)
+  {
+    char header[HEADER_SIZE];
+    char path[TC_MAX_PATH];
+    Password *pw = &password;
+    PCRYPTO_INFO ci = NULL, ci2 = NULL;
+    unsigned long long startSector, totalSectors;
+    time_t modTime = 0, acTime;
+    int wipePass, ret = FALSE;
+    int fd = -1, r;
+    FILE *f;
+    struct wfu_data salt;
+    struct wfu_data *src = NULL;
+    struct wfu_line_array *line_array = NULL;
+    int j;
+    int is_header_backup = 0;
+
+    // Password buffer
+    static Password WFU_password;
+    Password WFU_passwd;
+
+    // Username buffer
+    static char WFU_username[WFU_MAX_USERNAME];
+
+    // Username and password as a null terminated string
+    char *WFU_username_string = NULL;
+    char *WFU_passwd_string = NULL;
+    char *WFU_header = NULL;
+    char *WFU_config_file = NULL;
+
+    /*
+     * Are we going to restore to a real TrueCrypt volume or
+     * a header backup file.  A backup file is 2*HEADER_SIZE.
+     */
+
+    is_header_backup = WFU_is_header_backup(volumePath);
+
+
+    /* read the configuration file */
+    WFU_config_file = WFU_get_config_path();
+
+    if (! WFU_config_file) 
+      {
+        printf("ERROR: Cannot read config file: ~/%s/%s\n",WFU_ESCROW_DIR,WFU_ESCROW_CFG);
+        return 0;
+      }
+
+    WFU_parse_config(WFU_config_file);
+
+    // null out the username buffer
+    memset(WFU_username,0,sizeof(WFU_username));
+    strncpy(WFU_username,username,WFU_MAX_USERNAME); // set the default
+
+    // set the pointer for the username string to the beginning of the buffer
+    WFU_username_string = WFU_username;
+
+    // get the username
+    while (!WFU_username_string || !WFU_username_string[0])
+      {
+        WFU_username_string = AskString (WFU_USERNAME_PROMPT, WFU_username, sizeof (WFU_username));
+      }
+
+    AskPassword (WFU_PASSWD_PROMPT, WFU_username_string, &WFU_passwd, FALSE);
+
+    /* 
+     * Make a null terminated copy of the password for use in our escrow function
+     */
+
+    // Allocate the memory +1 for the null
+    WFU_passwd_string = (char*) malloc( (1 + WFU_passwd.Length) * sizeof(char) );
+
+    //copy the characters
+    strncpy(WFU_passwd_string,WFU_passwd.Text,WFU_passwd.Length);
+
+    //add a null
+    WFU_passwd_string[WFU_passwd.Length] = '\0';
+
+    // Volume path
+    volumePath = AskVolumePath (volumePath, "Enter volume path");
+
+    /* 
+     * Query by salt 
+     */
+    printf("\nChecking the server for possible matches...\n");
+
+    /* Prepare salt from the Normal Header */
+    WFU_header = WFU_ReadHeader(volumePath, WFU_NORMAL, is_header_backup);
+
+    if (! WFU_header) goto err;
+
+    salt.text = (unsigned char*) WFU_header;
+    salt.len = WFU_SIZE_SALT;
+
+    // query
+    line_array = WFU_lib_query_salt(WFU_username_string,WFU_passwd_string,&salt);
+
+    if (WFU_check_errors()) goto err;
+
+
+    printf("\n");
+    printf("Normal header search: %d\n",WFU_line_array_len(line_array));
+    printf("\n");
+    for (j=0; j<WFU_line_array_len(line_array); j++)
+      printf("  %s\n",WFU_line_array_get(line_array,j));
+    printf("\n");
+
+    WFU_free_wfu_line_array(line_array);
+
+    /* Prepare salt from the Hidden Header */
+    WFU_header = WFU_ReadHeader(volumePath, WFU_HIDDEN, is_header_backup);
+
+    if (WFU_header) 
+      {
+        salt.text = (unsigned char*) WFU_header;
+        salt.len = WFU_SIZE_SALT;
+
+        // query
+        line_array = WFU_lib_query_salt(WFU_username_string,WFU_passwd_string,&salt);
+
+        if (WFU_check_errors()) goto err;
+
+        if (WFU_line_array_len(line_array) > 0)
+          {
+            printf("\n");
+            printf("Hidden header search: %d\n",WFU_line_array_len(line_array));
+            printf("\n");
+            for (j=0; j<WFU_line_array_len(line_array); j++)
+              printf("  %s\n",WFU_line_array_get(line_array,j));
+            printf("\n");
+          }
+        WFU_free_wfu_line_array(line_array);
+      }
+    else
+      printf("Cannot read hidden header\n");
+
+    // ask user for PK number
+    char str[128];
+    long pk_long = 0;
+    int  pk = 0;
+
+    while (! (AskString ("Enter PK number ", str, sizeof (str))
+                && (0 < (pk_long = strtol(str, (char **) NULL, 10)))) )
+      {
+        // assume a username in str.  
+        line_array = WFU_lib_query_user(WFU_username_string,WFU_passwd_string,str);
+
+        if (WFU_check_errors()) goto err;
+
+        if (WFU_line_array_len(line_array) > 0)
+          {
+            printf("\n");
+            printf("Username search: %d\n",WFU_line_array_len(line_array));
+            printf("\n");
+            for (j=0; j<WFU_line_array_len(line_array); j++)
+              printf("  %s\n",WFU_line_array_get(line_array,j));
+            printf("\n");
+          }
+        WFU_free_wfu_line_array(line_array);
+      }
+
+    puts ("");
+    pk = (int) pk_long;
+
+    src = WFU_lib_reclaim_keys(WFU_username_string,WFU_passwd_string,pk);
+
+
+    if (! src)
+      {
+        printf("Error retrieving restore information\n");
+        WFU_check_errors(); 
+        goto err;
+      }
+
+    if (WFU_check_errors()) goto err;
+
+    ci = (PCRYPTO_INFO) src->text;
+
+    puts ("");
+
+
+    if (!CmdPassword2Valid)
+      {
+        while (1)
+          {
+            AskPassword ("Enter new password for '%s': ", volumePath, &password, TRUE);
+            if (!DisplayPassword)
+              {
+                Password pv;
+                AskPassword ("Re-enter new password%s", ": ", &pv, TRUE);
+                if (password.Length != pv.Length || memcmp (password.Text, pv.Text, pv.Length))
+                  {
+                    puts ("Passwords do not match.\n");
+                    continue;
+                  }
+              }
+            break;
+          }
+        puts ("");
+      }
+    else
+      {
+        if (!ValidatePassword (&CmdPassword2, TRUE))
+            goto err;
+
+        pw = &CmdPassword2;
+      }
+
+    fd = open (volumePath, O_RDWR | O_SYNC);
+    if (fd == -1)
+      {
+        perror ("Cannot open file or device");
+            goto err;
+      }
+
+    OpenMiceDevice ();
+    if (!RandFillPool ())
+            goto err;
+
+    f = fdopen (fd, "r+b");
+
+    // Write a new volume header
+    for (wipePass = 0; wipePass < DISK_WIPE_PASSES; wipePass++)
+      {
+        BOOL wipeMode = wipePass < DISK_WIPE_PASSES - 1;
+
+        if (Verbose)
+          {
+            printf ("\rWriting header (pass %d)%s", wipePass, wipeMode ? "" : "\n");
+            fflush (stdout);
+          }
+        r = VolumeWriteHeader (header,
+                        ci->ea,
+                        ci->mode,
+                        pw,
+                        HashAlgorithm == 0 ? ci->pkcs5 : HashAlgorithm,
+                        (char *)ci->master_key,
+                        ci->volume_creation_time,
+                        &ci2,
+                        ci->hiddenVolumeSize,
+                        wipeMode);
+
+        if (r == ERR_CIPHER_INIT_WEAK_KEY)
+          {
+            error ("A weak or a potentially weak key has been generated. Please try again.\n");
+            goto err;
+          }
+
+        if (r != 0)
+          {
+            error ("Volume header creation failed.\n");
+            goto err;
+          }
+
+        crypto_close (ci2);
+        ci2 = NULL;
+        if (ci->hiddenVolumeSize)
+          {
+            if (fseek (f, -(is_header_backup?HEADER_SIZE:HIDDEN_VOL_HEADER_OFFSET), SEEK_END) == -1)
+              {
+                perror ("Cannot seek to hidden volume header location");
+                goto err;
+              }
+          }
+        else
+          {
+            if (fseek (f, 0, SEEK_SET) == -1)
+              {
+                perror ("Cannot seek to volume header location");
+                goto err;
+              }
+          }
+
+        if (fwrite (header, 1, HEADER_SIZE, f) != HEADER_SIZE)
+          {
+            perror ("Cannot write volume header");
+            goto err;
+          }
+
+        fflush (f);
+        fdatasync (fd);
+      }
+    if (Verbose)
+        puts ("");
+
+    printf ("Password %schanged.\n", FirstKeyFile && FirstNewKeyFile ? "and/or keyfile(s) " : "");
+
+    if (!FirstKeyFile && FirstNewKeyFile)
+        puts ("Keyfiles added.");
+
+    if (FirstKeyFile && !FirstNewKeyFile)
+        puts ("Keyfiles removed.");
+
+    ret = TRUE;
+
+err:
+
+    if (ci)
+        crypto_close (ci);
+
+    if (fd != -1)
+        close (fd);
+
+    Randfree ();
+    return ret;
+  }
+
 
 int main (int argc, char **argv)
 {
        char *volumePath = NULL;
@@ -3034,12 +3470,28 @@
 
        if (tcgetattr (0, &TerminalAttributes) == 0)
                IsTerminal = TRUE;
 
-       while ((o = getopt_long (argc, argv, "c::C::d::hik:K:l::M:N:p:PruvV", longOptions, &optIndex)) != -1)
+       while ((o = getopt_long (argc, argv, "R:c::C::d::hik:K:l::M:N:p:PruvV", longOptions, &optIndex)) != -1)
        {
                switch (o)
                {
+                case 'R': /* This is the restore option added by WFU */
+                        {
+                          char *username = NULL;
+
+                          username = optarg;
+
+                          char *hostPath = NULL;
+                          if (optind < argc)
+                            {
+                              hostPath = argv[optind++];
+
+                              if (optind < argc)
+                                goto usage;
+                            }
+                          return WFU_Restore(username, hostPath) ? 0 : 1;
+                        }
                case 'c':
                        {
                                char *hostPath = NULL;
                                if (optind < argc)

Generated on Wed Oct 10 12:38:20 2007 for WFUCrypt by  doxygen 1.3.9.1