Page MenuHomePhabricator

[services] Backup - redesign proto
ClosedPublic

Authored by karol on Feb 3 2022, 6:47 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Apr 11, 3:23 AM
Unknown Object (File)
Thu, Apr 11, 3:23 AM
Unknown Object (File)
Thu, Apr 11, 3:23 AM
Unknown Object (File)
Thu, Apr 11, 3:23 AM
Unknown Object (File)
Thu, Apr 11, 3:23 AM
Unknown Object (File)
Thu, Apr 11, 3:22 AM
Unknown Object (File)
Tue, Apr 2, 3:43 AM
Unknown Object (File)
Sun, Mar 31, 2:31 AM

Details

Summary

Based on this revision: D2950
Adding proto file as discussed in the meeting and also as an introduction to implementing a new version of backup service.
This proto should be compatible with the API described in the linked revision.

Test Plan

grpc files generated successfully.

Diff Detail

Repository
rCOMM Comm
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
native/cpp/CommonCpp/grpc/protos/backup.proto
51–52 ↗(On Diff #9642)

Yes. This proto code is correct.

I think you miss one important thing here. Just because this object(CreateNewBackupResponse) comes after the keyword return does not mean that it is returned once. If you do something like this:

rpc CreateNewBackup(stream CreateNewBackupRequest) returns (stream CreateNewBackupResponse) {}

you can do a bidi stream in which you can do something like this:

[client] => [CreateNewBackupRequest] => [server]
[server] => [CreateNewBackupResponse] => [client]

[client] => [CreateNewBackupRequest] => [server]
[server] => [CreateNewBackupResponse] => [client]

// N times...

[client] => [CreateNewBackupRequest] => [server]
[server] => [CreateNewBackupResponse] => [client]

[end connection]
native/cpp/CommonCpp/grpc/protos/backup.proto
17 ↗(On Diff #9642)

yeah requestBytes and responseBytes is fine, I forgot that we wanted these gRPC messages to be generic. also these names match what the opaque-ke library uses so no need to reveal the cryptographic internals IMO.

Turned request bytes and response bytes into oneof definitions.

pakeRegistrationRequest: blinded password info (step 1 of PAKE registration)
pakeRegistrationResponse: server's public key and output of a cryptographic function (step 2 of PAKE registration)
pakeRegistrationUpload: envelope containing sealed cryptographic identifiers and the client’s public key (step 3 of PAKE registration)
pakeRegistrationSuccess: lets client know if registration was successful or not
pakeCredentialRequest: blinded password info (step 1 of PAKE login)
pakeCredentialResponse: sealed envelope only client can open (step 2 of PAKE login)
pakeCredentialFinalization: client answer to the server upon reception of stored envelope (step 3 of PAKE login)
pakeServerMAC: server sends MAC of a static string to client using the shared secret key
pakeClientMAC: client sends MAC of a static string to server using the shared secret key

change challenge-response auth to MAC

ashoat requested changes to this revision.Feb 17 2022, 10:33 PM
ashoat added inline comments.
native/cpp/CommonCpp/grpc/protos/backup.proto
23 ↗(On Diff #9770)

This is just a wallet address?

54–55 ↗(On Diff #9770)

What's the point of keeping these two separate? They are always served together, and if you combined them you might be able to reduce the number of individual messages that need to be sent. I suspect that nonce can be sent up at the same time as something else

This revision now requires changes to proceed.Feb 17 2022, 10:33 PM

I still don't understand why we cannot proceed here, implement the service leaving the places where the auth is supposed to be as TODOs and follow up with this in following diffs. What is the reason for this?

native/cpp/CommonCpp/grpc/protos/backup.proto
54–55 ↗(On Diff #9770)

They are always served together

I don't think so:

  • here, you have FullAuthenticationRequestData(FRQ) and AuthenticationInformationData(AD) servers together
  • in RecoverBackupKeyRequest you have FullAuthenticationRequestData(FRQ)
  • in RecoverBackupKeyResponse you have FullAuthenticationResponseData(FRS) and AuthenticationInformationData(AD)

Ok, we can merge AuthenticationInformationData into FullAuthenticationRequestData and FullAuthenticationResponseData, but:

  • it's going to be the same in both places, so we'll still need a separate type to follow the DRY rule
  • we'll have to have AuthenticationInformationData in RecoverBackupKeyRequest even though we don't need it there(we can assume what is the auth typer based on the recoveryData from the database, right?).

On the other hand it feels like raw message/nonce is a part of the auth process, so you can change it if you want.

native/cpp/CommonCpp/grpc/protos/backup.proto
23 ↗(On Diff #9770)

So I assume we'll need yet a couple more cycles since here there are going to be changes as well with the explicit types for the wallet, is this correct(IIRC wallet auth has more steps than just one for the full auth, right?)?

varun edited reviewers, added: karol; removed: varun.

After reading up on Sign-in with Ethereum (SIWE), I now understand that the only communication between client and server for wallet auth is:

  1. Client sends rawMessage to server, containing wallet address, timestamp, etc.
  2. Server validates the message per the EIP spec, and sends back a bool indicating the success/failure of said validation (if we were generating the message on the server we could omit this step, but we want to generate it on the client)

The rest of the auth process is with the user's wallet. Once the user is authenticated the server can send the desired data back to the client via gRPC.

native/cpp/CommonCpp/grpc/protos/backup.proto
23 ↗(On Diff #9770)

We can actually remove walletAuthenticationRequest entirely. The client only needs to send the rawMessage for full auth with wallet.

34 ↗(On Diff #9770)

this should be bool walletRawMessageValid = 5;

54–55 ↗(On Diff #9770)

I'm leaning towards keeping this as is, but can update if you feel strongly about it @ashoat

remove walletAuthenticationRequest, change walletAuthenticationResponse to walletRawMessageValid

karol edited reviewers, added: varun; removed: karol.
karol added inline comments.
native/cpp/CommonCpp/grpc/protos/backup.proto
53 ↗(On Diff #9780)

So we can go ahead and name narrow this name to be pake specific as wallet does not use this field at all, right?

I change these types a bit, please let me know if it's ok!

native/cpp/CommonCpp/grpc/protos/backup.proto
18–23 ↗(On Diff #9792)

not sure if nonce is supposed to be sent at the beginning or at the end?

ashoat requested changes to this revision.Feb 22 2022, 8:06 PM

Assuming we are still trying to get the auth right here, there are some changes we still need. Hopefully @varun can help with some of this stuff once he's feeling recovered. I think the pattern of commandeering the diff is a good one, and should make this a bit easier for @karol-bisztyga

native/cpp/CommonCpp/grpc/protos/backup.proto
18–23 ↗(On Diff #9792)

There are 6 request fields here but only 4 response fields. That doesn't add up... given that this is an interactive protocol, the the difference should be no more than 1.

I don't understand Protobufs well, but what we want to do is to represent each step of the interactive protocol. Eg. "first clients send A and B, then server returns C, then client sends D, then server returns E and F, etc."

  1. If two fields are sent together (like A and B or E and F), ideally we can make this explicit in the API by combining them into some sort of struct
  2. The oneof blocks inside PakeAuthenticationRequestData and PakeAuthenticationResponseData (and other comparable message declarations) should have one line for each step
25 ↗(On Diff #9792)

Why are we sending this up every time we send up any one of the six fields above? We should only need to send up the userID once

29–30 ↗(On Diff #9792)

You're not even including the wallet address?

41 ↗(On Diff #9792)

We obviously need more here

97–99 ↗(On Diff #9792)

These three get sent back together, so they should be combined

This revision now requires changes to proceed.Feb 22 2022, 8:06 PM
karol added inline comments.
native/cpp/CommonCpp/grpc/protos/backup.proto
18–23 ↗(On Diff #9792)

These types have been added by @varun, Varun could you answer this, please?

25 ↗(On Diff #9792)

I think so.

29–30 ↗(On Diff #9792)

It is basen on the Varun's comment:

After reading up on Sign-in with Ethereum (SIWE), I now understand that the only communication between client and server for wallet auth is:

  1. Client sends rawMessage to server, containing wallet address, timestamp, etc.
  2. Server validates the message per the EIP spec, and sends back a bool indicating the success/failure of said validation (if we were generating the message on the server we could omit this step, but we want to generate it on the client)

The rest of the auth process is with the user's wallet. Once the user is authenticated the server can send the desired data back to the client via gRPC.

@varun can you clarify?

41 ↗(On Diff #9792)

as above

native/cpp/CommonCpp/grpc/protos/backup.proto
97–99 ↗(On Diff #9792)

Do they? I thought we are supposed to send either nonce or rawMessage depending on whether we use pake or wallet. So it could look more like this:

oneof {
  {
    nonce
    backupID
  }
  {
    rawMessage
    backupID
  }
}

But this is a more complicated structure.

Sounds like @varun will need to take a pass on this and he is a bit sick right now, plus @jimpo is out. Sorry for continuing to block you here @karol-bisztyga

native/cpp/CommonCpp/grpc/protos/backup.proto
97–99 ↗(On Diff #9792)

Good call, you're right

varun edited reviewers, added: karol; removed: varun.
native/cpp/CommonCpp/grpc/protos/backup.proto
29–30 ↗(On Diff #9792)
  1. userID
  2. rawMessage
  3. walletAddress
  4. signedMessage
ashoat requested changes to this revision.Feb 27 2022, 8:54 PM

To your queue

This revision now requires changes to proceed.Feb 27 2022, 8:54 PM

addressing feedback. fixed wallet auth structures, removed redundant messages, moved entropy values to separate message

native/cpp/CommonCpp/grpc/protos/backup.proto
18–23 ↗(On Diff #9792)

nonce should probably be sent after password auth is complete, and since it's only part of CreateNewBackup and not part of RecoverBackupKey (which also uses the FullAuthenticationRequestData message), it should be moved out to CreateNewBackupRequest.

25 ↗(On Diff #9792)

fixed in latest revision

29–30 ↗(On Diff #9792)

after discussing this with ashoat, we're moving rawMessage to CreateNewBackupRequest too, since it's specific to that RPC

41 ↗(On Diff #9792)

discussed with ashoat, don't think we need anything else here

ashoat added 1 blocking reviewer(s): karol.

This looks pretty much ready to go to me. @karol-bisztyga should definitely take a look before we land, and would be great to get @geekbrother and maybe @jimpo's eyes on it as well.

native/cpp/CommonCpp/grpc/protos/backup.proto
18 ↗(On Diff #9952)

For consistency with the rest of the codebase (and the identifier name here), please capitalize ID at the end of PakeRegistrationRequestAndUserId

89 ↗(On Diff #9952)

What's this entropyValid message communicate, and in what cases would the entry be invalid?

110–111 ↗(On Diff #9952)

Instead of listing these two individually here, can/should we just have them combined by NewBackupKeyEntropy?

karol edited reviewers, added: varun; removed: karol.

LGTM, I'm going to commandeer this and push the final(I hope) changes.

native/cpp/CommonCpp/grpc/protos/backup.proto
26–29 ↗(On Diff #9952)

NIT: It should be before PakeAuthenticationRequestData

110–111 ↗(On Diff #9952)

I think so

This revision is now accepted and ready to land.Mar 2 2022, 6:12 AM
native/cpp/CommonCpp/grpc/protos/backup.proto
89 ↗(On Diff #9952)

I was thinking there might be some constraints that the server should enforce, e.g. rawMessage can’t be a duplicate

This revision was automatically updated to reflect the committed changes.