bool DoThisFile (const KFile * infile, EncScheme enc, ArcScheme * parc) { const KFile * Infile; ArcScheme arc; rc_t rc; *parc = arcNone; switch (enc) { default: STSMSG (1, ("not encrypted")); return false; case encEncFile: /* * this will apply to KEncFiles versions 1 and 2, maybe not 3 * but will hopefully become obsolete eventually. */ rc = KEncFileMakeRead (&Infile, infile, &Key); /* replace with VFSManagerOpenFileReadDirectoryRelativeInt */ if (rc) return false; break; case encSraEncFile: /* these are NCBIsenc instead of NCBInenc */ goto sra_enc_file; case encWGAEncFile: rc = KFileMakeWGAEncRead (&Infile, infile, Password, PasswordSize); if (rc) return false; break; } arc = ArchiveTypeCheck (Infile); KFileRelease (Infile); switch (arc) { default: return false; case arcNone: return true; case arcSRAFile: break; } sra_enc_file: *parc = arcSRAFile; STSMSG (1, ("encrypted sra archive\ndecryption%s requested", DecryptSraFlag ? "" : " not")); return DecryptSraFlag; }
static rc_t run() { KDirectory * pwd; rc_t rc; STSMSG (1, ("Open file system\n")); rc = KDirectoryNativeDir (&pwd); if (rc) LOGERR (klogErr, rc, "Failed to open filesystem"); else { const KFile * unencrypt; STSMSG (1, ("Open unencryptd file %s\n", UNENCRYPT)); rc = KDirectoryOpenFileRead (pwd, &unencrypt, UNENCRYPT); if (rc) LOGERR (klogErr, rc, "failed to open unencryptd file"); else { const KFile * encrypt; STSMSG (1, ("Open encryptd file %s\n", ENCRYPT)); rc = KDirectoryOpenFileRead (pwd, &encrypt, ENCRYPT); if (rc) LOGERR (klogErr, rc, "Failed to open encryptd file"); else { const KFile * decrypt; STSMSG (1, ("Open decrypt file\n")); rc = KFileMakeWGAEncRead (&decrypt, encrypt, WGA_KEY, 1); if (rc) LOGERR (klogErr, rc, "Failed to open decrypter"); else { size_t tot_readu; size_t tot_readd; size_t num_read; uint8_t * decoded = NULL; uint8_t * unencoded = NULL; int comp; decoded = calloc ( 64 * 1024, 24 ); unencoded = calloc ( 64 * 1024, 24 ); for (tot_readu = 0; rc == 0 && tot_readu < sizeof unencoded; tot_readu += num_read) { STSMSG (5, ("Read unencrypted '%u' @ %lu\n", sizeof unencoded - tot_readu, tot_readu)); rc = KFileRead (unencrypt, tot_readu, unencoded + tot_readu, sizeof unencoded - tot_readu, &num_read); if (num_read == 0) break; } if (rc == 0) { for (tot_readd = 0; rc == 0 && tot_readd < sizeof decoded; tot_readd += num_read) { STSMSG (5, ("Read decrypted '%u' @ %lu\n", sizeof decoded - tot_readd, tot_readd)); rc = KFileRead (decrypt, tot_readd, decoded + tot_readd, sizeof decoded - tot_readd, &num_read); if (num_read == 0) break; } comp = memcmp(decoded,unencoded, sizeof decoded); STSMSG (1, ("Read u '%zu' d '%zu' cmp '%d'", tot_readu, tot_readd, comp)); if (comp != 0) { rc = RC (rcExe, rcNoTarg, rcValidating, rcFile, rcInconsistent); LOGERR (klogErr, rc, "Unencryptfailed"); { size_t ix; size_t limit; size_t matched = 0; size_t mismatched = 0; limit = tot_readu; if (limit < tot_readd) limit = tot_readd; for (ix = 0; ix < limit; ++ix) { if (decoded[ix] != unencoded[ix]) { ++mismatched; STSMSG (2, ("%5.5zu: D %c %2.2X U %c %2.2X\n", ix, decoded[ix]?decoded[ix]:'?',decoded[ix], unencoded[ix]?unencoded[ix]:'?',unencoded[ix])); } else ++matched; } STSMSG (2, ("matched %zu mismatched %zu",matched,mismatched)); } } } free (decoded); free (unencoded); } KFileRelease (decrypt); } KFileRelease (encrypt); } KFileRelease (unencrypt); } KDirectoryRelease (pwd); return rc; }
/* not KDB specific - just uses vfs/krypto/kfs objects */ static rc_t KDBOpenFileAsDirectory (const KDirectory * dir, const char * path, const KDirectory ** pdir, uint32_t rcobj) { const KFile * file; const KFile * f; const KDirectory * ldir; bool encrypted = false; rc_t rc; *pdir = NULL; rc = KDirectoryOpenFileRead (dir, &file, path); if (rc == 0) { rc = KFileRandomAccess(file); if (rc) rc = RC (rcDB, rcMgr, rcOpening, rcobj, rcUnsupported); else { size_t tz; char tbuff [4096]; char pbuff [4096 + 1]; rc = KFileReadAll (file, 0, tbuff, sizeof tbuff, &tz); if (rc == 0) { if (KFileIsEnc (tbuff, tz) == 0) { encrypted = true; rc = KDBOpenFileGetPassword (pbuff, sizeof (pbuff) - 1); if (rc == 0) { KKey key; rc = KKeyInitRead (&key, kkeyAES128, pbuff, string_size (pbuff)); if (rc == 0) { rc = KEncFileMakeRead (&f, file, &key); if (rc == 0) { /* KEncFileMakeRead adds a reference */ KFileRelease (file); file = f; rc = KFileReadAll (file, 0, tbuff, sizeof tbuff, &tz); } } } } else if (KFileIsWGAEnc (tbuff, tz) == 0) { encrypted = true; rc = KDBOpenFileGetPassword (pbuff, sizeof (pbuff) - 1); if (rc == 0) { rc = KFileMakeWGAEncRead (&f, file, pbuff, string_size (pbuff)); if (rc == 0) { /* KFileMakeWGAEncRead adds a reference */ KFileRelease (file); file = f; rc = KFileReadAll (file, 0, tbuff, sizeof tbuff, &tz); } } } /* else not a handled encryption or unencrypted: we can't distinguish too much */ if (rc == 0) { if (KFileIsSRA (tbuff, tz) == 0) { rc = KDirectoryOpenSraArchiveReadUnbounded_silent_preopened (dir, &ldir, false, file, path); } else { rc = KDirectoryOpenTarArchiveRead_silent_preopened (dir, &ldir, false, file, path); } /* not an archive type we handle or a bad archive */ if (rc) { if (encrypted) rc = RC ( rcDB, rcMgr, rcOpening, rcEncryptionKey, rcIncorrect ); else rc = RC ( rcDB, rcMgr, rcOpening, rcPath, rcIncorrect ); } else { /* * release our ownership of the KFile that but archive will * keep theirs */ KFileRelease (file); *pdir = ldir; return 0; } } } } KFileRelease (file); } return rc; }
rc_t CryptFile (const KFile * in, const KFile ** new_in, KFile * out, KFile ** new_out, EncScheme scheme) { const KFile * dec; rc_t rc; assert (in); assert (out); assert (new_in); assert (new_out); rc = KFileAddRef (out); if (rc) return rc; switch (scheme) { default: case encError: rc = RC (rcExe, rcFile, rcClassifying, rcFile, rcInvalid); break; case encNone: copy: rc = KFileAddRef (in); if (rc) goto fail; *new_in = in; *new_out = out; STSMSG (1, ("not encrypted just copying")); return 0; case encEncFile: rc = KEncFileMakeRead (&dec, in, &Key); made_enc: if (rc) goto fail; switch (ArchiveTypeCheck (dec)) { default: case arcError: rc = RC (rcExe, rcFile, rcClassifying, rcFile, rcInvalid); break; case arcSRAFile: if (!DecryptSraFlag) { rc = KFileRelease (dec); if (rc) { KFileRelease (dec); KFileRelease (in); goto fail; } goto copy; } /* fall through */ case arcNone: *new_out = out; *new_in = dec; return 0; } break; case encWGAEncFile: rc = KFileMakeWGAEncRead (&dec, in, Password, PasswordSize); goto made_enc; break; } fail: KFileRelease (out); *new_in = *new_out = NULL; return rc; }
static rc_t run() { KDirectory * pwd; rc_t rc; STSMSG (1, ("Open file system")); rc = KDirectoryNativeDir (&pwd); if (rc) LOGERR (klogErr, rc, "Failed to open filesystem"); else { /* encrypt the file */ { const KFile * sourcefile; /* open source first to make sure we are in the right place */ rc = KDirectoryOpenFileRead (pwd, &sourcefile, UNENCRYPT); if (rc) LOGERR (klogErr, rc, "Failed to open source file"); else { KFile * encfile; rc = KDirectoryCreateFile (pwd, &encfile, true, 0664, kcmInit, TEST); if (rc) LOGERR (klogErr, rc, "Failed to open encrypted output"); else { KFile * writefile; rc = KFileMakeWGAEncWrite (&writefile, encfile, WGA_KEY, 1, 4096, fer_encAES); if (rc) LOGERR (klogErr, rc, "Failed to open encrypter"); else { uint64_t pos = 0; size_t num_read; uint64_t buffer [64*1024]; do { rc = KFileRead (sourcefile, pos, buffer, sizeof buffer, &num_read); if (rc) LOGERR (klogErr, rc, "Failed to read"); else if (num_read) { size_t tot_writ; size_t num_writ; for (tot_writ = 0; tot_writ < num_read; tot_writ += num_writ) { rc = KFileWrite (writefile, pos + tot_writ, buffer + tot_writ, num_read - tot_writ, &num_writ); if (rc) { LOGERR (klogErr, rc, "Failed to write"); break; } else if (num_writ == 0) { rc = -1; break; } } pos += num_read; } } while ((rc == 0) && (num_read > 0)); KFileRelease (writefile); } KFileRelease (encfile); } KFileRelease (sourcefile); } } if (rc == 0) { const KFile * unencrypt; STSMSG (1, ("Open unencryptd file %s\n", UNENCRYPT)); rc = KDirectoryOpenFileRead (pwd, &unencrypt, UNENCRYPT); if (rc) LOGERR (klogErr, rc, "failed to open unencryptd file"); else { const KFile * encrypt; STSMSG (1, ("Open encryptd file %s\n", ENCRYPT)); rc = KDirectoryOpenFileRead (pwd, &encrypt, ENCRYPT); if (rc) LOGERR (klogErr, rc, "Failed to open encryptd file"); else { const KFile * decrypt; STSMSG (1, ("Open decrypt file\n")); rc = KFileMakeWGAEncRead (&decrypt, encrypt, WGA_KEY, 1); if (rc) LOGERR (klogErr, rc, "Failed to open decrypter"); else { size_t tot_readu; size_t tot_readd; size_t num_read; uint8_t decoded [64 * 1024 * 24]; uint8_t unencoded [64 * 1024 * 24]; int comp; memset (decoded, 0, sizeof decoded); memset (unencoded, 0, sizeof unencoded); for (tot_readu = 0; rc == 0 && tot_readu < sizeof unencoded; tot_readu += num_read) { STSMSG (5, ("Read unencrypted '%u' @ %lu\n", sizeof unencoded - tot_readu, tot_readu)); rc = KFileRead (unencrypt, tot_readu, unencoded + tot_readu, sizeof unencoded - tot_readu, &num_read); if (num_read == 0) break; } if (rc == 0) { for (tot_readd = 0; rc == 0 && tot_readd < sizeof decoded; tot_readd += num_read) { STSMSG (5, ("Read decrypted '%u' @ %lu\n", sizeof decoded - tot_readd, tot_readd)); rc = KFileRead (decrypt, tot_readd, decoded + tot_readd, sizeof decoded - tot_readd, &num_read); if (num_read == 0) break; } comp = memcmp(decoded,unencoded, sizeof decoded); STSMSG (1, ("Read u '%zu' d '%zu' cmp '%d'", tot_readu, tot_readd, comp)); if (comp != 0) { rc = RC (rcExe, rcNoTarg, rcValidating, rcFile, rcInconsistent); LOGERR (klogErr, rc, "Unencryptfailed"); { size_t ix; size_t limit; size_t matched = 0; size_t mismatched = 0; limit = tot_readu; if (limit < tot_readd) limit = tot_readd; for (ix = 0; ix < limit; ++ix) { if (decoded[ix] != unencoded[ix]) { ++mismatched; STSMSG (2, ("%5.5zu: D %c %2.2X U %c %2.2X\n", ix, decoded[ix]?decoded[ix]:'?',decoded[ix], unencoded[ix]?unencoded[ix]:'?',unencoded[ix])); } else ++matched; } STSMSG (2, ("matched %zu mismatched %zu",matched,mismatched)); } } } } KFileRelease (decrypt); } KFileRelease (encrypt); } KFileRelease (unencrypt); } if (rc == 0) { const KFile * unencrypt; STSMSG (1, ("Open unencryptd file %s\n", UNENCRYPT)); rc = KDirectoryOpenFileRead (pwd, &unencrypt, UNENCRYPT); if (rc) LOGERR (klogErr, rc, "failed to open unencryptd file"); else { const KFile * encrypt; STSMSG (1, ("Open encryptd file %s\n", TEST)); rc = KDirectoryOpenFileRead (pwd, &encrypt, TEST); if (rc) LOGERR (klogErr, rc, "Failed to open encryptd file"); else { const KFile * decrypt; STSMSG (1, ("Open decrypt file\n")); rc = KFileMakeWGAEncRead (&decrypt, encrypt, WGA_KEY, 1); if (rc) LOGERR (klogErr, rc, "Failed to open decrypter"); else { size_t tot_readu; size_t tot_readd; size_t num_read; uint8_t decoded [64 * 1024 * 24]; uint8_t unencoded [64 * 1024 * 24]; int comp; memset (decoded, 0, sizeof decoded); memset (unencoded, 0, sizeof unencoded); for (tot_readu = 0; rc == 0 && tot_readu < sizeof unencoded; tot_readu += num_read) { STSMSG (5, ("Read unencrypted '%u' @ %lu\n", sizeof unencoded - tot_readu, tot_readu)); rc = KFileRead (unencrypt, tot_readu, unencoded + tot_readu, sizeof unencoded - tot_readu, &num_read); if (num_read == 0) break; } if (rc == 0) { for (tot_readd = 0; rc == 0 && tot_readd < sizeof decoded; tot_readd += num_read) { STSMSG (5, ("Read decrypted '%u' @ %lu\n", sizeof decoded - tot_readd, tot_readd)); rc = KFileRead (decrypt, tot_readd, decoded + tot_readd, sizeof decoded - tot_readd, &num_read); if (num_read == 0) break; } comp = memcmp(decoded,unencoded, sizeof decoded); STSMSG (1, ("Read u '%zu' d '%zu' cmp '%d'", tot_readu, tot_readd, comp)); if (comp != 0) { rc = RC (rcExe, rcNoTarg, rcValidating, rcFile, rcInconsistent); LOGERR (klogErr, rc, "Unencryptfailed"); { size_t ix; size_t limit; size_t matched = 0; size_t mismatched = 0; limit = tot_readu; if (limit < tot_readd) limit = tot_readd; for (ix = 0; ix < limit; ++ix) { if (decoded[ix] != unencoded[ix]) { ++mismatched; STSMSG (2, ("%5.5zu: D %c %2.2X U %c %2.2X\n", ix, decoded[ix]?decoded[ix]:'?',decoded[ix], unencoded[ix]?unencoded[ix]:'?',unencoded[ix])); } else ++matched; } STSMSG (2, ("matched %zu mismatched %zu",matched,mismatched)); } } } } KFileRelease (decrypt); } KFileRelease (encrypt); } KFileRelease (unencrypt); } } KDirectoryRelease (pwd); return rc; }