Return decrypted options on validation
This commit is contained in:
parent
c5077609ee
commit
eed0df3420
|
@ -60,61 +60,60 @@ func (p *Server) validateUUID(u string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Server) ValidateRegistration(previousPreferences *protobuf.PushNotificationOptions, publicKey *ecdsa.PublicKey, payload []byte) error {
|
// ValidateRegistration validates a new message against the last one received for a given installationID and and public key
|
||||||
|
// and return the decrypted message
|
||||||
|
func (p *Server) ValidateRegistration(previousOptions *protobuf.PushNotificationOptions, publicKey *ecdsa.PublicKey, payload []byte) (*protobuf.PushNotificationOptions, error) {
|
||||||
if payload == nil {
|
if payload == nil {
|
||||||
return ErrEmptyPushNotificationOptionsPayload
|
return nil, ErrEmptyPushNotificationOptionsPayload
|
||||||
}
|
}
|
||||||
|
|
||||||
if publicKey == nil {
|
if publicKey == nil {
|
||||||
return ErrEmptyPushNotificationOptionsPublicKey
|
return nil, ErrEmptyPushNotificationOptionsPublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
sharedKey, err := p.generateSharedKey(publicKey)
|
sharedKey, err := p.generateSharedKey(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
decryptedPayload, err := decrypt(payload, sharedKey)
|
decryptedPayload, err := decrypt(payload, sharedKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
preferences := &protobuf.PushNotificationOptions{}
|
options := &protobuf.PushNotificationOptions{}
|
||||||
|
|
||||||
if err := proto.Unmarshal(decryptedPayload, preferences); err != nil {
|
if err := proto.Unmarshal(decryptedPayload, options); err != nil {
|
||||||
return ErrCouldNotUnmarshalPushNotificationOptions
|
return nil, ErrCouldNotUnmarshalPushNotificationOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
if preferences.Version < 1 {
|
if options.Version < 1 {
|
||||||
return ErrInvalidPushNotificationOptionsVersion
|
return nil, ErrInvalidPushNotificationOptionsVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
if previousPreferences != nil && preferences.Version <= previousPreferences.Version {
|
if previousOptions != nil && options.Version <= previousOptions.Version {
|
||||||
return ErrInvalidPushNotificationOptionsVersion
|
return nil, ErrInvalidPushNotificationOptionsVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.validateUUID(preferences.InstallationId); err != nil {
|
if err := p.validateUUID(options.InstallationId); err != nil {
|
||||||
return ErrMalformedPushNotificationOptionsInstallationID
|
return nil, ErrMalformedPushNotificationOptionsInstallationID
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unregistering message
|
// Unregistering message
|
||||||
if preferences.Unregister {
|
if options.Unregister {
|
||||||
return nil
|
return options, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.validateUUID(preferences.AccessToken); err != nil {
|
if err := p.validateUUID(options.AccessToken); err != nil {
|
||||||
return ErrMalformedPushNotificationOptionsAccessToken
|
return nil, ErrMalformedPushNotificationOptionsAccessToken
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(preferences.Token) == 0 {
|
if len(options.Token) == 0 {
|
||||||
return ErrMalformedPushNotificationOptionsDeviceToken
|
return nil, ErrMalformedPushNotificationOptionsDeviceToken
|
||||||
}
|
}
|
||||||
fmt.Println(decryptedPayload)
|
fmt.Println(decryptedPayload)
|
||||||
|
|
||||||
/*if newRegistration.Version < 1 {
|
return options, nil
|
||||||
return ErrInvalidPushNotificationOptionsVersion
|
|
||||||
}*/
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func decrypt(cyphertext []byte, key []byte) ([]byte, error) {
|
func decrypt(cyphertext []byte, key []byte) ([]byte, error) {
|
||||||
|
|
|
@ -30,29 +30,36 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Empty payload
|
// Empty payload
|
||||||
require.Equal(t, ErrEmptyPushNotificationOptionsPayload, server.ValidateRegistration(nil, &key.PublicKey, nil))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, nil)
|
||||||
|
require.Equal(t, ErrEmptyPushNotificationOptionsPayload, err)
|
||||||
|
|
||||||
// Empty key
|
// Empty key
|
||||||
require.Equal(t, ErrEmptyPushNotificationOptionsPublicKey, server.ValidateRegistration(nil, nil, []byte("payload")))
|
_, err = server.ValidateRegistration(nil, nil, []byte("payload"))
|
||||||
|
require.Equal(t, ErrEmptyPushNotificationOptionsPublicKey, err)
|
||||||
|
|
||||||
// Invalid cyphertext length
|
// Invalid cyphertext length
|
||||||
require.Equal(t, ErrInvalidCiphertextLength, server.ValidateRegistration(nil, &key.PublicKey, []byte("too short")))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, []byte("too short"))
|
||||||
|
require.Equal(t, ErrInvalidCiphertextLength, err)
|
||||||
|
|
||||||
// Invalid cyphertext length
|
// Invalid cyphertext length
|
||||||
require.Equal(t, ErrInvalidCiphertextLength, server.ValidateRegistration(nil, &key.PublicKey, []byte("too short")))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, []byte("too short"))
|
||||||
|
require.Equal(t, ErrInvalidCiphertextLength, err)
|
||||||
|
|
||||||
// Invalid ciphertext
|
// Invalid ciphertext
|
||||||
require.Error(t, ErrInvalidCiphertextLength, server.ValidateRegistration(nil, &key.PublicKey, []byte("not too short but invalid")))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, []byte("not too short but invalid"))
|
||||||
|
require.Error(t, ErrInvalidCiphertextLength, err)
|
||||||
|
|
||||||
// Different key ciphertext
|
// Different key ciphertext
|
||||||
cyphertext, err := encrypt([]byte("plaintext"), make([]byte, 32), rand.Reader)
|
cyphertext, err := encrypt([]byte("plaintext"), make([]byte, 32), rand.Reader)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Error(t, server.ValidateRegistration(nil, &key.PublicKey, cyphertext))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, cyphertext)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
// Right cyphertext but non unmarshable payload
|
// Right cyphertext but non unmarshable payload
|
||||||
cyphertext, err = encrypt([]byte("plaintext"), sharedKey, rand.Reader)
|
cyphertext, err = encrypt([]byte("plaintext"), sharedKey, rand.Reader)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, ErrCouldNotUnmarshalPushNotificationOptions, server.ValidateRegistration(nil, &key.PublicKey, cyphertext))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, cyphertext)
|
||||||
|
require.Equal(t, ErrCouldNotUnmarshalPushNotificationOptions, err)
|
||||||
|
|
||||||
// Missing installationID
|
// Missing installationID
|
||||||
payload, err := proto.Marshal(&protobuf.PushNotificationOptions{
|
payload, err := proto.Marshal(&protobuf.PushNotificationOptions{
|
||||||
|
@ -63,7 +70,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
||||||
|
|
||||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, ErrMalformedPushNotificationOptionsInstallationID, server.ValidateRegistration(nil, &key.PublicKey, cyphertext))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, cyphertext)
|
||||||
|
require.Equal(t, ErrMalformedPushNotificationOptionsInstallationID, err)
|
||||||
|
|
||||||
// Malformed installationID
|
// Malformed installationID
|
||||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||||
|
@ -73,7 +81,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
||||||
})
|
})
|
||||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, ErrMalformedPushNotificationOptionsInstallationID, server.ValidateRegistration(nil, &key.PublicKey, cyphertext))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, cyphertext)
|
||||||
|
require.Equal(t, ErrMalformedPushNotificationOptionsInstallationID, err)
|
||||||
|
|
||||||
// Version set to 0
|
// Version set to 0
|
||||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||||
|
@ -84,7 +93,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
||||||
|
|
||||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, ErrInvalidPushNotificationOptionsVersion, server.ValidateRegistration(nil, &key.PublicKey, cyphertext))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, cyphertext)
|
||||||
|
require.Equal(t, ErrInvalidPushNotificationOptionsVersion, err)
|
||||||
|
|
||||||
// Version lower than previous one
|
// Version lower than previous one
|
||||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||||
|
@ -96,10 +106,11 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
||||||
|
|
||||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, ErrInvalidPushNotificationOptionsVersion, server.ValidateRegistration(&protobuf.PushNotificationOptions{
|
_, err = server.ValidateRegistration(&protobuf.PushNotificationOptions{
|
||||||
AccessToken: accessToken,
|
AccessToken: accessToken,
|
||||||
InstallationId: installationID,
|
InstallationId: installationID,
|
||||||
Version: 2}, &key.PublicKey, cyphertext))
|
Version: 2}, &key.PublicKey, cyphertext)
|
||||||
|
require.Equal(t, ErrInvalidPushNotificationOptionsVersion, err)
|
||||||
|
|
||||||
// Unregistering message
|
// Unregistering message
|
||||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||||
|
@ -111,7 +122,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
||||||
|
|
||||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Nil(t, server.ValidateRegistration(nil, &key.PublicKey, cyphertext))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, cyphertext)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
// Missing access token
|
// Missing access token
|
||||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||||
|
@ -122,7 +134,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
||||||
|
|
||||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, ErrMalformedPushNotificationOptionsAccessToken, server.ValidateRegistration(nil, &key.PublicKey, cyphertext))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, cyphertext)
|
||||||
|
require.Equal(t, ErrMalformedPushNotificationOptionsAccessToken, err)
|
||||||
|
|
||||||
// Invalid access token
|
// Invalid access token
|
||||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||||
|
@ -134,7 +147,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
||||||
|
|
||||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, ErrMalformedPushNotificationOptionsAccessToken, server.ValidateRegistration(nil, &key.PublicKey, cyphertext))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, cyphertext)
|
||||||
|
require.Equal(t, ErrMalformedPushNotificationOptionsAccessToken, err)
|
||||||
|
|
||||||
// Missing device token
|
// Missing device token
|
||||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||||
|
@ -146,6 +160,7 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
||||||
|
|
||||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, ErrMalformedPushNotificationOptionsDeviceToken, server.ValidateRegistration(nil, &key.PublicKey, cyphertext))
|
_, err = server.ValidateRegistration(nil, &key.PublicKey, cyphertext)
|
||||||
|
require.Equal(t, ErrMalformedPushNotificationOptionsDeviceToken, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue