Create server identity on start if necessary

This commit is contained in:
Andrea Maria Piana 2020-07-13 12:39:33 +02:00
parent 3f4575b802
commit 7e8d1353d0
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
6 changed files with 88 additions and 8 deletions

View File

@ -1,7 +1,7 @@
// Code generated by go-bindata. DO NOT EDIT.
// sources:
// 1593601728_initial_schema.down.sql (200B)
// 1593601728_initial_schema.up.sql (517B)
// 1593601728_initial_schema.up.sql (675B)
// doc.go (382B)
package migrations
@ -91,7 +91,7 @@ func _1593601728_initial_schemaDownSql() (*asset, error) {
return a, nil
}
var __1593601728_initial_schemaUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x90\xc1\x4a\x03\x31\x14\x45\xf7\xf9\x8a\xbb\xec\x40\xff\x60\x56\x99\x98\x62\x20\xbc\xe8\x34\x23\xdd\x85\xda\x46\x7d\x38\xcc\x94\x24\x2d\xfa\xf7\xe2\x28\x38\xad\x9b\x22\x6e\x2f\x8f\x7b\xde\x3d\xaa\xd5\xd2\x6b\x78\xd9\x58\x0d\xb3\x02\x39\x0f\xbd\x31\x6b\xbf\xc6\xe1\x98\x5f\xc2\x30\x16\x7e\xe2\xdd\xb6\xf0\x38\x84\x1c\xd3\x29\xa6\x90\xe2\x33\xe7\x92\xa6\x2c\x63\x21\x80\xc3\xf1\xb1\xe7\x5d\x78\x8d\xef\x68\xac\x6b\xa6\x16\xea\xac\x5d\x0a\x80\x87\x5c\xb6\x7d\xff\xd5\xc0\x7b\x3c\xc8\x56\xdd\xca\xf6\xec\xe6\x14\x53\xe6\x71\x80\x21\x7f\x96\xcf\x49\x53\xf3\x67\xd8\x91\xb9\xef\xf4\xe2\x87\xb9\xbc\x64\x54\x70\x04\xe5\x68\x65\x8d\xf2\x68\xf5\x9d\x95\x4a\x8b\xaa\x16\xe2\x7b\xae\xa1\x1b\xbd\x01\xef\xdf\xc2\x75\x23\xc3\x6c\xa0\xa3\x2b\xcd\xcc\x3e\xac\xea\x7f\x20\x87\x4b\x93\x7f\xf9\xe4\xb7\xab\x5a\x88\x8f\x00\x00\x00\xff\xff\x5c\xf8\x30\xd8\x05\x02\x00\x00")
var __1593601728_initial_schemaUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x91\x31\x6b\xc3\x30\x14\x84\x77\xfd\x8a\x37\xc6\x90\xa1\xbb\x27\xd9\x91\xa9\x40\x48\xad\x23\x97\x6c\xc2\xb5\xd5\xe6\x51\x23\x07\x49\x31\xf5\xbf\x2f\x71\x86\x2a\x69\x87\x10\xb2\x1e\x8f\xbb\xf7\xdd\x95\x35\xa3\x9a\x81\xa6\x85\x60\xc0\x2b\x90\x4a\x03\xdb\xf1\xad\xde\xc2\xe1\x18\xf6\xc6\x8d\x11\x3f\xb0\x6b\x23\x8e\xce\x04\xeb\x27\xeb\x8d\xb7\x9f\x18\xa2\x5f\xb4\x00\x2b\x02\x70\x38\xbe\x0f\xd8\x99\x2f\x3b\x43\x21\x54\xb1\xb8\xc8\x46\x88\x35\x01\x40\x17\x62\x3b\x0c\x67\x07\xec\xe1\x8d\xd6\xe5\x33\xad\x2f\x6e\x26\xeb\x03\x8e\x0e\xb8\xd4\x17\x7a\x9a\xb4\x38\x9f\xc4\x46\xf2\xd7\x86\xad\x7e\x33\xd7\xd7\x19\x19\x28\x09\xa5\x92\x95\xe0\xa5\x86\x9a\xbd\x08\x5a\x32\x92\xe5\x84\xdc\x83\x8b\xbd\x75\x11\xe3\x7c\x26\xf5\x38\xb5\xd1\xfe\x8f\x1a\x66\x17\xf7\x36\x62\x77\xe2\x4c\x59\x60\xc3\x2a\xda\x08\x0d\x4f\x09\x40\x7a\x9d\xa5\xdf\x71\xb9\x61\x3b\xc0\xfe\xdb\xdc\x36\x81\x49\xea\x57\xf2\xc6\xdd\x92\xfe\xb2\xfc\x01\xc9\xe6\x7a\xe7\x7b\x3e\xf9\xbb\x64\x4e\xc8\x4f\x00\x00\x00\xff\xff\xcc\xa0\x4d\x54\xa3\x02\x00\x00")
func _1593601728_initial_schemaUpSqlBytes() ([]byte, error) {
return bindataRead(
@ -106,8 +106,8 @@ func _1593601728_initial_schemaUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1593601728_initial_schema.up.sql", size: 517, mode: os.FileMode(0644), modTime: time.Unix(1594393629, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf1, 0x55, 0xab, 0xbf, 0xee, 0x66, 0xe9, 0x81, 0x9f, 0x89, 0xca, 0x6b, 0xf8, 0x1d, 0x12, 0x59, 0xf6, 0x1e, 0xac, 0x79, 0x93, 0x8f, 0x47, 0xbd, 0x76, 0x65, 0xbb, 0x10, 0x99, 0x8a, 0xda, 0x9e}}
info := bindataFileInfo{name: "1593601728_initial_schema.up.sql", size: 675, mode: os.FileMode(0644), modTime: time.Unix(1594636412, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfd, 0x61, 0x90, 0x79, 0xd9, 0x14, 0x65, 0xe9, 0x96, 0x53, 0x17, 0x33, 0x54, 0xeb, 0x8b, 0x5d, 0x95, 0x99, 0x10, 0x36, 0x58, 0xdd, 0xb2, 0xbf, 0x45, 0xd9, 0xbb, 0xc4, 0x92, 0xe, 0xce, 0x2}}
return a, nil
}

View File

@ -6,6 +6,12 @@ CREATE TABLE IF NOT EXISTS push_notification_server_registrations (
UNIQUE(public_key, installation_id) ON CONFLICT REPLACE
);
CREATE TABLE IF NOT EXISTS push_notification_server_identity (
private_key BLOB NOT NULL,
synthetic_id INT NOT NULL DEFAULT 0,
UNIQUE(synthetic_id)
);
CREATE INDEX idx_push_notification_server_registrations_public_key ON push_notification_server_registrations(public_key);
CREATE INDEX idx_push_notification_server_registrations_public_key_installation_id ON push_notification_server_registrations(public_key, installation_id);

View File

@ -1,11 +1,13 @@
package push_notification_server
import (
"crypto/ecdsa"
"database/sql"
"strings"
"github.com/golang/protobuf/proto"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/protocol/protobuf"
)
@ -21,6 +23,10 @@ type Persistence interface {
DeletePushNotificationRegistration(publicKey []byte, installationID string) error
// SavePushNotificationRegistration saves a push notification option to the db
SavePushNotificationRegistration(publicKey []byte, registration *protobuf.PushNotificationRegistration) error
// GetIdentity returns the server identity key
GetIdentity() (*ecdsa.PrivateKey, error)
// SaveIdentity saves the server identity key
SaveIdentity(*ecdsa.PrivateKey) error
}
type SQLitePersistence struct {
@ -124,3 +130,25 @@ func (p *SQLitePersistence) DeletePushNotificationRegistration(publicKey []byte,
_, err := p.db.Exec(`DELETE FROM push_notification_server_registrations WHERE public_key = ? AND installation_id = ?`, publicKey, installationID)
return err
}
func (p *SQLitePersistence) SaveIdentity(privateKey *ecdsa.PrivateKey) error {
_, err := p.db.Exec(`INSERT INTO push_notification_server_identity (private_key) VALUES (?)`, crypto.FromECDSA(privateKey))
return err
}
func (p *SQLitePersistence) GetIdentity() (*ecdsa.PrivateKey, error) {
var pkBytes []byte
err := p.db.QueryRow(`SELECT private_key FROM push_notification_server_identity LIMIT 1`).Scan(&pkBytes)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
pk, err := crypto.ToECDSA(pkBytes)
if err != nil {
return nil, err
}
return pk, nil
}

View File

@ -57,3 +57,29 @@ func (s *SQLitePersistenceSuite) TestSaveAndRetrieve() {
s.Require().True(proto.Equal(registration, retrievedRegistration))
}
func (s *SQLitePersistenceSuite) TestSaveAndRetrieveIdentity() {
retrievedKey, err := s.persistence.GetIdentity()
s.Require().NoError(err)
s.Require().Nil(retrievedKey)
key, err := crypto.GenerateKey()
s.Require().NoError(err)
s.Require().NoError(s.persistence.SaveIdentity(key))
retrievedKey, err = s.persistence.GetIdentity()
s.Require().NoError(err)
s.Require().Equal(key, retrievedKey)
}
func (s *SQLitePersistenceSuite) TestSaveDifferentIdenities() {
key1, err := crypto.GenerateKey()
s.Require().NoError(err)
key2, err := crypto.GenerateKey()
s.Require().NoError(err)
// First one should be successul, second should fail
s.Require().NoError(s.persistence.SaveIdentity(key1))
s.Require().Error(s.persistence.SaveIdentity(key2))
}

View File

@ -17,6 +17,7 @@ import (
)
const encryptedPayloadKeyLength = 16
const defaultGorushURL = "https://gorush.status.im"
type Config struct {
// Identity is our identity key
@ -34,6 +35,10 @@ type Server struct {
}
func New(config *Config, persistence Persistence, messageProcessor *common.MessageProcessor) *Server {
if len(config.GorushURL) == 0 {
config.GorushURL = defaultGorushURL
}
return &Server{persistence: persistence, config: config, messageProcessor: messageProcessor}
}
@ -270,6 +275,24 @@ func (s *Server) HandlePushNotificationRegistration(publicKey *ecdsa.PublicKey,
}
func (s *Server) Start() error {
if s.config.Identity == nil {
// Pull identity from database
identity, err := s.persistence.GetIdentity()
if err != nil {
return err
}
if identity == nil {
identity, err = crypto.GenerateKey()
if err != nil {
return err
}
if err := s.persistence.SaveIdentity(identity); err != nil {
return err
}
}
s.config.Identity = identity
}
pks, err := s.persistence.GetPushNotificationRegistrationPublicKeys()
if err != nil {
return err

View File

@ -459,12 +459,9 @@ func buildMessengerOptions(
options = append(options, protocol.WithDatasync())
}
// For now build with default/hardcoded options.
if config.PushNotificationServerEnabled {
config := &push_notification_server.Config{
Identity: identity,
Logger: logger,
GorushURL: "https://gorush.status.im",
Logger: logger,
}
options = append(options, protocol.WithPushNotificationServerConfig(config))
}