# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-## Copyright 2017-2021 Canonical Ltd.## This program is free software; you can redistribute it and/or# modify it under the terms of the GNU Lesser General Public# License version 3 as published by the Free Software Foundation.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU# Lesser General Public License for more details.## You should have received a copy of the GNU Lesser General Public License# along with this program. If not, see <http://www.gnu.org/licenses/>."""Helpers to compute and verify file checksums."""frompathlibimportPathfromcraft_parts.utilsimportfile_utilsfrom.importerrors
[docs]defsplit_checksum(source_checksum:str)->tuple:"""Split the given source checksum into algorithm and hash. :param source_checksum: Source checksum in algorithm/hash format. :return: a tuple consisting of the algorithm and the hash. :raise ValueError: If the checksum is not in the expected format. """try:algorithm,digest=source_checksum.split("/",1)exceptValueErroraserr:raiseValueError(f"invalid checksum format: {source_checksum!r}")fromerrreturn(algorithm,digest)
[docs]defverify_checksum(source_checksum:str,checkfile:Path)->tuple:"""Verify that checkfile corresponds to the given source checksum. :param source_checksum: Source checksum in algorithm/hash format. :param checkfile: The file to calculate the sum for with the algorithm defined in source_checksum. :return: A tuple consisting of the algorithm and the hash. :raise ValueError: If source_checksum is not of the form algorithm/hash. :raise ChecksumMismatch: If checkfile does not match the expected hash calculated with the algorithm defined in source_checksum. """algorithm,digest=split_checksum(source_checksum)calculated_digest=file_utils.calculate_hash(checkfile,algorithm=algorithm)ifdigest!=calculated_digest:raiseerrors.ChecksumMismatch(expected=digest,obtained=calculated_digest)return(algorithm,digest)