signature/signature.go
func (s *untrustedSignature) strictUnmarshalJSON(data []byte) error {
	var critical, optional json.RawMessage
	if err := paranoidUnmarshalJSONObjectExactFields(data, map[string]interface{}{
		"critical": &critical,
		"optional": &optional,
	}); err != nil {
		return err
	}

	var creatorID string
	var timestamp float64
	var gotCreatorID, gotTimestamp = false, false
	if err := paranoidUnmarshalJSONObject(optional, func(key string) interface{} {
		switch key {
		case "creator":
			gotCreatorID = true
			return &creatorID
		case "timestamp":
			gotTimestamp = true
			return &timestamp
		default:
			var ignore interface{}
			return &ignore
		}
	}); err != nil {
		return err
	}
	if gotCreatorID {
		s.UntrustedCreatorID = &creatorID
	}
	if gotTimestamp {
		intTimestamp := int64(timestamp)
		if float64(intTimestamp) != timestamp {
			return InvalidSignatureError{msg: "Field optional.timestamp is not is not an integer"}
		}
		s.UntrustedTimestamp = &intTimestamp
	}

	var t string
	var image, identity json.RawMessage
	if err := paranoidUnmarshalJSONObjectExactFields(critical, map[string]interface{}{
		"type":     &t,
		"image":    &image,
		"identity": &identity,
	}); err != nil {
		return err
	}
	if t != signatureType {
		return InvalidSignatureError{msg: fmt.Sprintf("Unrecognized signature type %s", t)}
	}

	var digestString string
	if err := paranoidUnmarshalJSONObjectExactFields(image, map[string]interface{}{
		"docker-manifest-digest": &digestString,
	}); err != nil {
		return err
	}
	s.UntrustedDockerManifestDigest = digest.Digest(digestString)

	return paranoidUnmarshalJSONObjectExactFields(identity, map[string]interface{}{
		"docker-reference": &s.UntrustedDockerReference,
	})
}
func (s *untrustedSignature) strictUnmarshalJSON(data []byte) error {
	var critical, optional json.RawMessage
	if err := paranoidUnmarshalJSONObjectExactFields(data, map[string]interface{}{
		"critical": &critical,
		"optional": &optional,
	}); err != nil {
		return err
	}

	var creatorID string
	var timestamp float64
	var gotCreatorID, gotTimestamp = false, false
	if err := paranoidUnmarshalJSONObject(optional, func(key string) interface{} {
		switch key {
		case "creator":
			gotCreatorID = true
			return &creatorID
		case "timestamp":
			gotTimestamp = true
			return &timestamp
		default:
			var ignore interface{}
			return &ignore
		}
	}); err != nil {
		return err
	}
	if gotCreatorID {
		s.UntrustedCreatorID = &creatorID
	}
	if gotTimestamp {
		intTimestamp := int64(timestamp)
		if float64(intTimestamp) != timestamp {
			return InvalidSignatureError{msg: "Field optional.timestamp is not is not an integer"}
		}
		s.UntrustedTimestamp = &intTimestamp
	}

	var t string
	var image, identity json.RawMessage
	if err := paranoidUnmarshalJSONObjectExactFields(critical, map[string]interface{}{
		"type":     &t,
		"image":    &image,
		"identity": &identity,
	}); err != nil {
		return err
	}
	if t != signatureType {
		return InvalidSignatureError{msg: fmt.Sprintf("Unrecognized signature type %s", t)}
	}

	var digestString string
	if err := paranoidUnmarshalJSONObjectExactFields(image, map[string]interface{}{
		"docker-manifest-digest": &digestString,
	}); err != nil {
		return err
	}
	s.UntrustedDockerManifestDigest = digest.Digest(digestString)

	return paranoidUnmarshalJSONObjectExactFields(identity, map[string]interface{}{
		"docker-reference": &s.UntrustedDockerReference,
	})
}
// strictUnmarshalJSON is UnmarshalJSON, except that it may return the internal jsonFormatError error type.
// Splitting it into a separate function allows us to do the jsonFormatError → InvalidSignatureError in a single place, the caller.