Skip to content
Snippets Groups Projects
Denis kreiner's avatar
Denis kreiner authored
# Conflicts:
#   go.mod
#   go.sum
#   internal/common/consts.go
798d90d3
History

Storage Service

Use Modes

Remote

Type: REST Security: Client Authentication + Device Bound Tokens

The service can be used as a remote storage for mobile applications. In this case the storage verifies a device key against incoming tokens and accepts device registrations. For using this mode be aware that an additional protection by an mobile app protection framework is required to issue client certificates to establish an secure channel to the storage. An addtional fraud management can be docked by configuring the fraud management middleware.

Prerequisites

Each User must have the following preperations to use the backend:

  • Valid Account created and validated over the Account Service
  • Valid Client Certificate for mTLS
  • RSA PSS Certificate for Signing Tokens and Decrypting Receipts
  • RSA PSS Certificate to sign Credential Envelopes (Content Certificate)

Event

Type: NATS Security: API KEY

Direct

Type: REST Security: Standard JWK

API

Structure

TODO OPENAPI

Authorization Bearer

All credential routes are protected by a self signed token which must be created with the registered device key. The jwt must contain in the body:

  • Nonce (initial nonce or from receipt)
  • Subject (account id)

All nonces are just usable once and are invalid after receiving an receipt.

Example(signed with token from this repo):

eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiL3Rlc3QyL3RlbmFudF9zcGFjZS9BQkNEMTIzIl0sImV4cCI6MTcwMDUyNDU3OSwiaWF0IjoxNzAwNTIwOTc5LCJpc3MiOiJnaXRodWIuY29tL2xlc3RycmF0LWdvL2p3eCIsIm5vbmNlIjoiTlRVMU5RPT0iLCJzdWIiOiJBQkNEMTIzIn0.hOrqF6L6PaKsSOxlF6hUCBbDMJBhwXa7trqoW0cLw28CWv8bZxbWJccnfomkIin-ygJPsw4U7d8o4OHfhdHPETx7RGo2XBktIheERzivOORl3eDpqU7zfV9FTuU-U8dH9Tmx4HSpW9AS0c0SJjxzew4iwNC_UBy5KRBkgIwS7ZDNEDLpc4NTEwT9jfXwUUR6PopfeFr9kDtVEcmsXCxRVe8QQ_x_mFk_xtMoYzx-tKTLtXpH3KYKYmmAbcjkrfajcFi5w5Cai3OAO2ugfRZ6XTEev3_8SPMVgPq2Qoz2Ka3Cq26-7A7GzLrrLo5NAWe3urUMfxvtU9wsf_Wi535niw

Receipt

The receipt is returned in an JWE envelop adressed to the device key. After decrypting it, the receipt contains a nonce and nonce expired value for usage in the next call.

Usage

Register Device

Expects

Content-Type: application/json
Body: None
Method: GET

Example:

curl -H 'Authorization:Bearer eyJhbGciOiJFUzI1NiIsImp3ayI6eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiU2JTdlZNWGJDbjZnZWFMN1F1c3JtQk1nU29uRC1vclVkNUNUdGtLS1BmQSIsInkiOiJ1M2Fzd0tVbFVieGZjUXFLSUZJZGppdmZSbklEa3c2N0k4dUNGUjY4NmMwIn0sInR5cCI6IkpXVCJ9.eyJhdWQiOlsiL3RlbmFudF9zcGFjZS9BQkNEMTIzL3Rlc3QzIl0sImV4cCI6NTMwMjY0ODgxMywiaWF0IjoxNzAyNjUyNDEzLCJpc3MiOiJnaXRodWIuY29tL2xlc3RycmF0LWdvL2p3eCIsInN1YiI6IkFCQ0QxMjMifQ.VhLKC4ObpQuUq95aHIrhEAZXQS1lbvDEjAoExb3K4dfvjEOvWbPNc9ZE9119TpTMGmFtnJkFjIggh9hzbalTpA' https://.../ABCD123/device/registration/register

Returns

Content-Type: application/jose Body: JWE encrypted by RSA_OAEP_256 and AES256_GCM
Example:

eyJjaXBoZXJ0ZXh0IjoiTS15bE9BcURqVFl5cjcxMElaaXRyQUtQRWVZeldsTlVXZTJpV25uU3hnck1ZMm5CMUJTbi16N1otdldLX1ctV1Jyanktb0hXZml2Tnd3TWVrTmRFN0VfV1dvR3FCYWk4WGlhVlZQdHp6cDRjTHJ5aU5GQjVWUE1VOVB4VlZQdUhlbGtfc2JKSVM4UUxreGk3VlEiLCJlbmNyeXB0ZWRfa2V5IjoiS2FQV0ZfeDlLV0c3aU51WlkzUUlaV2xlNUFkUFgyUFhSaTFDa3F1VkhLMWJZQ0c5VHZ3ZnBnIiwiaGVhZGVyIjp7ImFsZyI6IkVDREgtRVMrQTI1NktXIiwiZXBrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiX0JqX0gweURldGJ6bFo4NVQ5dXdOLW5UQWhQSWp6cjdybi1vRDB0Z1cyQSIsInkiOiJ5bjJ0T2JPUElSaGdETDQwMWdhTjFRTHFCVkliTzdSdUhTclFzbkR1NGJJIn19LCJpdiI6ImlMN3MyaWxqLVNWc2xROXoiLCJwcm90ZWN0ZWQiOiJleUpoYkdjaU9pSkZRMFJJTFVWVEswRXlOVFpMVnlJc0ltVnVZeUk2SWtFeU5UWkhRMDBpTENKbGNHc2lPbnNpWTNKMklqb2lVQzB5TlRZaUxDSnJkSGtpT2lKRlF5SXNJbmdpT2lKZlFtcGZTREI1UkdWMFlucHNXamcxVkRsMWQwNHRibFJCYUZCSmFucHlOM0p1TFc5RU1IUm5WekpCSWl3aWVTSTZJbmx1TW5SUFlrOVFTVkpvWjBSTU5EQXhaMkZPTVZGTWNVSldTV0pQTjFKMVNGTnlVWE51UkhVMFlra2lmWDAiLCJ0YWciOiJPV3VNbFp1SnBUbDk2VkR0RkM2RVBBIn0=

Create Session

Add Credential

This route receives a JWE message which contains the credential encrypted by the Users Content Certificate.

Expects

Content-Type: application/jose
Body: JWE encrypted by RSA_OAEP_256 and AES256_GCM
Method: PUT

Example:

Returns

Content-Type: application/jose Body: JWE encrypted by RSA_OAEP_256 and AES256_GCM
Example:

Delete Credential Expects

Body: No Body Method: DELETE

Returns

Body: No Body

Get Credentials

Expects

Body: No Body Method: GET

Returns

Body:

Setup

1. Using makefile

make docker-compose-run

  1. Using docker compose directly
docker compose -f docker-compose.yml rm
docker compose -f docker-compose.yml --env-file=.env up --build --detach

Using Cassandra

Installation: https://cassandra.apache.org/_/quickstart.html

Python console: pip install -U cqlsh

Note: After bootstrapping the docker compose file, the initialize/insert container must be executed manually so long as no error occurs, because the cassandra DB needs a while to bootstrap.

Statements:

DESCRIBE keyspaces; //you should see tenant_space here select * from tenant_space.credentials;

Using Postman

Tokens+ PS256 Key Pairs can be created here: https://dinochiesa.github.io/jwt/

Sequence Diagram

title Cloud Storage 
alt case Registration
App->Module:Initialize Cloud Storage
Module->Module:Create Keypair for Content Encryption(CE) and create Keypair for Device Binding (DB)
Module->Module: Create Key Storage
Module<->Key Storage: Store Key Pair
Module<->Key Storage: Extract Public Key
Module<->Key Storage: Create Self Signed JWT
Module->Cloud Storage: Register Account with Self Signed JWT
Cloud Storage->Cloud Storage: Insert in Db/Register Device Key
Cloud Storage->Module: Recovery Nonce + Nonce
Module->Module: Sign Recovery Nonce with Device Key to RJWT
Module->Module: Create QR Code (RJWT, CE) 
Module->App: Please insert Password
App->Module:Password is...
Module->Module: Encrypt QR with KDF(PW) and base45 Encoding/Compression
Module->App: QR Code
end

alt Add Credential
App->Module: Store Credential
Module->Cloud Storage: Create Session
Cloud Storage->Module: Nonce
Module->Module: Sign JWT + Nonce with Device Key
Module->Module: Encrypt Credential with JWE
Module->Cloud Storage: Call Rest Api for Add Credential
Module->Module: Decrypt Response JWE
Module->App:  Reponse
end

alt Delete Credential
App->Module: Delete Credential
Module->Cloud Storage: Create Session
Cloud Storage->Module: Nonce
Module->Module: Sign JWT + Nonce with Device Key
Module->Cloud Storage: Call Rest Api for Delete Credential
Module->Module: Decrypt Response JWE
Module->App:  Response
end

alt Get Credentials
App->Module: Get Credentials
Module->Cloud Storage: Create Session
Cloud Storage->Module: Nonce
Module->Module: Sign JWT + Nonce with Device Key
Module->Cloud Storage: Call Rest Api for Get Credential
Module->Module: Decrypt Response JWE
Module->App:  Credentials
end