Make sure to decode manifests into utf-8 when necessary

This fixes a decoding error
This commit is contained in:
Joseph Schorr 2018-12-17 16:31:24 -05:00
parent 6cc7102ec8
commit 48e584905a
15 changed files with 268 additions and 32 deletions

View file

@ -15,7 +15,7 @@ import dateutil.parser
from jsonschema import validate as validate_schema, ValidationError
from jwkest.jws import SIGNER_ALGS, keyrep
from jwkest.jws import SIGNER_ALGS, keyrep, BadSignature
from jwt.utils import base64url_encode, base64url_decode
from digest import digest_tools
@ -23,6 +23,7 @@ from image.docker import ManifestException
from image.docker.types import ManifestImageLayer
from image.docker.interfaces import ManifestInterface
from image.docker.v1 import DockerV1Metadata
from image.docker.schemautil import ensure_utf8
logger = logging.getLogger(__name__)
@ -198,14 +199,19 @@ class DockerSchema1Manifest(ManifestInterface):
if not self._signatures:
return
payload_str = ensure_utf8(self._payload)
for signature in self._signatures:
bytes_to_verify = '{0}.{1}'.format(signature['protected'],
base64url_encode(self._payload))
bytes_to_verify = '{0}.{1}'.format(signature['protected'], base64url_encode(payload_str))
signer = SIGNER_ALGS[signature['header']['alg']]
key = keyrep(signature['header']['jwk'])
gk = key.get_key()
sig = base64url_decode(signature['signature'].encode('utf-8'))
verified = signer.verify(bytes_to_verify, sig, gk)
try:
verified = signer.verify(bytes_to_verify, sig, gk)
except BadSignature:
raise InvalidSchema1Signature()
if not verified:
raise InvalidSchema1Signature()
@ -264,7 +270,7 @@ class DockerSchema1Manifest(ManifestInterface):
@property
def digest(self):
return digest_tools.sha256_digest(self._payload)
return digest_tools.sha256_digest(ensure_utf8(self._payload))
@property
def image_ids(self):
@ -530,7 +536,7 @@ class DockerSchema1ManifestBuilder(object):
return self
def build(self, json_web_key=None):
def build(self, json_web_key=None, ensure_ascii=True):
"""
Builds a DockerSchema1Manifest object, with optional signature.
"""
@ -540,7 +546,7 @@ class DockerSchema1ManifestBuilder(object):
DOCKER_SCHEMA1_FS_LAYERS_KEY: self._fs_layer_digests,
})
payload_str = json.dumps(payload, indent=3)
payload_str = json.dumps(payload, indent=3, ensure_ascii=ensure_ascii)
if json_web_key is None:
return DockerSchema1Manifest(payload_str)
@ -551,9 +557,10 @@ class DockerSchema1ManifestBuilder(object):
'formatLength': split_point,
'time': datetime.utcnow().strftime(_ISO_DATETIME_FORMAT_ZULU),
}
protected = base64url_encode(json.dumps(protected_payload))
protected = base64url_encode(json.dumps(protected_payload, ensure_ascii=ensure_ascii))
logger.debug('Generated protected block: %s', protected)
payload_str = ensure_utf8(payload_str)
bytes_to_sign = '{0}.{1}'.format(protected, base64url_encode(payload_str))
signer = SIGNER_ALGS[_JWS_SIGNING_ALGORITHM]
@ -571,10 +578,8 @@ class DockerSchema1ManifestBuilder(object):
}
logger.debug('Encoded signature block: %s', json.dumps(signature_block))
payload.update({DOCKER_SCHEMA1_SIGNATURES_KEY: [signature_block]})
return DockerSchema1Manifest(json.dumps(payload, indent=3))
return DockerSchema1Manifest(json.dumps(payload, indent=3, ensure_ascii=ensure_ascii))
def _updated_v1_metadata(v1_metadata_json, updated_id_map):