private function readBlock() { if (!$this->canRead()) { return false; } $bl = $this->base->readInt(); if (!$bl->equalsInt($this->currentIndex)) { return false; } $this->currentIndex++; $hash = $this->base->read(32); if ($hash == null || strlen($hash) != 32) { return false; } // Won't work if $blockSize is bigger than 2**31 $blockSize = $this->base->readInt()->asInt(); if ($blockSize <= 0) { return false; } $block = $this->base->read($blockSize); if ($block == null || strlen($block) != $blockSize) { return false; } if ($this->verify && strcmp($hash, $this->h->hash($block)) != 0) { KeePassPHP::printDebug("Corrupted data !"); return false; } $this->currentBlock = $block; $this->currentSize = $blockSize; $this->currentPos = 0; return true; }
/** * Tries to parse the given string $xmlsource, assumed to be data formatted * in XML, with the format of a KeePass 2.x database. Returns true * if the parsing succeeds, or false otherwise ; in case of success, * the attribute $this->entries will contain the result of the parsing, * as an array of entries. * @param string $xmlsource * @return boolean */ private function tryXMLParse($xmlsource) { $xml = new XMLStackReader(); if (!$xml->XML($xmlsource)) { $xml->close(); return false; } if (!$xml->read() || $xml->r->name != self::XML_FILEROOT) { $xml->close(); return false; } $expectedParentsMeta = array(self::XML_FILEROOT, self::XML_META); if (!$xml->readUntilParentsBe($expectedParentsMeta)) { $xml->close(); return false; } $isHeaderChecked = false; $d = $xml->r->depth; while ($xml->isInSubtree($d)) { if ($xml->r->name == self::XML_HEADERHASH) { $hash = base64_decode($this->readTextValueFromXML($xml)); if (strcmp($hash, $this->header->headerHash) != 0) { KeePassPHP::printDebug("Bad HeaderHash !"); } $isHeaderChecked = true; } elseif ($xml->r->name == self::XML_CUSTOMICONS) { foreach ($xml->readInnerXML($xml->r->depth) as $icon) { $uuid = null; $data = null; if ($icon[XMLStackReader::NODENAME] == self::XML_ICON && $this->tryReadTextValueFromArray($icon[XMLStackReader::INNER], self::XML_UUID, $uuid) && $this->tryReadTextValueFromArray($icon[XMLStackReader::INNER], self::XML_ICON_DATA, $data)) { $this->icons->addIcon($uuid, $data); } } } } if (!$isHeaderChecked) { KeePassPHP::printDebug("Did not found HeaderHash text node..."); } $this->rawEntries = array(); $expectedParents = array(self::XML_GROUP, self::XML_ENTRY); while ($xml->readUntilParentsBe($expectedParents)) { $entry = array(); $d = $xml->r->depth; while ($xml->isInSubtree($d)) { if ($xml->r->name == self::XML_UUID) { $entry[self::XML_UUID] = bin2hex(base64_decode($this->readTextValueFromXML($xml))); } elseif ($xml->r->name == self::XML_CUSTOMICONUUID) { $entry[self::XML_CUSTOMICONUUID] = $this->readTextValueFromXML($xml); } elseif ($xml->r->name == self::XML_TAGS) { $entry[self::XML_TAGS] = $this->readTextValueFromXML($xml); } elseif ($xml->r->name == self::XML_TIMES) { $value = null; $isHistory = $xml->isAncestor(self::XML_HISTORY); $inner = $xml->readInnerXML($xml->r->depth); if ($this->tryReadTextValueFromArray($inner, self::XML_CREATION_TIME, $value)) { if ($value != null && !$isHistory) { $entry[self::XML_CREATION_TIME] = $value; } } } elseif ($xml->r->name == self::XML_STRING) { $key = null; $value = null; $isHistory = $xml->isAncestor(self::XML_HISTORY); $inner = $xml->readInnerXML($xml->r->depth); if ($this->tryReadTextValueFromArray($inner, self::XML_STRING_VALUE, $value) && $this->tryReadTextValueFromArray($inner, self::XML_STRING_KEY, $key)) { if ($key != null && $value != null && !$isHistory) { $entry[$key] = $value; } } } } if (count($entry) > 0) { array_push($this->rawEntries, $entry); } } $xml->close(); return true; }
public function parse(Reader $reader) { $dreader = new DigestReader($reader); $sig1 = $dreader->readInt(); $sig2 = $dreader->readInt(); if (!$sig1->equalsString(self::SIGNATURE1) || !$sig2->equalsString(self::SIGNATURE2)) { KeePassPHP::printDebug("Bad database file !"); return false; } $version = $dreader->readInt(); if ($version->lsr(2)->asShort() < self::MINIMAL_VERSION) { KeePassPHP::printDebug("Database version not supported !"); return false; } $ended = false; while (!$ended) { $headerId = $dreader->readByte()->asByte(); $headerLen = $dreader->readShort()->asShort(); $header = $dreader->read($headerLen); /* * end of header */ if ($headerId == 0) { $ended = true; } elseif ($headerId == 1) { } elseif ($headerId == 2) { if (strcmp($header, self::CIPHER_AES) == 0) { $this->cipher = new CipherMcrypt(CipherMcrypt::AES128); } } elseif ($headerId == 3) { $res = Binary::fromString($header)->asInt(); if ($res == 0) { $this->compression = self::COMPRESSION_NONE; } elseif ($res == 1) { $this->compression = self::COMPRESSION_GZIP; } } elseif ($headerId == 4) { if (strlen($header) == self::SEED_LEN) { $this->masterSeed = $header; } } elseif ($headerId == 5) { if (strlen($header) == self::SEED_LEN) { $this->transformSeed = $header; } } elseif ($headerId == 6) { $this->rounds = Binary::fromString($header, $headerLen); } elseif ($headerId == 7) { $this->encryptionIV = $header; } elseif ($headerId == 8) { $this->randomStreamKey = $header; } elseif ($headerId == 9) { if (strlen($header) == self::STARTBYTES_LEN) { $this->startBytes = $header; } } elseif ($headerId == 10) { $res = Binary::fromString($header)->asInt(); /*if($res == 1) // unsuported $this->innerRandomStream= self::INNER_RANDOM_ARC4; else*/ if ($res == 2) { $this->innerRandomStream = self::INNER_RANDOM_SALSA20; } } } $this->headerHash = $dreader->GetDigest(); }