Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ticket ownership validation/authentication API middleware #4

Open
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

itswisdomagain
Copy link

@itswisdomagain itswisdomagain commented Aug 1, 2019

Current API routes are mounted on /api/v1/* and /api/v2/*; and authentication is carried out by providing an API access token in the Authorization request header field in the format:
Authorization: Bearer <api key>

This PR adds a new authentication scheme for API endpoints in addition to/without removing the current Bearer auth scheme. The added TicketAuth scheme performs ticket-level authentication before executing requested actions. Clients can thus provide authentication information in the Authorization request header field in the format:
Authorization: TicketAuth SignedTimestamp=1564531200, Signature=frJIUN8DYpKDtOLCwo, TicketHash=591b17ed03afc916f274669939924e12ed5ac90d8cc602172fb53237b8a20522

Where;

  • TicketAuth: is the authentication scheme
  • SignedTimestamp: is the unix timestamp as at the time of request
  • Signature (base64 string): the result of signing the timestamp above using the private key for the ticket reward address belonging to the user's wallet (see below)
  • TicketHash: the hash of the ticket for which the requested operation is to be performed

This authorization header format matches that defined in RFC2617. See this SO answer.

User's ticket reward address

A ticket purchased with voting rights shared with a vsp has 2 sstxcommitment outputs for receiving staking reward. One of these addresses belongs to the vsp wallet, while the other belongs to the ticket owner's wallet. This second address belonging to the ticket owner is what is used in preparing the Signature passed in the authentication header as described above.

@itswisdomagain itswisdomagain force-pushed the ticket-auth branch 2 times, most recently from 66c1943 to a2f89e6 Compare August 1, 2019 21:37
@JoeGruffins
Copy link

This is a cool idea! Are you going to bring it over to decred's repo?

@itswisdomagain itswisdomagain marked this pull request as ready for review August 2, 2019 23:45
beansgum
beansgum previously approved these changes Aug 7, 2019
@xaur
Copy link

xaur commented Aug 7, 2019

Great to see work on this! Just curious

  1. why the ticket reward address private key and not just ticket address private key was chosen?
  2. how the signature is produced?

@itswisdomagain
Copy link
Author

  1. why the ticket reward address private key and not just ticket address private key was chosen?

The ticket address cannot be signed by the user using his wallet.

  1. how the signature is produced?

User signs a message from his wallet using an address that belongs to the wallet (the ticket reward address). The message the user signs is the current unix timestamp in seconds.

@xaur
Copy link

xaur commented Aug 8, 2019

The ticket address cannot be signed by the user using his wallet.

I guess you mean it cannot be used to sign. Why? Is it because it is a multisig?

User signs a message from his wallet using an address that belongs to the wallet (the ticket reward address). The message the user signs is the current unix timestamp in seconds.

I mean how the signature bytes are generated, what algorithm is used?

@itswisdomagain
Copy link
Author

I guess you mean it cannot be used to sign. Why? Is it because it is a multisig?

Yes, that's what I meant (apologies). And yes, that's why.

I mean how the signature bytes are generated, what algorithm is used?

https://github.com/decred/dcrwallet/blob/master/wallet/wallet.go#L1428. The message signed ought to be the unix timestamp (in seconds) as at the time of making the request. While the timestamp may be earlier, it cannot be later than the current timestamp. Also, the server rejects timestamps that are up to/more than 30 minutes earlier than the current timestamp.

@xaur
Copy link

xaur commented Aug 10, 2019

Where I'm getting at, is that the signature scheme is defined by the hash algo (Blake256 I guess) and signing algo (SignCompact) used. This combination is bound to the name TicketAuth in Authorization header. I wondered, what if this scheme changes? Is it common to version such things, e.g. Authorization: TicketAuth v1 ...?

@itswisdomagain
Copy link
Author

Where I'm getting at, is that the signature scheme is defined by the hash algo (Blake256 I guess) and signing algo (SignCompact) used. This combination is bound to the name TicketAuth in Authorization header. I wondered, what if this scheme changes? Is it common to version such things, e.g. Authorization: TicketAuth v1 ...?

Apologies for late reply. I see a valid concern there. It's not common to version auth schemes in that manner. We could use a different scheme name should/when the need arise, such as TicketAuthV2.

Your question has even given me further mental clarification. It is unnecessary to mount a new API version endpoint (v3) to allow authentication using this auth scheme. Only need to modify the code to be able to process the new auth scheme on any of the current API version endpoints (v1, v2) if it is supplied. The current scheme supported for API authorization is Bearer token. What I'd do instead is check for the auth scheme present in the auth header and invoke the proper validation routine to do its work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants