You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: messageUtil.go
    path of file: ./repos/databag/net/server/internal
    
    the code of the file until where you have to start completion: package databag

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"errors"
	"time"
)

//ReadDataMessage is a helper function to read signed protocol messages
func ReadDataMessage(msg *DataMessage, obj interface{}) (string, string, int64, error) {

	var data []byte
	var hash [32]byte
	var err error
	var publicKey *rsa.PublicKey

	if msg.KeyType != APPRSA4096 && msg.KeyType != APPRSA2048 {
		return "", "", 0, errors.New("unsupported key type")
	}

	// extract public key
	data, err = base64.StdEncoding.DecodeString(msg.PublicKey)
	if err != nil {
		return "", "", 0, err
	}
	publicKey, err = ParseRsaPublicKeyFromPemStr(string(data))
	if err != nil {
		return "", "", 0, err
	}

	// compute guid
	hash = sha256.Sum256(data)
	guid := hex.EncodeToString(hash[:])

	// extract signature
	data, err = base64.StdEncoding.DecodeString(msg.Signature)
	if err != nil {
		return "", "", 0, err
	}
	signature := data

	// verify hash
	data, err = base64.StdEncoding.DecodeString(msg.Message)
	if err != nil {
		return "", "", 0, err
	}
	hash = sha256.Sum256(data)
	if msg.SignatureType == APPSignPKCS1V15 {
		err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hash[:], signature)
		if err != nil {
			return "", "", 0, err
		}
	} else if msg.SignatureType == APPSignPSS {
		err = rsa.VerifyPSS(publicKey, crypto.SHA256, hash[:], signature, nil)
		if err != nil {
			return "", "", 0, err
		
    
func ReadDataMessage(msg *DataMessage, obj interface{}) (string, string, int64, error) {

	var data []byte
	var hash [32]byte
	var err error
	var publicKey *rsa.PublicKey

	if msg.KeyType != APPRSA4096 && msg.KeyType != APPRSA2048 {
		return "", "", 0, errors.New("unsupported key type")
	}

	// extract public key
	data, err = base64.StdEncoding.DecodeString(msg.PublicKey)
	if err != nil {
		return "", "", 0, err
	}
	publicKey, err = ParseRsaPublicKeyFromPemStr(string(data))
	if err != nil {
		return "", "", 0, err
	}

	// compute guid
	hash = sha256.Sum256(data)
	guid := hex.EncodeToString(hash[:])

	// extract signature
	data, err = base64.StdEncoding.DecodeString(msg.Signature)
	if err != nil {
		return "", "", 0, err
	}
	signature := data

	// verify hash
	data, err = base64.StdEncoding.DecodeString(msg.Message)
	if err != nil {
		return "", "", 0, err
	}
	hash = sha256.Sum256(data)
	if msg.SignatureType == APPSignPKCS1V15 {
		err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hash[:], signature)
		if err != nil {
			return "", "", 0, err
		}
	} else if msg.SignatureType == APPSignPSS {
		err = rsa.VerifyPSS(publicKey, crypto.SHA256, hash[:], signature, nil)
		if err != nil {
			return "", "", 0, err
		}
	} else {
		return "", "", 0, errors.New("unsupported signature type")
	}

	// extract data
	var signedData SignedData
	err = json.Unmarshal(data, &signedData)
	if err != nil {
		return "", "", 0, err
	}

	// validate signer
	if signedData.GUID != guid {
		return "", "", 0, errors.New("invalid message source")
	}

	// extract data
	err = json.Unmarshal([]byte(signedData.Value), obj)
	if err != nil {
		return "", "", 0, err
	}

	return guid, signedData.MessageType, signedData.Timestamp, nil
}