Make sure to decode manifests into utf-8 when necessary
This fixes a decoding error
This commit is contained in:
parent
6cc7102ec8
commit
48e584905a
15 changed files with 268 additions and 32 deletions
|
|
@ -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):
|
||||
|
|
|
|||
Reference in a new issue