Source code for craft_parts.sources.checksum
# -*- 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."""
from pathlib import Path
from typing import Tuple
from craft_parts.utils import file_utils
from . import errors
[docs]def split_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)
except ValueError as err:
raise ValueError(f"invalid checksum format: {source_checksum!r}") from err
return (algorithm, digest)
[docs]def verify_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)
if digest != calculated_digest:
raise errors.ChecksumMismatch(expected=digest, obtained=calculated_digest)
return (algorithm, digest)