LIB_EXPORT rc_t CC XFS_InitKKey_ZHR ( const char * EncPass, const char * EncType, struct KKey * Key ) { rc_t RCt; KKeyType Type; RCt = 0; Type = kkeyNone; XFS_CAN ( EncPass ) XFS_CAN ( Key ) RCt = XFS_KeyType_ZHR ( EncType, & Type ); if ( RCt == 0 ) { RCt = KKeyInitRead ( Key, Type, EncPass, string_size ( EncPass ) ); } return RCt; } /* XFS_InitKey_ZHR () */
rc_t ArchiveAndEncrypt(KDirectory* wd, const char* inpath, const char* outpath, const char* passwd) { const KDirectory* d; rc_t rc = KDirectoryOpenDirRead (wd, &d, false, "%s", inpath); if (rc == 0) { const KFile* infile; rc_t rc2; rc = KDirectoryOpenTocFileRead (d, &infile, 4, NULL, NULL, NULL); if (rc == 0) { KFile* outfile; /* if the file exists, add write access */ KDirectorySetAccess( wd, false, 0600, 0777, "%s", outpath ); rc = KDirectoryCreateFile(wd, &outfile, false, 0600, kcmCreate|kcmInit, "%s", outpath); if ( rc == 0 ) { KFile* enc_outfile; KKey key; rc = KKeyInitRead(&key, kkeyAES256, passwd, string_measure(passwd, NULL)); if ( rc == 0 ) rc = KEncFileMakeWrite(&enc_outfile, outfile, &key); if (rc == 0) rc = copy_file(infile, enc_outfile); rc2 = KFileRelease(outfile); if (rc == 0) rc = rc2; /* remove write access */ rc2 = KDirectorySetAccess( wd, false, 0400, 0777, "%s", outpath ); if (rc == 0) rc = rc2; rc2 = KFileRelease(enc_outfile); if (rc == 0) rc = rc2; } rc2 = KFileRelease(infile); if (rc == 0) rc = rc2; } rc2 = KDirectoryRelease(d); if (rc == 0) rc = rc2; } return rc; }
rc_t OpenDatabase(KKeyRing* self) { rc_t rc; const KFile* enc_infile; assert(self); rc = KDirectoryOpenFileRead(self->wd, &enc_infile, "%s", self->path); if ( rc == 0) { rc_t rc2; const KFile* infile; KKey key; rc = KKeyInitRead(&key, kkeyAES256, self->passwd, string_measure(self->passwd, NULL)); if ( rc == 0 ) { rc = KEncFileMakeRead (&infile, enc_infile, &key); if (rc == 0) { const KDirectory* arc; rc = KDirectoryOpenArcDirRead_silent_preopened(self->wd, &arc, true, "/keyring", tocKFile, (void*)infile, KArcParseSRA, NULL, NULL); if (rc == 0) { /* Hack: we violate the KDirectory object interface in order for VDBManagerMakeUpdate to succeed, since it would refuse to open a read-only dir (i.e. archive); We will only read from the object, though. */ ((KDirectory*)arc)->read_only = false; rc = KeyRingDatabaseLoad(self->data, arc, "/keyring"); rc2 = KDirectoryRelease(arc); if (rc == 0) rc = rc2; } rc2 = KFileRelease(infile); if (rc == 0) rc = rc2; } } rc2 = KFileRelease(enc_infile); if (rc == 0) rc = rc2; } return rc; }
static rc_t StartFileSystem (const char * src, const char * dst) { VFSManager * vmanager; rc_t rc; rc = VFSManagerMake (&vmanager); if (rc) LOGERR (klogErr, rc, "Failed to open file system"); else { rc = VFSManagerGetKryptoPassword (vmanager, Password, sizeof Password, &PasswordSize); if (rc != 0) LOGERR (klogErr, rc, "unable to obtain a password"); else { rc = KKeyInitRead (&Key, kkeyAES128, Password, PasswordSize); if (rc) LOGERR (klogErr, rc, "Unable to make encryption/decryption key"); else { KDirectory * cwd; rc = VFSManagerGetCWD (vmanager, &cwd); if (rc) LOGERR (klogInt, rc, "unable to access current directory"); else { rc = Start (cwd, src, dst); KDirectoryRelease (cwd); } } } VFSManagerRelease (vmanager); } 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; }