Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into feature/supported-open-telemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabe authored Jul 19, 2022
2 parents fa51042 + f4983b2 commit af7c804
Show file tree
Hide file tree
Showing 30 changed files with 1,790 additions and 657 deletions.
26 changes: 21 additions & 5 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package config

import (
"fmt"
"github.com/BurntSushi/toml"
"github.com/ardanlabs/conf"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"os"
"path/filepath"
"reflect"
"time"

"github.com/BurntSushi/toml"
"github.com/ardanlabs/conf"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

const (
Expand All @@ -32,7 +33,7 @@ type ServerConfig struct {
ReadTimeout time.Duration `toml:"read_timeout" conf:"default:5s"`
WriteTimeout time.Duration `toml:"write_timeout" conf:"default:5s"`
ShutdownTimeout time.Duration `toml:"shutdown_timeout" conf:"default:5s"`
LogLocation string `toml:"log_location"`
LogLocation string `toml:"log_location" conf:"default:log"`
LogLevel string `toml:"log_level" conf:"default:debug"`
}

Expand All @@ -48,6 +49,7 @@ type ServicesConfig struct {
DIDConfig DIDServiceConfig `toml:"did,omitempty"`
SchemaConfig SchemaServiceConfig `toml:"schema,omitempty"`
CredentialConfig CredentialServiceConfig `toml:"credential,omitempty"`
KeyStoreConfig KeyStoreServiceConfig `toml:"keystore,omitempty"`
}

// BaseServiceConfig represents configurable properties for a specific component of the SSI Service
Expand Down Expand Up @@ -84,6 +86,13 @@ type CredentialServiceConfig struct {
// TODO(gabe) supported key and signature types
}

type KeyStoreServiceConfig struct {
*BaseServiceConfig
// Service key password. Used by a KDF whose key is used by a symmetric cypher for key encryption.
// The password is salted before usage.
ServiceKeyPassword string
}

// LoadConfig attempts to load a TOML config file from the given path, and coerce it into our object model.
// Before loading, defaults are applied on certain properties, which are overwritten if specified in the TOML file.
func LoadConfig(path string) (*SSIServiceConfig, error) {
Expand Down Expand Up @@ -134,6 +143,13 @@ func LoadConfig(path string) (*SSIServiceConfig, error) {
SchemaConfig: SchemaServiceConfig{
BaseServiceConfig: &BaseServiceConfig{Name: "schema"},
},
CredentialConfig: CredentialServiceConfig{
BaseServiceConfig: &BaseServiceConfig{Name: "credential"},
},
KeyStoreConfig: KeyStoreServiceConfig{
BaseServiceConfig: &BaseServiceConfig{Name: "keystore"},
ServiceKeyPassword: "default-password",
},
}
} else {
// load from TOML file
Expand Down
119 changes: 113 additions & 6 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,17 @@ definitions:
status:
type: string
type: object
github.com_tbd54566975_ssi-service_pkg_server_router.GetKeyDetailsResponse:
properties:
controller:
type: string
createdAt:
type: string
id:
type: string
type:
type: string
type: object
github.com_tbd54566975_ssi-service_pkg_server_router.GetSchemaResponse:
properties:
schema:
Expand All @@ -279,6 +290,22 @@ definitions:
$ref: '#/definitions/schema.VCJSONSchema'
type: array
type: object
github.com_tbd54566975_ssi-service_pkg_server_router.StoreKeyRequest:
properties:
base58PrivateKey:
type: string
controller:
type: string
id:
type: string
type:
type: string
required:
- base58PrivateKey
- controller
- id
- type
type: object
pkg_server_router.CreateCredentialRequest:
properties:
'@context':
Expand Down Expand Up @@ -373,6 +400,17 @@ definitions:
status:
type: string
type: object
pkg_server_router.GetKeyDetailsResponse:
properties:
controller:
type: string
createdAt:
type: string
id:
type: string
type:
type: string
type: object
pkg_server_router.GetSchemaResponse:
properties:
schema:
Expand All @@ -385,6 +423,22 @@ definitions:
$ref: '#/definitions/schema.VCJSONSchema'
type: array
type: object
pkg_server_router.StoreKeyRequest:
properties:
base58PrivateKey:
type: string
controller:
type: string
id:
type: string
type:
type: string
required:
- base58PrivateKey
- controller
- id
- type
type: object
schema.JSONSchema:
additionalProperties: true
type: object
Expand Down Expand Up @@ -429,7 +483,7 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetHealthCheckResponse'
$ref: '#/definitions/pkg_server_router.GetHealthCheckResponse'
summary: Health Check
tags:
- HealthCheck
Expand Down Expand Up @@ -580,7 +634,7 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/pkg_server_router.GetDIDMethodsResponse'
$ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetDIDMethodsResponse'
summary: Get DID Methods
tags:
- DecentralizedIdentityAPI
Expand All @@ -595,7 +649,7 @@ paths:
name: request
required: true
schema:
$ref: '#/definitions/pkg_server_router.CreateDIDByMethodRequest'
$ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.CreateDIDByMethodRequest'
- description: Method
in: path
name: method
Expand All @@ -607,7 +661,7 @@ paths:
"201":
description: Created
schema:
$ref: '#/definitions/pkg_server_router.CreateDIDByMethodResponse'
$ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.CreateDIDByMethodResponse'
"400":
description: Bad request
schema:
Expand All @@ -630,7 +684,7 @@ paths:
name: request
required: true
schema:
$ref: '#/definitions/pkg_server_router.CreateDIDByMethodRequest'
$ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.CreateDIDByMethodRequest'
- description: Method
in: path
name: method
Expand All @@ -647,14 +701,67 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/pkg_server_router.GetDIDByMethodResponse'
$ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetDIDByMethodResponse'
"400":
description: Bad request
schema:
type: string
summary: Get DID
tags:
- DecentralizedIdentityAPI
/v1/keys:
put:
consumes:
- application/json
description: Stores a key to be used by the service
parameters:
- description: request body
in: body
name: request
required: true
schema:
$ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.StoreKeyRequest'
produces:
- application/json
responses:
"201":
description: ""
"400":
description: Bad request
schema:
type: string
"500":
description: Internal server error
schema:
type: string
summary: Store Key
tags:
- KeyStoreAPI
/v1/keys/{id}:
get:
consumes:
- application/json
description: Get details about a stored key
parameters:
- description: ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetKeyDetailsResponse'
"400":
description: Bad request
schema:
type: string
summary: Get Details For Key
tags:
- KeyStoreAPI
/v1/schemas:
get:
consumes:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.17

require (
github.com/BurntSushi/toml v1.1.0
github.com/TBD54566975/ssi-sdk v0.0.0-20220705213209-17514605afb5
github.com/TBD54566975/ssi-sdk v0.0.0-20220719010135-e2fdcfb80e49
github.com/ardanlabs/conf v1.5.0
github.com/boltdb/bolt v1.3.1
github.com/dimfeld/httptreemux/v5 v5.4.0
Expand Down
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/TBD54566975/ssi-sdk v0.0.0-20220705213209-17514605afb5 h1:UDTN4mYVOsFKH8yDs7kljkT4OMZIkmgGuDXOGrsZGq8=
github.com/TBD54566975/ssi-sdk v0.0.0-20220705213209-17514605afb5/go.mod h1:VqKlHw4Oz1ncfavUamyO16VckHMz9APwiYd3GFc/Jgg=
github.com/TBD54566975/ssi-sdk v0.0.0-20220719010135-e2fdcfb80e49 h1:BozkJ4jg1nZyTzBs/ltNq+KtTuveZDh48Ax85cVh0M4=
github.com/TBD54566975/ssi-sdk v0.0.0-20220719010135-e2fdcfb80e49/go.mod h1:uWJkLbobBINP2QFVFL5kku5GtCmbmggzCHh8sTH5NYs=
github.com/ardanlabs/conf v1.5.0 h1:5TwP6Wu9Xi07eLFEpiCUF3oQXh9UzHMDVnD3u/I5d5c=
github.com/ardanlabs/conf v1.5.0/go.mod h1:ILsMo9dMqYzCxDjDXTiwMI0IgxOJd0MOiucbQY2wlJw=
github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
Expand Down Expand Up @@ -32,8 +32,6 @@ github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2B
github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.9.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.9.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.9.10 h1:hCeNmprSNLB8B8vQKWl6DpuH0t60oEs+TAk9a7CScKc=
github.com/goccy/go-json v0.9.10/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
Expand Down
96 changes: 96 additions & 0 deletions internal/util/crypto.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package util

import (
"crypto/rand"

"github.com/pkg/errors"
"golang.org/x/crypto/argon2"
"golang.org/x/crypto/chacha20poly1305"
)

const (
// Argon2SaltSize represents the recommended salt size for argon2, which is 16 bytes
// https://tools.ietf.org/id/draft-irtf-cfrg-argon2-05.html#rfc.section.3.1
Argon2SaltSize = 16

// default parameters from https://pkg.go.dev/golang.org/x/crypto/argon2
argon2Time = 1

// From the godoc: the number of passes over the memory and the
// memory parameter specifies the size of the memory in KiB. For example
// memory=64*1024 sets the memory cost to ~64 MB. The number of threads can be
// adjusted to the numbers of available CPUs. The cost parameters should be
// increased as memory latency and CPU parallelism increases
argon2Memory = 64 * 1024
threads = 4
)

// XChaCha20Poly1305Encrypt takes a 32 byte key and uses XChaCha20-Poly1305 to encrypt a piece of data
func XChaCha20Poly1305Encrypt(key, data []byte) ([]byte, error) {
aead, err := chacha20poly1305.NewX(key)
if err != nil {
return nil, errors.Wrap(err, "could not create aead with provided key")
}

// generate a random nonce, leaving room for the ciphertext
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(data)+aead.Overhead())
if _, err := rand.Read(nonce); err != nil {
return nil, errors.Wrap(err, "could not generate nonce for encryption")
}

encrypted := aead.Seal(nonce, nonce, data, nil)
return encrypted, nil
}

// XChaCha20Poly1305Decrypt takes a 32 byte key and uses XChaCha20-Poly1305 to decrypt a piece of data
func XChaCha20Poly1305Decrypt(key, data []byte) ([]byte, error) {
aead, err := chacha20poly1305.NewX(key)
if err != nil {
return nil, errors.Wrap(err, "could not create aead with provided key")
}

if len(data) < aead.NonceSize() {
panic("ciphertext too short")
}

// split nonce and ciphertext
nonce, ciphertext := data[:aead.NonceSize()], data[aead.NonceSize():]

// Decrypt the message and check it wasn't tampered with.
decyrpted, err := aead.Open(nil, nonce, ciphertext, nil)
if err != nil {
return nil, errors.Wrap(err, "could not decrypt data")
}
return decyrpted, nil
}

// Argon2KeyGen returns an encoded string generation of a key generated using the go crypto argon2 impl
// specifically, the Argon2id version, a "hybrid version of Argon2 combining Argon2i and Argon2d."
func Argon2KeyGen(password string, salt []byte, keyLen int) ([]byte, error) {
if password == "" {
return nil, errors.New("password cannot be empty")
}
if len(salt) == 0 {
return nil, errors.New("salt cannot be empty")
}
if keyLen <= 0 {
return nil, errors.New("invalid key length")
}

key := argon2.IDKey([]byte(password), salt, argon2Time, argon2Memory, threads, uint32(keyLen))
return key, nil
}

// GenerateSalt generates a random salt value for a given size
func GenerateSalt(size int) ([]byte, error) {
if size <= 0 {
return nil, errors.New("invalid size")
}

salt := make([]byte, size)
if _, err := rand.Read(salt[:]); err != nil {
return nil, err
}

return salt, nil
}
Loading

0 comments on commit af7c804

Please sign in to comment.