Skip to content
Snippets Groups Projects
Commit cf6a4be7 authored by Jonah Husson's avatar Jonah Husson
Browse files

Extract hashing to helper, switch to blake2b, rename client sender, cleanup

parent 9f655e7e
Branches
Tags
No related merge requests found
package client
import (
"crypto"
"crypto/sha256"
"git.xx.network/elixxir/mainnet-commitments/messages"
"git.xx.network/elixxir/mainnet-commitments/utils"
"github.com/pkg/errors"
"gitlab.com/xx_network/comms/connect"
"gitlab.com/xx_network/crypto/csprng"
......@@ -16,21 +15,18 @@ func SignAndTransmit(pk, idfBytes []byte, wallet string, h *connect.Host, s Send
if err != nil {
return errors.WithMessage(err, "Failed to load private key")
}
hasher := sha256.New()
_, err = hasher.Write(idfBytes)
if err != nil {
return errors.WithMessage(err, "Failed to write IDF to hash")
}
_, err = hasher.Write([]byte(wallet))
hashed, hash, err := utils.HashNodeInfo(wallet, idfBytes)
if err != nil {
return errors.WithMessage(err, "Failed to write wallet to hash")
return errors.WithMessage(err, "Failed to hash node info")
}
sig, err := rsa.Sign(csprng.NewSystemRNG(), key, crypto.SHA256, hasher.Sum(nil), nil)
sig, err := rsa.Sign(csprng.NewSystemRNG(), key, hash, hashed, nil)
if err != nil {
return errors.WithMessage(err, "Failed to sign node info")
}
err = s.SignAndTransmit(h, &messages.Commitment{
err = s.TransmitSignature(h, &messages.Commitment{
PrivateKey: pk,
IDF: idfBytes,
Wallet: wallet,
......
......@@ -11,7 +11,7 @@ import (
)
type Sender interface {
SignAndTransmit(host *connect.Host, message *messages.Commitment) error
TransmitSignature(host *connect.Host, message *messages.Commitment) error
}
// Client struct implements the GRPC client call to mainnet-commitments servers
......@@ -31,7 +31,7 @@ func StartClient(key, cert, salt []byte, id *id.ID) (*Client, error) {
}
// SignAndTransmit func sends a Commitment message to the mainnet-commitments server
func (c *Client) SignAndTransmit(host *connect.Host, message *messages.Commitment) error {
func (c *Client) TransmitSignature(host *connect.Host, message *messages.Commitment) error {
f := func(conn *grpc.ClientConn) (*any.Any, error) {
// Set up the context
ctx, cancel := host.GetMessagingContext()
......
......@@ -18,7 +18,7 @@ type MockSender struct {
id, cert []byte
}
func (ms *MockSender) SignAndTransmit(host *connect.Host, message *messages.Commitment) error {
func (ms *MockSender) TransmitSignature(host *connect.Host, message *messages.Commitment) error {
s, err := storage.NewStorage(storage.Params{})
if err != nil {
ms.t.Error("Failed to init storage for mock server")
......
......@@ -2,12 +2,10 @@ package server
import (
"context"
"crypto"
"crypto/sha256"
"encoding/json"
"git.xx.network/elixxir/mainnet-commitments/constants"
"git.xx.network/elixxir/mainnet-commitments/messages"
"git.xx.network/elixxir/mainnet-commitments/storage"
"git.xx.network/elixxir/mainnet-commitments/utils"
"github.com/pkg/errors"
"gitlab.com/xx_network/comms/connect"
"gitlab.com/xx_network/crypto/signature/rsa"
......@@ -26,7 +24,7 @@ type Params struct {
// StartServer creates a server object from params
func StartServer(params Params) (*Impl, error) {
// Create grpc server
pc, _, err := connect.StartCommServer(&constants.ServerID, params.Address, params.Cert, params.Key, nil)
pc, _, err := connect.StartCommServer(&utils.ServerID, params.Address, params.Cert, params.Key, nil)
if err != nil {
return nil, errors.WithMessage(err, "Failed to start comms server")
}
......@@ -58,31 +56,26 @@ func (i *Impl) Verify(_ context.Context, msg *messages.Commitment) (*messages.Co
return nil, errors.WithMessage(err, "Failed to unmarshal IDF json")
}
// Get member info from database
m, err := i.s.GetMember(idfStruct.IdBytes[:])
// Hash node info from message
hashed, hash, err := utils.HashNodeInfo(msg.Wallet, msg.IDF)
if err != nil {
return nil, errors.WithMessagef(err, "Member %s [%+v] not found", idfStruct.ID, idfStruct.IdBytes)
return nil, errors.WithMessage(err, "Failed to hash node info")
}
// Hash IDF & Wallet
hasher := sha256.New()
_, err = hasher.Write(msg.IDF)
if err != nil {
return nil, errors.WithMessage(err, "Failed to write IDF to hasher")
}
_, err = hasher.Write([]byte(msg.Wallet))
// Get member info from database
m, err := i.s.GetMember(idfStruct.IdBytes[:])
if err != nil {
return nil, errors.WithMessage(err, "Failed to write wallet to hasher")
return nil, errors.WithMessagef(err, "Member %s [%+v] not found", idfStruct.ID, idfStruct.IdBytes)
}
// Load certificate from database
// Load member certificate
cert, err := rsa.LoadPublicKeyFromPem(m.Cert)
if err != nil {
return nil, errors.WithMessage(err, "Failed to load certificate")
}
// Attempt to verify signature
err = rsa.Verify(cert, crypto.SHA256, hasher.Sum(nil), msg.Signature, nil)
err = rsa.Verify(cert, hash, hashed, msg.Signature, nil)
if err != nil {
return nil, errors.WithMessage(err, "Could not verify node commitment info signature")
}
......
......@@ -7,6 +7,7 @@ import (
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"sync"
"time"
)
......@@ -19,6 +20,7 @@ type database interface {
// DatabaseImpl struct implements the Database Interface with an underlying DB
type DatabaseImpl struct {
sync.RWMutex
db *gorm.DB // Stored database connection
}
......
......@@ -3,14 +3,20 @@ package storage
import "gorm.io/gorm/clause"
func (db *DatabaseImpl) InsertMembers(members []Member) error {
db.Lock()
defer db.Unlock()
return db.db.Create(&members).Error
}
func (db *DatabaseImpl) InsertCommitment(commitment Commitment) error {
db.Lock()
defer db.Unlock()
return db.db.Clauses(clause.OnConflict{UpdateAll: true}).Create(&commitment).Error
}
func (db *DatabaseImpl) GetMember(id []byte) (*Member, error) {
db.RLock()
defer db.RUnlock()
m := Member{}
return &m, db.db.First(&m, "id = ?", id).Error
}
......@@ -14,6 +14,8 @@ type MapImpl struct {
}
func (db *MapImpl) InsertMembers(members []Member) error {
db.Lock()
defer db.Unlock()
for _, m := range members {
db.members[base64.StdEncoding.EncodeToString(m.Id)] = m
}
......@@ -21,11 +23,15 @@ func (db *MapImpl) InsertMembers(members []Member) error {
}
func (db *MapImpl) InsertCommitment(commitment Commitment) error {
db.Lock()
defer db.Unlock()
db.commitments[base64.StdEncoding.EncodeToString(commitment.Id)] = commitment
return nil
}
func (db *MapImpl) GetMember(id []byte) (*Member, error) {
db.RLock()
defer db.RUnlock()
encoded := base64.StdEncoding.EncodeToString(id)
m, ok := db.members[encoded]
if !ok {
......
package constants
package utils
import "gitlab.com/xx_network/primitives/id"
......
package utils
import (
"crypto"
"github.com/pkg/errors"
)
func HashNodeInfo(wallet string, idfBytes []byte) ([]byte, crypto.Hash, error) {
h := crypto.BLAKE2b_512 // Define & return this here so we aren't defining hash type in 3 places for sign/verify calls
hasher := h.New()
_, err := hasher.Write(idfBytes)
if err != nil {
return nil, h, errors.WithMessage(err, "Failed to write IDF to hash")
}
_, err = hasher.Write([]byte(wallet))
if err != nil {
return nil, h, errors.WithMessage(err, "Failed to write wallet to hash")
}
return hasher.Sum(nil), h, nil
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment