Skip to content

Commit

Permalink
Merge pull request #1494 from 0chain/feat/session-key
Browse files Browse the repository at this point in the history
Session key
  • Loading branch information
dabasov authored Oct 28, 2024
2 parents 2c9787f + 2dbc985 commit 3da56c1
Show file tree
Hide file tree
Showing 17 changed files with 144 additions and 54 deletions.
5 changes: 3 additions & 2 deletions code/go/0chain.net/blobbercore/allocation/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ type Allocation struct {
TimeUnit time.Duration `gorm:"column:time_unit;not null;default:172800000000000"`
StartTime common.Timestamp `gorm:"column:start_time;not null"`
// Ending and cleaning
CleanedUp bool `gorm:"column:cleaned_up;not null;default:false"`
Finalized bool `gorm:"column:finalized;not null;default:false"`
CleanedUp bool `gorm:"column:cleaned_up;not null;default:false"`
Finalized bool `gorm:"column:finalized;not null;default:false"`
OwnerSigningPublicKey string `gorm:"column:owner_signing_public_key;size:512;not null" json:"owner_signing_public_key"`

// FileOptions to define file restrictions on an allocation for third-parties
// default 00000000 for all crud operations suggesting only owner has the below listed abilities.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ type BaseFileChanger struct {
EncryptedKeyPoint string `json:"encrypted_key_point,omitempty"`
CustomMeta string `json:"custom_meta,omitempty"`

ChunkSize int64 `json:"chunk_size,omitempty"` // the size of achunk. 64*1024 is default
IsFinal bool `json:"is_final,omitempty"` // current chunk is last or not
ChunkSize int64 `json:"chunk_size,omitempty"` // the size of achunk. 64*1024 is default
IsFinal bool `json:"is_final,omitempty"` // current chunk is last or not
SignatureVersion int `json:"signature_version,omitempty"`

ChunkStartIndex int `json:"chunk_start_index,omitempty"` // start index of chunks.
ChunkEndIndex int `json:"chunk_end_index,omitempty"` // end index of chunks. all chunks MUST be uploaded one by one because of CompactMerkleTree
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func (nf *UpdateFileChanger) ApplyChange(ctx context.Context, rootRef *reference
fileRef.ChunkSize = nf.ChunkSize
fileRef.IsPrecommit = true
fileRef.FilestoreVersion = filestore.VERSION
fileRef.SignatureVersion = nf.SignatureVersion

return rootRef, nil
}
Expand Down Expand Up @@ -173,6 +174,7 @@ func (nf *UpdateFileChanger) ApplyChangeV2(ctx context.Context, allocationRoot,
PathLevel: len(strings.Split(strings.TrimRight(nf.Path, "/"), "/")),
NumBlocks: int64(math.Ceil(float64(nf.Size*1.0) / float64(nf.ChunkSize))),
NumUpdates: refResult.NumUpdates + 1,
SignatureVersion: nf.SignatureVersion,
}
nf.storageVersion = 1
newFile.FileMetaHash = encryption.Hash(newFile.GetFileMetaHashDataV2())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ func (nf *UploadFileChanger) applyChange(ctx context.Context, rootRef *reference
HashToBeComputed: true,
IsPrecommit: true,
FilestoreVersion: filestore.VERSION,
SignatureVersion: nf.SignatureVersion,
}

fileID, ok := fileIDMeta[newFile.Path]
Expand Down Expand Up @@ -197,6 +198,7 @@ func (nf *UploadFileChanger) ApplyChangeV2(ctx context.Context, allocationRoot,
PathLevel: len(strings.Split(strings.TrimRight(nf.Path, "/"), "/")),
NumBlocks: int64(math.Ceil(float64(nf.Size*1.0) / float64(nf.ChunkSize))),
NumUpdates: 1,
SignatureVersion: nf.SignatureVersion,
}
nf.storageVersion = 1
newFile.FileMetaHash = encryption.Hash(newFile.GetFileMetaHashDataV2())
Expand Down
2 changes: 1 addition & 1 deletion code/go/0chain.net/blobbercore/allocation/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ func FetchAllocationFromEventsDB(ctx context.Context, allocationID string, alloc
a.TimeUnit = sa.TimeUnit
a.FileOptions = sa.FileOptions
a.StartTime = sa.StartTime
// Only for testing purpose
a.StorageVersion = uint8(sa.StorageVersion)
a.OwnerSigningPublicKey = sa.OwnerSigningPublicKey

m := map[string]interface{}{
"allocation_id": a.ID,
Expand Down
3 changes: 3 additions & 0 deletions code/go/0chain.net/blobbercore/allocation/workers.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ func updateAllocationInDB(ctx context.Context, a *Allocation, sa *transaction.St
a.Tx = sa.Tx
a.OwnerID = sa.OwnerID
a.OwnerPublicKey = sa.OwnerPublicKey
a.OwnerSigningPublicKey = sa.OwnerSigningPublicKey

// // update fields
a.Expiration = sa.Expiration
Expand All @@ -263,6 +264,7 @@ func updateAllocationInDB(ctx context.Context, a *Allocation, sa *transaction.St
updateMap["finalized"] = a.Finalized
updateMap["file_options"] = a.FileOptions
updateMap["blobber_size"] = a.BlobberSize
updateMap["owner_signing_public_key"] = a.OwnerSigningPublicKey

updateOption := func(alloc *Allocation) {
alloc.Tx = a.Tx
Expand All @@ -273,6 +275,7 @@ func updateAllocationInDB(ctx context.Context, a *Allocation, sa *transaction.St
alloc.Finalized = a.Finalized
alloc.FileOptions = a.FileOptions
alloc.BlobberSize = a.BlobberSize
alloc.OwnerSigningPublicKey = a.OwnerSigningPublicKey
}

// update terms
Expand Down
2 changes: 2 additions & 0 deletions code/go/0chain.net/blobbercore/allocation/zcn.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ func SyncAllocation(allocationId string) (*Allocation, error) {
alloc.Finalized = sa.Finalized
alloc.TimeUnit = sa.TimeUnit
alloc.FileOptions = sa.FileOptions
alloc.StorageVersion = uint8(sa.StorageVersion)
alloc.OwnerSigningPublicKey = sa.OwnerSigningPublicKey

// related terms
terms := make([]*Terms, 0, len(sa.BlobberDetails))
Expand Down
6 changes: 4 additions & 2 deletions code/go/0chain.net/blobbercore/challenge/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import (
"encoding/hex"
"encoding/json"
"errors"
"github.com/0chain/blobber/code/go/0chain.net/core/transaction"
coreTxn "github.com/0chain/gosdk/core/transaction"
"math/rand"
"strings"
"sync"
"time"

"github.com/0chain/blobber/code/go/0chain.net/core/transaction"
coreTxn "github.com/0chain/gosdk/core/transaction"

"github.com/0chain/blobber/code/go/0chain.net/blobbercore/allocation"
"github.com/0chain/blobber/code/go/0chain.net/blobbercore/datastore"
"github.com/0chain/blobber/code/go/0chain.net/blobbercore/filestore"
Expand Down Expand Up @@ -366,6 +367,7 @@ func (cr *ChallengeEntity) getPostDataV2(ctx context.Context, allocationObj *all
FixedMerkleRoot: ref.FixedMerkleRoot,
Size: ref.Size,
FileMetaHash: ref.FileMetaHash,
SignatureVersion: ref.SignatureVersion,
}
postData["meta"] = metaRef
}
Expand Down
10 changes: 9 additions & 1 deletion code/go/0chain.net/blobbercore/handler/file_command_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,15 @@ func (cmd *UpdateFileCommand) ProcessContent(ctx context.Context, allocationObj
hashData := fmt.Sprintf("%s:%s:%s:%s", cmd.fileChanger.ActualHash, cmd.fileChanger.ValidationRoot, cmd.fileChanger.FixedMerkleRoot, node.Self.ID)
hash = encryption.Hash(hashData)
}
verify, err := encryption.Verify(allocationObj.OwnerPublicKey, cmd.fileChanger.ValidationRootSignature, hash)
var (
err error
verify bool
)
if cmd.fileChanger.SignatureVersion == reference.SignatureV2 {
verify, err = encryption.VerifyEd25519(allocationObj.OwnerSigningPublicKey, cmd.fileChanger.ValidationRootSignature, hash)
} else {
verify, err = encryption.Verify(allocationObj.OwnerPublicKey, cmd.fileChanger.ValidationRootSignature, hash)
}
if err != nil || !verify {
logging.Logger.Error("UpdateFileCommand.VerifySignature", zap.Error(err))
return result, common.NewError("update_error", "Failed to verify validation root signature. ")
Expand Down
10 changes: 9 additions & 1 deletion code/go/0chain.net/blobbercore/handler/file_command_upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,15 @@ func (cmd *UploadFileCommand) ProcessContent(ctx context.Context, allocationObj
hashData := fmt.Sprintf("%s:%s:%s:%s", cmd.fileChanger.ActualHash, cmd.fileChanger.ValidationRoot, cmd.fileChanger.FixedMerkleRoot, node.Self.ID)
hash = encryption.Hash(hashData)
}
verify, err := encryption.Verify(allocationObj.OwnerPublicKey, cmd.fileChanger.ValidationRootSignature, hash)
var (
err error
verify bool
)
if cmd.fileChanger.SignatureVersion == reference.SignatureV2 {
verify, err = encryption.VerifyEd25519(allocationObj.OwnerSigningPublicKey, cmd.fileChanger.ValidationRootSignature, hash)
} else {
verify, err = encryption.Verify(allocationObj.OwnerPublicKey, cmd.fileChanger.ValidationRootSignature, hash)
}
if err != nil || !verify {
logging.Logger.Error("UploadFileCommand.VerifySignature", zap.Error(err))
return result, common.NewError("upload_error", "Failed to verify validation root signature. ")
Expand Down
4 changes: 4 additions & 0 deletions code/go/0chain.net/blobbercore/reference/ref.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const (

DIR_LIST_TAG = "dirlist"
FILE_LIST_TAG = "filelist"
SignatureV2 = 1
)

var (
Expand Down Expand Up @@ -91,6 +92,7 @@ type Ref struct {
NumUpdates int64 `gorm:"column:num_of_updates" json:"num_of_updates"`
NumBlockDownloads int64 `gorm:"column:num_of_block_downloads" json:"num_of_block_downloads"`
FilestoreVersion int `gorm:"column:filestore_version" json:"-"`
SignatureVersion int `gorm:"column:signature_version" json:"signature_version" filelist:"signature_version"`
IsEmpty bool `gorm:"-" dirlist:"is_empty"`
HashToBeComputed bool `gorm:"-"`
prevID int64 `gorm:"-"`
Expand Down Expand Up @@ -148,6 +150,7 @@ type PaginatedRef struct { //Gorm smart select fields.
EncryptedKey string `gorm:"column:encrypted_key" json:"encrypted_key,omitempty"`
EncryptedKeyPoint string `gorm:"column:encrypted_key_point" json:"encrypted_key_point,omitempty"`
FileMetaHash string `gorm:"column:file_meta_hash;size:64;not null" dirlist:"file_meta_hash" filelist:"file_meta_hash"`
SignatureVersion int `gorm:"column:signature_version" json:"signature_version,omitempty" filelist:"signature_version"`

CreatedAt common.Timestamp `gorm:"column:created_at" json:"created_at,omitempty"`
UpdatedAt common.Timestamp `gorm:"column:updated_at" json:"updated_at,omitempty"`
Expand All @@ -166,6 +169,7 @@ type RefMeta struct {
FixedMerkleRoot string `json:"fixed_merkle_root"`
Size int64 `json:"size"`
FileMetaHash string `json:"file_meta_hash"`
SignatureVersion int `json:"signature_version"`
}

// GetReferenceLookup hash(allocationID + ":" + path)
Expand Down
36 changes: 32 additions & 4 deletions code/go/0chain.net/core/encryption/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package encryption

import (
"bufio"
"crypto/ed25519"
"encoding/hex"
"io"
"strings"

Expand All @@ -13,8 +15,10 @@ import (
"github.com/herumi/bls-go-binary/bls"
)

/*ReadKeys - reads a publicKey and a privateKey from a Reader.
They are assumed to be in two separate lines one followed by the other*/
/*
ReadKeys - reads a publicKey and a privateKey from a Reader.
They are assumed to be in two separate lines one followed by the other
*/
func ReadKeys(reader io.Reader) (publicKey, privateKey, publicIp, port string) {
scanner := bufio.NewScanner(reader)
scanner.Scan()
Expand Down Expand Up @@ -44,14 +48,38 @@ func Verify(publicKey, signature, hash string) (bool, error) {
return false, common.NewError("invalid_signature_scheme", "Invalid signature scheme. Please check configuration")
}

// VerifyEd25519 - verify the signature using the public key
func VerifyEd25519(publicKey, signature, hash string) (bool, error) {
if len(publicKey) == 0 {
return false, common.NewError("invalid_public_key", "Invalid public key")
}
if len(signature) == 0 {
return false, common.NewError("invalid_signature", "Invalid signature")
}
sig, err := hex.DecodeString(signature)
if err != nil {
return false, err
}
pub, err := hex.DecodeString(publicKey)
if err != nil {
return false, err
}
msg, err := hex.DecodeString(hash)
if err != nil {
return false, err
}
return ed25519.Verify(pub, msg, sig), nil
}

// If input is normal herumi/bls public key, it returns it immmediately.
// So this is completely backward compatible with herumi/bls.
//
// So this is completely backward compatible with herumi/bls.
//
// If input is MIRACL public key, convert it to herumi/bls public key.
//
// This is an example of the raw public key we expect from MIRACL
var miraclExamplePK = `0418a02c6bd223ae0dfda1d2f9a3c81726ab436ce5e9d17c531ff0a385a13a0b491bdfed3a85690775ee35c61678957aaba7b1a1899438829f1dc94248d87ed36817f6dfafec19bfa87bf791a4d694f43fec227ae6f5a867490e30328cac05eaff039ac7dfc3364e851ebd2631ea6f1685609fc66d50223cc696cb59ff2fee47ac`

//
// This is an example of the same MIRACL public key serialized with ToString().
// pk ([1bdfed3a85690775ee35c61678957aaba7b1a1899438829f1dc94248d87ed368,18a02c6bd223ae0dfda1d2f9a3c81726ab436ce5e9d17c531ff0a385a13a0b49],[039ac7dfc3364e851ebd2631ea6f1685609fc66d50223cc696cb59ff2fee47ac,17f6dfafec19bfa87bf791a4d694f43fec227ae6f5a867490e30328cac05eaff])
func MiraclToHerumiPK(pk string) string {
Expand Down
29 changes: 15 additions & 14 deletions code/go/0chain.net/core/transaction/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,21 @@ type BlobberAllocation struct {
}

type StorageAllocation struct {
ID string `json:"id"`
Tx string `json:"tx"`
OwnerPublicKey string `json:"owner_public_key"`
OwnerID string `json:"owner_id"`
Size int64 `json:"size"`
UsedSize int64 `json:"used_size"`
Expiration common.Timestamp `json:"expiration_date"`
BlobberDetails []*BlobberAllocation `json:"blobber_details"`
Finalized bool `json:"finalized"`
TimeUnit time.Duration `json:"time_unit"`
WritePool uint64 `json:"write_pool"`
FileOptions uint16 `json:"file_options"`
StartTime common.Timestamp `json:"start_time"`
StorageVersion int `json:"storage_version"`
ID string `json:"id"`
Tx string `json:"tx"`
OwnerPublicKey string `json:"owner_public_key"`
OwnerID string `json:"owner_id"`
Size int64 `json:"size"`
UsedSize int64 `json:"used_size"`
Expiration common.Timestamp `json:"expiration_date"`
BlobberDetails []*BlobberAllocation `json:"blobber_details"`
Finalized bool `json:"finalized"`
TimeUnit time.Duration `json:"time_unit"`
WritePool uint64 `json:"write_pool"`
FileOptions uint16 `json:"file_options"`
StartTime common.Timestamp `json:"start_time"`
StorageVersion int `json:"storage_version"`
OwnerSigningPublicKey string `json:"owner_signing_public_key"`

DataShards int64 `json:"data_shards"`
ParityShards int64 `json:"parity_shards"`
Expand Down
40 changes: 26 additions & 14 deletions code/go/0chain.net/validatorcore/storage/challenge_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/hex"
"encoding/json"
"github.com/0chain/gosdk/zboxcore/sdk"
"io"
"net/http"
"strings"
Expand All @@ -14,6 +13,7 @@ import (
"github.com/0chain/blobber/code/go/0chain.net/core/common"
"github.com/0chain/blobber/code/go/0chain.net/core/logging"
"github.com/0chain/blobber/code/go/0chain.net/core/node"
"github.com/0chain/blobber/code/go/0chain.net/core/transaction"

"go.uber.org/zap"
"golang.org/x/crypto/sha3"
Expand Down Expand Up @@ -42,14 +42,12 @@ func challengeHandler(ctx context.Context, r *http.Request) (interface{}, error)

time.Sleep(1 * time.Second)

sdkAlloc, err := sdk.GetAllocation(challengeObj.AllocationID)
allocationObj, err := requestAllocation(challengeObj.AllocationID)
if err != nil {
logging.Logger.Error("Error getting allocation from chain", zap.String("allocation_id", challengeObj.AllocationID), zap.Error(err))
return nil, common.NewError("invalid_parameters", "Allocation could not be verified. "+err.Error())
}

allocationObj := sdkAllocToBlobberAlloc(sdkAlloc)

err = challengeRequest.VerifyChallenge(challengeObj, allocationObj)
if err != nil {
updateStats(false)
Expand All @@ -61,17 +59,31 @@ func challengeHandler(ctx context.Context, r *http.Request) (interface{}, error)
return ValidValidationTicket(challengeObj, challengeRequest.ChallengeID, challengeHash)
}

func sdkAllocToBlobberAlloc(sdkAlloc *sdk.Allocation) *Allocation {
return &Allocation{
ID: sdkAlloc.ID,
DataShards: sdkAlloc.DataShards,
ParityShards: sdkAlloc.ParityShards,
Size: sdkAlloc.Size,
Owner: sdkAlloc.Owner,
OwnerPublicKey: sdkAlloc.OwnerPublicKey,
UsedSize: sdkAlloc.Stats.UsedSize,
Expiration: common.Timestamp(sdkAlloc.Expiration),
func requestAllocation(allocID string) (allocation *Allocation, err error) {
var b []byte
b, err = transaction.MakeSCRestAPICall(
transaction.STORAGE_CONTRACT_ADDRESS,
"/allocation",
map[string]string{"allocation": allocID})
if err != nil {
return
}
sa := new(transaction.StorageAllocation)
err = json.Unmarshal(b, sa)
if err != nil {
return
}
allocation = &Allocation{
ID: sa.ID,
DataShards: sa.DataShards,
ParityShards: sa.ParityShards,
Size: sa.Size,
Expiration: sa.Expiration,
Owner: sa.OwnerID,
OwnerPublicKey: sa.OwnerPublicKey,
OwnerSigningPublicKey: sa.OwnerSigningPublicKey,
}
return
}

func NewChallengeRequest(r *http.Request) (*ChallengeRequest, string, error) {
Expand Down
Loading

0 comments on commit 3da56c1

Please sign in to comment.