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
|
||||
}
|
||||
|
||||
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 {
|
||||
return ErrEmptyPushNotificationOptionsPayload
|
||||
return nil, ErrEmptyPushNotificationOptionsPayload
|
||||
}
|
||||
|
||||
if publicKey == nil {
|
||||
return ErrEmptyPushNotificationOptionsPublicKey
|
||||
return nil, ErrEmptyPushNotificationOptionsPublicKey
|
||||
}
|
||||
|
||||
sharedKey, err := p.generateSharedKey(publicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decryptedPayload, err := decrypt(payload, sharedKey)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
preferences := &protobuf.PushNotificationOptions{}
|
||||
options := &protobuf.PushNotificationOptions{}
|
||||
|
||||
if err := proto.Unmarshal(decryptedPayload, preferences); err != nil {
|
||||
return ErrCouldNotUnmarshalPushNotificationOptions
|
||||
if err := proto.Unmarshal(decryptedPayload, options); err != nil {
|
||||
return nil, ErrCouldNotUnmarshalPushNotificationOptions
|
||||
}
|
||||
|
||||
if preferences.Version < 1 {
|
||||
return ErrInvalidPushNotificationOptionsVersion
|
||||
if options.Version < 1 {
|
||||
return nil, ErrInvalidPushNotificationOptionsVersion
|
||||
}
|
||||
|
||||
if previousPreferences != nil && preferences.Version <= previousPreferences.Version {
|
||||
return ErrInvalidPushNotificationOptionsVersion
|
||||
if previousOptions != nil && options.Version <= previousOptions.Version {
|
||||
return nil, ErrInvalidPushNotificationOptionsVersion
|
||||
}
|
||||
|
||||
if err := p.validateUUID(preferences.InstallationId); err != nil {
|
||||
return ErrMalformedPushNotificationOptionsInstallationID
|
||||
if err := p.validateUUID(options.InstallationId); err != nil {
|
||||
return nil, ErrMalformedPushNotificationOptionsInstallationID
|
||||
}
|
||||
|
||||
// Unregistering message
|
||||
if preferences.Unregister {
|
||||
return nil
|
||||
if options.Unregister {
|
||||
return options, nil
|
||||
}
|
||||
|
||||
if err := p.validateUUID(preferences.AccessToken); err != nil {
|
||||
return ErrMalformedPushNotificationOptionsAccessToken
|
||||
if err := p.validateUUID(options.AccessToken); err != nil {
|
||||
return nil, ErrMalformedPushNotificationOptionsAccessToken
|
||||
}
|
||||
|
||||
if len(preferences.Token) == 0 {
|
||||
return ErrMalformedPushNotificationOptionsDeviceToken
|
||||
if len(options.Token) == 0 {
|
||||
return nil, ErrMalformedPushNotificationOptionsDeviceToken
|
||||
}
|
||||
fmt.Println(decryptedPayload)
|
||||
|
||||
/*if newRegistration.Version < 1 {
|
||||
return ErrInvalidPushNotificationOptionsVersion
|
||||
}*/
|
||||
return nil
|
||||
return options, nil
|
||||
}
|
||||
|
||||
func decrypt(cyphertext []byte, key []byte) ([]byte, error) {
|
||||
|
|
|
@ -30,29 +30,36 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// 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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
cyphertext, err := encrypt([]byte("plaintext"), make([]byte, 32), rand.Reader)
|
||||
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
|
||||
cyphertext, err = encrypt([]byte("plaintext"), sharedKey, rand.Reader)
|
||||
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
|
||||
payload, err := proto.Marshal(&protobuf.PushNotificationOptions{
|
||||
|
@ -63,7 +70,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
|||
|
||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||
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
|
||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||
|
@ -73,7 +81,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
|||
})
|
||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||
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
|
||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||
|
@ -84,7 +93,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
|||
|
||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||
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
|
||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||
|
@ -96,10 +106,11 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
|||
|
||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, ErrInvalidPushNotificationOptionsVersion, server.ValidateRegistration(&protobuf.PushNotificationOptions{
|
||||
_, err = server.ValidateRegistration(&protobuf.PushNotificationOptions{
|
||||
AccessToken: accessToken,
|
||||
InstallationId: installationID,
|
||||
Version: 2}, &key.PublicKey, cyphertext))
|
||||
Version: 2}, &key.PublicKey, cyphertext)
|
||||
require.Equal(t, ErrInvalidPushNotificationOptionsVersion, err)
|
||||
|
||||
// Unregistering message
|
||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||
|
@ -111,7 +122,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
|||
|
||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||
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
|
||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||
|
@ -122,7 +134,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
|||
|
||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||
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
|
||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||
|
@ -134,7 +147,8 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
|||
|
||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||
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
|
||||
payload, err = proto.Marshal(&protobuf.PushNotificationOptions{
|
||||
|
@ -146,6 +160,7 @@ func TestPushNotificationServerValidateRegistration(t *testing.T) {
|
|||
|
||||
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
|
||||
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