From 0b73ad041748308ffa7ff65d0cff689696ae0ceb Mon Sep 17 00:00:00 2001 From: Roman <96019015+RomanHarazha@users.noreply.github.com> Date: Tue, 27 Feb 2024 18:39:23 +0200 Subject: [PATCH] Feature/vault (#3) * remove user data from the database; move blinder and issuer auth data to the vault * minor config fix * remove unused func * import dig lib --- config.yaml | 6 +- go.mod | 15 ++- go.sum | 51 +++++++- internal/assets/migrations/001_initial.sql | 13 +- internal/assets/migrations/002_claims.sql | 13 -- internal/config/issuer.go | 32 ++++- internal/config/main.go | 3 + internal/config/vault.go | 50 +++++++ internal/config/verifier.go | 10 -- internal/data/claims.go | 8 +- internal/data/main.go | 1 - internal/data/pg/main.go | 4 - internal/data/pg/proofs.go | 40 ------ internal/data/proofs.go | 20 --- .../service/api/handlers/create_identity.go | 122 +++++++++++------- internal/service/api/handlers/ctx.go | 22 +--- .../api/handlers/get_document_nullifier.go | 7 +- internal/service/issuer/main.go | 8 +- internal/service/main.go | 2 +- internal/service/router.go | 15 ++- internal/service/vault/main.go | 82 ++++++++++++ 21 files changed, 342 insertions(+), 182 deletions(-) delete mode 100644 internal/assets/migrations/002_claims.sql create mode 100644 internal/config/vault.go delete mode 100644 internal/data/pg/proofs.go delete mode 100644 internal/data/proofs.go create mode 100644 internal/service/vault/main.go diff --git a/config.yaml b/config.yaml index d896847..26c2ae4 100644 --- a/config.yaml +++ b/config.yaml @@ -1,3 +1,6 @@ +vault: + address: "http://127.0.0.1:8200" + network: eth_rpc: state_contract: @@ -8,13 +11,10 @@ verifier: sha256: "./sha256_verification_key.json" master_certs_path: "./masterList.dev.pem" allowed_age: 18 - blinder: 1 # big value required issuer: base_url: "http://localhost:3002/v1" did: "" - auth_username: "" - auth_password: "" claim_type: "VotingCredential" credential_schema: "https://bafybeibbniic63etdbcn5rs5ir5bhelym6ogv46afj35keatzhn2eqnioi.ipfs.w3s.link/VotingCredential.json" diff --git a/go.mod b/go.mod index 760b0d7..a81f2b3 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/go-chi/chi v4.1.2+incompatible github.com/go-ozzo/ozzo-validation/v4 v4.2.1 github.com/google/uuid v1.3.0 + github.com/hashicorp/vault/api v1.12.0 github.com/iden3/contracts-abi/state/go/abi v1.0.1 github.com/iden3/go-iden3-core/v2 v2.0.4 github.com/iden3/go-iden3-crypto v0.0.15 @@ -19,6 +20,7 @@ require ( github.com/rarimo/certificate-transparency-go v0.0.0-20240216144634-4291bc43f73b github.com/rubenv/sql-migrate v1.6.1 gitlab.com/distributed_lab/ape v1.7.1 + gitlab.com/distributed_lab/dig v0.0.0-20230207152643-c44f80a4294c gitlab.com/distributed_lab/figure v2.1.0+incompatible gitlab.com/distributed_lab/figure/v3 v3.1.3 gitlab.com/distributed_lab/kit v1.11.2 @@ -32,6 +34,7 @@ require ( github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect github.com/andybalholm/brotli v1.0.6 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/cenkalti/backoff/v3 v3.0.0 // indirect github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect @@ -40,6 +43,7 @@ require ( github.com/getsentry/raven-go v0.2.0 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect + github.com/go-jose/go-jose/v3 v3.0.1 // indirect github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect @@ -47,7 +51,13 @@ require ( github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.6.6 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/uint256 v1.2.0 // indirect github.com/jmoiron/sqlx v1.2.0 // indirect @@ -56,7 +66,8 @@ require ( github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/magiconair/properties v1.8.0 // indirect - github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/onsi/ginkgo/v2 v2.13.2 // indirect @@ -66,6 +77,7 @@ require ( github.com/quic-go/qtls-go1-20 v0.4.1 // indirect github.com/quic-go/quic-go v0.40.1 // indirect github.com/refraction-networking/utls v1.6.0 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/afero v1.1.2 // indirect @@ -84,6 +96,7 @@ require ( golang.org/x/net v0.21.0 // indirect golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.16.1 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index e6b82e4..1a1069f 100644 --- a/go.sum +++ b/go.sum @@ -25,15 +25,19 @@ github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8V github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= +github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894 h1:JLaf/iINcLyjwbtTsCJjc6rtlASgHeIJPrB6QmwURnA= github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= @@ -78,6 +82,9 @@ github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHj github.com/ethereum/go-ethereum v1.11.5 h1:3M1uan+LAUvdn+7wCEFrcMM4LJTeuxDrPTg/f31a5QQ= github.com/ethereum/go-ethereum v1.11.5/go.mod h1:it7x0DWnTDMfVFdXcU6Ti4KEFQynLHVRarcSlPr0HBo= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -106,6 +113,8 @@ github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxI github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= +github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= +github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= @@ -120,6 +129,8 @@ github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= +github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= @@ -137,6 +148,7 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -155,11 +167,31 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs= +github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM= +github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/vault/api v1.12.0 h1:meCpJSesvzQyao8FCOgk2fGdoADAnbDu2WPJN1lDLJ4= +github.com/hashicorp/vault/api v1.12.0/go.mod h1:si+lJCYO7oGkIoNPAN8j3azBLTn9SjMGS+jFaHd1Cck= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= @@ -228,9 +260,11 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= @@ -248,10 +282,14 @@ github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQth github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -282,6 +320,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= @@ -315,6 +354,8 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -345,8 +386,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= @@ -379,6 +420,8 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDf github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= gitlab.com/distributed_lab/ape v1.7.1 h1:LpTmZgG7Lvx6ulopQbH2aWI3s8ey9FsKVjbic3ZQIy4= gitlab.com/distributed_lab/ape v1.7.1/go.mod h1:Qy9Y2arL0hmZIpVpctGEFhdrVsjWtyVJ5G+bZWcFT4s= +gitlab.com/distributed_lab/dig v0.0.0-20230207152643-c44f80a4294c h1:cqPwdAw7oJpNeN0F80bg5vNI5t3oJoSCPSnC6oj+Zyw= +gitlab.com/distributed_lab/dig v0.0.0-20230207152643-c44f80a4294c/go.mod h1:NT4H8lLoIqJxFa9AM88+6uUZ38BmxnFU8VOm/LJYUF4= gitlab.com/distributed_lab/figure v2.1.0+incompatible h1:8kNtvWO91BSQ4OsqL2P3qNWSBnh/Q/TdWB8vHy8xvNI= gitlab.com/distributed_lab/figure v2.1.0+incompatible/go.mod h1:tk+aPBohT49MGPLy5+eVbE1HpD/CaC5drBHfVpRI8eE= gitlab.com/distributed_lab/figure/v3 v3.1.3 h1:gCHplT1Ih8B1s4eYTeAhRZyto3gIWoUCUj3yYfNM4r8= @@ -399,6 +442,7 @@ go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= @@ -420,6 +464,7 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/internal/assets/migrations/001_initial.sql b/internal/assets/migrations/001_initial.sql index 4a87e5f..9775e14 100644 --- a/internal/assets/migrations/001_initial.sql +++ b/internal/assets/migrations/001_initial.sql @@ -1,11 +1,10 @@ -- +migrate Up -create table proofs( - id bigserial primary key, - did text not null, - data jsonb not null, - pub_signals jsonb not null, - document_sod jsonb not null +create table claims( + id uuid primary key, + user_did text not null, + issuer_did text not null, + document_hash text not null ); -- +migrate Down -drop table proofs; \ No newline at end of file +drop table claims; \ No newline at end of file diff --git a/internal/assets/migrations/002_claims.sql b/internal/assets/migrations/002_claims.sql deleted file mode 100644 index 9b1c810..0000000 --- a/internal/assets/migrations/002_claims.sql +++ /dev/null @@ -1,13 +0,0 @@ --- +migrate Up -alter table proofs add column claim_id uuid; - -create table claims( - id uuid primary key, - user_did text not null, - issuer_did text not null, - document text not null unique -); - --- +migrate Down -alter table proofs drop column claim_id; -drop table claims; \ No newline at end of file diff --git a/internal/config/issuer.go b/internal/config/issuer.go index 6444516..2c1e852 100644 --- a/internal/config/issuer.go +++ b/internal/config/issuer.go @@ -1,9 +1,13 @@ package config import ( + "fmt" + "github.com/iden3/go-iden3-core/v2/w3c" "gitlab.com/distributed_lab/figure" "gitlab.com/distributed_lab/kit/comfig" "gitlab.com/distributed_lab/kit/kv" + "gitlab.com/distributed_lab/logan/v3/errors" + "reflect" ) type IssuerConfiger interface { @@ -11,12 +15,10 @@ type IssuerConfiger interface { } type IssuerConfig struct { - BaseUrl string `fig:"base_url,required"` - AuthUsername string `fig:"auth_username,required"` - AuthPassword string `fig:"auth_password,required"` - DID string `fig:"did,required"` - ClaimType string `fig:"claim_type,required"` - CredentialSchema string `fig:"credential_schema,required"` + BaseUrl string `fig:"base_url,required"` + DID *w3c.DID `fig:"did,required"` + ClaimType string `fig:"claim_type,required"` + CredentialSchema string `fig:"credential_schema,required"` } type issuer struct { @@ -36,6 +38,7 @@ func (i *issuer) IssuerConfig() *IssuerConfig { err := figure. Out(&result). + With(figure.BaseHooks, iden3Hooks). From(kv.MustGetStringMap(i.getter, "issuer")). Please() if err != nil { @@ -45,3 +48,20 @@ func (i *issuer) IssuerConfig() *IssuerConfig { return &result }).(*IssuerConfig) } + +var iden3Hooks = figure.Hooks{ + "*w3c.DID": func(value interface{}) (reflect.Value, error) { + switch v := value.(type) { + case string: + did, err := w3c.ParseDID(v) + if err != nil { + return reflect.Value{}, errors.Wrap(err, "failed to parse DID") + } + return reflect.ValueOf(did), nil + case nil: + return reflect.ValueOf(nil), nil + default: + return reflect.Value{}, fmt.Errorf("unsupported conversion from %T", value) + } + }, +} diff --git a/internal/config/main.go b/internal/config/main.go index c80e8cc..c7c7e94 100644 --- a/internal/config/main.go +++ b/internal/config/main.go @@ -17,6 +17,7 @@ type Config interface { IssuerConfiger VerifierConfiger NetworkConfiger + VaultConfiger } type config struct { @@ -29,6 +30,7 @@ type config struct { IssuerConfiger VerifierConfiger NetworkConfiger + VaultConfiger } func New(getter kv.Getter) Config { @@ -41,5 +43,6 @@ func New(getter kv.Getter) Config { IssuerConfiger: NewIssuerConfiger(getter), VerifierConfiger: NewVerifierConfiger(getter), NetworkConfiger: NewNetworkConfiger(getter), + VaultConfiger: NewVaultConfiger(getter), } } diff --git a/internal/config/vault.go b/internal/config/vault.go new file mode 100644 index 0000000..b2ccb3c --- /dev/null +++ b/internal/config/vault.go @@ -0,0 +1,50 @@ +package config + +import ( + "gitlab.com/distributed_lab/dig" + "gitlab.com/distributed_lab/figure/v3" + "gitlab.com/distributed_lab/kit/comfig" + "gitlab.com/distributed_lab/kit/kv" +) + +type VaultConfiger interface { + VaultConfig() *VaultConfig +} + +type VaultConfig struct { + Address string `fig:"address,required"` + Token string `dig:"VAULT_TOKEN,clear"` +} + +type vault struct { + once comfig.Once + getter kv.Getter +} + +func NewVaultConfiger(getter kv.Getter) VaultConfiger { + return &vault{ + getter: getter, + } +} + +func (v *vault) VaultConfig() *VaultConfig { + return v.once.Do(func() interface{} { + var result VaultConfig + + err := figure. + Out(&result). + From(kv.MustGetStringMap(v.getter, "vault")). + Please() + if err != nil { + panic(err) + } + + if err := dig.Out(&result).Where(map[string]interface{}{ + "address": result.Address, + }).Now(); err != nil { + panic(err) + } + + return &result + }).(*VaultConfig) +} diff --git a/internal/config/verifier.go b/internal/config/verifier.go index 47d762a..6562ea2 100644 --- a/internal/config/verifier.go +++ b/internal/config/verifier.go @@ -4,8 +4,6 @@ import ( "gitlab.com/distributed_lab/figure/v3" "gitlab.com/distributed_lab/kit/comfig" "gitlab.com/distributed_lab/kit/kv" - "gitlab.com/distributed_lab/logan/v3/errors" - "math/big" "os" ) @@ -17,7 +15,6 @@ type VerifierConfig struct { VerificationKeys map[string][]byte MasterCerts []byte AllowedAge int - Blinder *big.Int } type verifier struct { @@ -37,7 +34,6 @@ func (v *verifier) VerifierConfig() *VerifierConfig { VerificationKeysPaths map[string]string `fig:"verification_keys_paths,required"` MasterCertsPath string `fig:"master_certs_path,required"` AllowedAge int `fig:"allowed_age,required"` - Blinder string `fig:"blinder,required"` }{} err := figure. @@ -63,16 +59,10 @@ func (v *verifier) VerifierConfig() *VerifierConfig { panic(err) } - blinder, ok := new(big.Int).SetString(newCfg.Blinder, 10) - if !ok { - panic(errors.New("failed to set blinder string to big.Int")) - } - return &VerifierConfig{ VerificationKeys: verificationKeys, MasterCerts: masterCerts, AllowedAge: newCfg.AllowedAge, - Blinder: blinder, } }).(*VerifierConfig) } diff --git a/internal/data/claims.go b/internal/data/claims.go index 1de952e..91f261c 100644 --- a/internal/data/claims.go +++ b/internal/data/claims.go @@ -14,8 +14,8 @@ type ClaimQ interface { } type Claim struct { - ID uuid.UUID `db:"id" structs:"id"` - UserDID string `db:"user_did" structs:"user_did"` - IssuerDID string `db:"issuer_did" structs:"issuer_did"` - Document string `db:"document" structs:"document"` + ID uuid.UUID `db:"id" structs:"id"` + UserDID string `db:"user_did" structs:"user_did"` + IssuerDID string `db:"issuer_did" structs:"issuer_did"` + DocumentHash string `db:"document_hash" structs:"document_hash"` } diff --git a/internal/data/main.go b/internal/data/main.go index 59e6a49..207c0ba 100644 --- a/internal/data/main.go +++ b/internal/data/main.go @@ -3,7 +3,6 @@ package data type MasterQ interface { New() MasterQ - Proof() ProofQ Claim() ClaimQ Transaction(fn func(db MasterQ) error) error diff --git a/internal/data/pg/main.go b/internal/data/pg/main.go index f6f8e1a..7c2826d 100644 --- a/internal/data/pg/main.go +++ b/internal/data/pg/main.go @@ -25,10 +25,6 @@ func (m *masterQ) Transaction(fn func(q data.MasterQ) error) error { }) } -func (m *masterQ) Proof() data.ProofQ { - return NewProofsQ(m.db) -} - func (m *masterQ) Claim() data.ClaimQ { return NewClaimsQ(m.db) } diff --git a/internal/data/pg/proofs.go b/internal/data/pg/proofs.go deleted file mode 100644 index 172ea1e..0000000 --- a/internal/data/pg/proofs.go +++ /dev/null @@ -1,40 +0,0 @@ -package pg - -import ( - sq "github.com/Masterminds/squirrel" - "github.com/fatih/structs" - "github.com/rarimo/passport-identity-provider/internal/data" - "gitlab.com/distributed_lab/kit/pgdb" -) - -const proofsTableName = "proofs" - -var ( - proofsSelector = sq.Select("*").From(proofsTableName) - proofsUpdate = sq.Update(proofsTableName) -) - -func NewProofsQ(db *pgdb.DB) data.ProofQ { - return &proofsQ{ - db: db, - sql: proofsSelector, - upd: proofsUpdate, - } -} - -type proofsQ struct { - db *pgdb.DB - sql sq.SelectBuilder - upd sq.UpdateBuilder -} - -func (q *proofsQ) New() data.ProofQ { - return NewProofsQ(q.db.Clone()) -} - -func (q *proofsQ) Insert(value data.Proof) error { - clauses := structs.Map(value) - stmt := sq.Insert(proofsTableName).SetMap(clauses) - err := q.db.Exec(stmt) - return err -} diff --git a/internal/data/proofs.go b/internal/data/proofs.go deleted file mode 100644 index 22ff615..0000000 --- a/internal/data/proofs.go +++ /dev/null @@ -1,20 +0,0 @@ -package data - -import ( - "encoding/json" - "github.com/google/uuid" -) - -type ProofQ interface { - New() ProofQ - Insert(value Proof) error -} - -type Proof struct { - ID int64 `db:"id" structs:"-"` - DID string `db:"did" structs:"did"` - ClaimID uuid.UUID `db:"claim_id" structs:"claim_id"` - Data json.RawMessage `db:"data" structs:"data"` - PubSignals json.RawMessage `db:"pub_signals" structs:"pub_signals"` - DocumentSOD json.RawMessage `db:"document_sod" structs:"document_sod"` -} diff --git a/internal/service/api/handlers/create_identity.go b/internal/service/api/handlers/create_identity.go index 52924f9..28c5a92 100644 --- a/internal/service/api/handlers/create_identity.go +++ b/internal/service/api/handlers/create_identity.go @@ -9,7 +9,6 @@ import ( "crypto/sha256" "encoding/asn1" "encoding/hex" - "encoding/json" "encoding/pem" "fmt" "math/big" @@ -19,6 +18,7 @@ import ( "time" "github.com/google/uuid" + "github.com/iden3/go-iden3-crypto/poseidon" "github.com/iden3/go-rapidsnark/verifier" "github.com/rarimo/certificate-transparency-go/x509" "github.com/rarimo/passport-identity-provider/internal/config" @@ -43,13 +43,14 @@ const ( SHA256withECDSA = "SHA256withECDSA" ) -var algorithms = map[string]string{ - "SHA256withRSA": SHA256withRSA, - - "SHA1withECDSA": SHA1withECDSA, - "ecdsa-with-SHA1": SHA1withECDSA, - - "SHA256withECDSA": SHA256withECDSA, +var algorithmsListMap = map[string]map[string]string{ + "SHA1": { + "ECDSA": SHA1withECDSA, + }, + "SHA256": { + "RSA": SHA256withRSA, + "ECDSA": SHA256withECDSA, + }, } func CreateIdentity(w http.ResponseWriter, r *http.Request) { @@ -59,7 +60,9 @@ func CreateIdentity(w http.ResponseWriter, r *http.Request) { return } - if err := verifySignature(req); err != nil { + algorithm := signatureAlgorithm(req.Data.DocumentSOD.Algorithm) + + if err := verifySignature(req, algorithm); err != nil { Log(r).WithError(err).Error("failed to verify signature") ape.RenderErr(w, problems.InternalError()) return @@ -67,7 +70,7 @@ func CreateIdentity(w http.ResponseWriter, r *http.Request) { cfg := VerifierConfig(r) - switch algorithms[req.Data.DocumentSOD.Algorithm] { + switch algorithm { case SHA1withECDSA: if err := verifier.VerifyGroth16(req.Data.ZKProof, cfg.VerificationKeys[SHA1]); err != nil { Log(r).WithError(err).Error("failed to verify Groth16") @@ -80,6 +83,10 @@ func CreateIdentity(w http.ResponseWriter, r *http.Request) { ape.RenderErr(w, problems.BadRequest(err)...) return } + default: + Log(r).WithField("algorithm", req.Data.DocumentSOD.Algorithm).Debug("invalid signature algorithm") + ape.RenderErr(w, problems.BadRequest(errors.New("invalid signature algorithm"))...) + return } encapsulatedContentBytes, err := hex.DecodeString(req.Data.DocumentSOD.EncapsulatedContent) @@ -153,11 +160,26 @@ func CreateIdentity(w http.ResponseWriter, r *http.Request) { var claimID string iss := Issuer(r) + vaultClient := VaultClient(r) + + blinder, err := vaultClient.Blinder() + if err != nil { + Log(r).WithError(err).Error("failed to get blinder from the vault") + ape.RenderErr(w, problems.InternalError()) + return + } + + hash, err := signedAttributesPoseidonHash(req.Data.DocumentSOD.SignedAttributes, blinder) + if err != nil { + Log(r).WithError(err).Error("failed to get signed attributes Poseidon hash") + ape.RenderErr(w, problems.InternalError()) + return + } if err := masterQ.Transaction(func(db data.MasterQ) error { // check if there are any claims for this document already claims, err := db.Claim().ResetFilter(). - FilterBy("document", req.Data.DocumentSOD.SignedAttributes). + FilterBy("document_hash", hash.String()). ForUpdate(). Select() if err != nil { @@ -175,14 +197,14 @@ func CreateIdentity(w http.ResponseWriter, r *http.Request) { claimID, err = iss.IssueVotingClaim( req.Data.ID, int64(issuingAuthority), true, identityExpiration, - encapsulatedData.PrivateKey.El2.OctetStr.Bytes, cfg.Blinder, + encapsulatedData.PrivateKey.El2.OctetStr.Bytes, blinder, ) if err != nil { ape.RenderErr(w, problems.InternalError()) return errors.Wrap(err, "failed to issue voting claim") } - if err := writeDataToDB(db, req, claimID, iss.DID()); err != nil { + if err := writeDataToDB(db, req, claimID, iss.DID(), hash.String()); err != nil { ape.RenderErr(w, problems.InternalError()) return errors.Wrap(err, "failed to write proof to the database") } @@ -210,6 +232,41 @@ func CreateIdentity(w http.ResponseWriter, r *http.Request) { ape.Render(w, response) } +func signatureAlgorithm(passedAlgorithm string) string { + if strings.Contains(strings.ToUpper(passedAlgorithm), "PSS") { + return "" // RSA-PSS is not currently supported + } + + for hashFunc, signatureAlgorithms := range algorithmsListMap { + if strings.Contains(strings.ToUpper(passedAlgorithm), hashFunc) { + for signatureAlgo, algorithmName := range signatureAlgorithms { + if strings.Contains(strings.ToUpper(passedAlgorithm), signatureAlgo) { + return algorithmName + } + } + } + } + return "" +} + +func signedAttributesPoseidonHash(signedAttributes string, blinder *big.Int) (*big.Int, error) { + signedAttributesBytes, err := hex.DecodeString(signedAttributes) + if err != nil { + return nil, errors.Wrap(err, "failed to decode hex string") + } + + dataToHash := make([]byte, 0) + dataToHash = append(dataToHash, signedAttributesBytes...) + dataToHash = append(dataToHash, blinder.Bytes()...) + + hash, err := poseidon.HashBytes(dataToHash) + if err != nil { + return nil, errors.Wrap(err, "failed to hash data using Poseidon") + } + + return hash, nil +} + func revokeOutdatedClaim(db data.MasterQ, iss *issuer.Issuer, claimID uuid.UUID) error { cred, err := iss.GetCredential(claimID) if err != nil { @@ -229,42 +286,17 @@ func revokeOutdatedClaim(db data.MasterQ, iss *issuer.Issuer, claimID uuid.UUID) return nil } -func writeDataToDB(db data.MasterQ, req requests.CreateIdentityRequest, claimIDStr, issuerDID string) error { - proofData, err := json.Marshal(req.Data.ZKProof.Proof) - if err != nil { - return errors.Wrap(err, "failed to marshal JSON") - } - - pubSignals, err := json.Marshal(req.Data.ZKProof.PubSignals) - if err != nil { - return errors.Wrap(err, "failed to marshal JSON") - } - - DocumentSOD, err := json.Marshal(req.Data.DocumentSOD) - if err != nil { - return errors.Wrap(err, "failed to marshal JSON") - } - +func writeDataToDB(db data.MasterQ, req requests.CreateIdentityRequest, claimIDStr, issuerDID, hash string) error { claimID, err := uuid.Parse(claimIDStr) if err != nil { return errors.Wrap(err, "failed to parse uuid") } - if err := db.Proof().Insert(data.Proof{ - DID: req.Data.ID, - ClaimID: claimID, - Data: proofData, - PubSignals: pubSignals, - DocumentSOD: DocumentSOD, - }); err != nil { - return errors.Wrap(err, "failed to insert proof in the database") - } - if err := db.Claim().Insert(data.Claim{ - ID: claimID, - UserDID: req.Data.ID, - IssuerDID: issuerDID, - Document: req.Data.DocumentSOD.SignedAttributes, + ID: claimID, + UserDID: req.Data.ID, + IssuerDID: issuerDID, + DocumentHash: hash, }); err != nil { return errors.Wrap(err, "failed to insert claim in the database") } @@ -272,7 +304,7 @@ func writeDataToDB(db data.MasterQ, req requests.CreateIdentityRequest, claimIDS return nil } -func verifySignature(req requests.CreateIdentityRequest) error { +func verifySignature(req requests.CreateIdentityRequest, algo string) error { block, _ := pem.Decode([]byte(req.Data.DocumentSOD.PemFile)) if block == nil { return fmt.Errorf("invalid certificate: invalid PEM") @@ -293,7 +325,7 @@ func verifySignature(req requests.CreateIdentityRequest) error { return errors.Wrap(err, "failed to decode hex string") } - switch algorithms[req.Data.DocumentSOD.Algorithm] { + switch algo { case SHA256withRSA: pubKey := cert.PublicKey.(*rsa.PublicKey) diff --git a/internal/service/api/handlers/ctx.go b/internal/service/api/handlers/ctx.go index cc61e42..c5d19d5 100644 --- a/internal/service/api/handlers/ctx.go +++ b/internal/service/api/handlers/ctx.go @@ -6,6 +6,7 @@ import ( "github.com/rarimo/passport-identity-provider/internal/config" "github.com/rarimo/passport-identity-provider/internal/data" "github.com/rarimo/passport-identity-provider/internal/service/issuer" + "github.com/rarimo/passport-identity-provider/internal/service/vault" "gitlab.com/distributed_lab/logan/v3" "net/http" ) @@ -18,8 +19,7 @@ const ( verifierConfigKey stateContractKey issuerCtxKey - proofsQKey - claimsQKey + vaultClientCtxKey ) func CtxLog(entry *logan.Entry) func(context.Context) context.Context { @@ -72,22 +72,12 @@ func Issuer(r *http.Request) *issuer.Issuer { return r.Context().Value(issuerCtxKey).(*issuer.Issuer) } -func CtxProofsQ(entry data.ProofQ) func(context.Context) context.Context { +func CtxVaultClient(vaultClient *vault.VaultClient) func(context.Context) context.Context { return func(ctx context.Context) context.Context { - return context.WithValue(ctx, proofsQKey, entry) + return context.WithValue(ctx, vaultClientCtxKey, vaultClient) } } -func ProofsQ(r *http.Request) data.ProofQ { - return r.Context().Value(proofsQKey).(data.ProofQ).New() -} - -func CtxClaimsQ(entry data.ClaimQ) func(context.Context) context.Context { - return func(ctx context.Context) context.Context { - return context.WithValue(ctx, claimsQKey, entry) - } -} - -func ClaimsQ(r *http.Request) data.ClaimQ { - return r.Context().Value(claimsQKey).(data.ClaimQ).New() +func VaultClient(r *http.Request) *vault.VaultClient { + return r.Context().Value(vaultClientCtxKey).(*vault.VaultClient) } diff --git a/internal/service/api/handlers/get_document_nullifier.go b/internal/service/api/handlers/get_document_nullifier.go index 1a7357e..c5a1f81 100644 --- a/internal/service/api/handlers/get_document_nullifier.go +++ b/internal/service/api/handlers/get_document_nullifier.go @@ -33,7 +33,12 @@ func GetDocumentNullifier(w http.ResponseWriter, r *http.Request) { nullifierHashInput = append(nullifierHashInput, new(big.Int).SetBytes(dg2HashBytes)) } - nullifierHashInput = append(nullifierHashInput, VerifierConfig(r).Blinder) + blinder, err := VaultClient(r).Blinder() + if err != nil { + Log(r).WithError(err).Error("failed to get blinder from the vault") + } + + nullifierHashInput = append(nullifierHashInput, blinder) nullifierHash, err := poseidon.Hash(nullifierHashInput) if err != nil { diff --git a/internal/service/issuer/main.go b/internal/service/issuer/main.go index 6c959d0..4e7e1d6 100644 --- a/internal/service/issuer/main.go +++ b/internal/service/issuer/main.go @@ -20,13 +20,14 @@ type Issuer struct { did string } -func New(log *logan.Entry, config *config.IssuerConfig) *Issuer { +func New(log *logan.Entry, config *config.IssuerConfig, login, password string) *Issuer { return &Issuer{ client: req.C(). SetBaseURL(config.BaseUrl). + SetCommonBasicAuth(login, password). SetLogger(log), cfg: config, - did: config.DID, + did: config.DID.String(), } } @@ -80,7 +81,6 @@ func (is *Issuer) IssueVotingClaim( } response, err := is.client.R(). - SetBasicAuth(is.cfg.AuthUsername, is.cfg.AuthPassword). SetBodyJsonMarshal(credentialRequest). SetSuccessResult(&result). Post("/credentials") @@ -99,7 +99,6 @@ func (is *Issuer) GetCredential(claimID uuid.UUID) (GetCredentialResponse, error var cred GetCredentialResponse response, err := is.client.R(). - SetBasicAuth(is.cfg.AuthUsername, is.cfg.AuthPassword). SetSuccessResult(&cred). SetPathParam("id", claimID.String()). Get("/credentials/{id}") @@ -116,7 +115,6 @@ func (is *Issuer) GetCredential(claimID uuid.UUID) (GetCredentialResponse, error func (is *Issuer) RevokeClaim(revocationNonce int64) error { response, err := is.client.R(). - SetBasicAuth(is.cfg.AuthUsername, is.cfg.AuthPassword). SetPathParam("nonce", strconv.FormatInt(revocationNonce, 10)). Post("/credentials/revoke/{nonce}") if err != nil { diff --git a/internal/service/main.go b/internal/service/main.go index 416c26b..d92fb6f 100644 --- a/internal/service/main.go +++ b/internal/service/main.go @@ -1,10 +1,10 @@ package service import ( - "github.com/rarimo/passport-identity-provider/internal/config" "net" "net/http" + "github.com/rarimo/passport-identity-provider/internal/config" "gitlab.com/distributed_lab/kit/copus/types" "gitlab.com/distributed_lab/logan/v3" "gitlab.com/distributed_lab/logan/v3/errors" diff --git a/internal/service/router.go b/internal/service/router.go index 27eef65..ab34ff3 100644 --- a/internal/service/router.go +++ b/internal/service/router.go @@ -8,6 +8,7 @@ import ( "github.com/rarimo/passport-identity-provider/internal/data/pg" "github.com/rarimo/passport-identity-provider/internal/service/api/handlers" "github.com/rarimo/passport-identity-provider/internal/service/issuer" + "github.com/rarimo/passport-identity-provider/internal/service/vault" "gitlab.com/distributed_lab/ape" ) @@ -22,6 +23,16 @@ func (s *service) router() chi.Router { s.log.WithError(err).Fatal("failed to init state contract") } + vaultClient, err := vault.NewVaultClient(s.cfg.VaultConfig()) + if err != nil { + s.log.WithError(err).Fatal("failed to init new vault client") + } + + issuerLogin, issuerPassword, err := vaultClient.IssuerAuthData() + if err != nil { + s.log.WithError(err).Fatal("failed to get issuer auth data from the vault") + } + r := chi.NewRouter() r.Use( @@ -32,12 +43,12 @@ func (s *service) router() chi.Router { handlers.CtxMasterQ(pg.NewMasterQ(s.cfg.DB())), handlers.CtxVerifierConfig(s.cfg.VerifierConfig()), handlers.CtxStateContract(stateContract), - handlers.CtxProofsQ(pg.NewProofsQ(s.cfg.DB())), - handlers.CtxClaimsQ(pg.NewClaimsQ(s.cfg.DB())), handlers.CtxIssuer(issuer.New( s.cfg.Log().WithField("service", "issuer"), s.cfg.IssuerConfig(), + issuerLogin, issuerPassword, )), + handlers.CtxVaultClient(vaultClient), ), ) r.Route("/integrations/identity-provider-service", func(r chi.Router) { diff --git a/internal/service/vault/main.go b/internal/service/vault/main.go new file mode 100644 index 0000000..1ebfa14 --- /dev/null +++ b/internal/service/vault/main.go @@ -0,0 +1,82 @@ +package vault + +import ( + "context" + vaultapi "github.com/hashicorp/vault/api" + "github.com/rarimo/passport-identity-provider/internal/config" + "gitlab.com/distributed_lab/figure/v3" + "gitlab.com/distributed_lab/logan/v3/errors" + "math/big" +) + +const ( + vaultMountPath = "secret" + vaultIssuerPath = "issuer" + vaultVerifierPath = "verifier" +) + +type VaultClient struct { + client *vaultapi.Client +} + +func NewVaultClient(config *config.VaultConfig) (*VaultClient, error) { + conf := vaultapi.DefaultConfig() + conf.Address = config.Address + + client, err := vaultapi.NewClient(conf) + if err != nil { + return nil, errors.Wrap(err, "failed to initialize new client") + } + + client.SetToken(config.Token) + + return &VaultClient{client: client}, nil +} + +func (v *VaultClient) IssuerAuthData() (string, string, error) { + conf := struct { + IssuerLogin string `fig:"login,required"` + IssuerPassword string `fig:"password,required"` + }{} + + secret, err := v.client.KVv2(vaultMountPath).Get(context.Background(), vaultIssuerPath) + if err != nil { + return "", "", errors.Wrap(err, "failed to get secret") + } + + if err := figure. + Out(&conf). + With(figure.BaseHooks). + From(secret.Data). + Please(); err != nil { + return "", "", errors.Wrap(err, "failed to figure out") + } + + return conf.IssuerLogin, conf.IssuerPassword, nil +} + +func (v *VaultClient) Blinder() (*big.Int, error) { + conf := struct { + Blinder string `fig:"blinder,required"` + }{} + + secret, err := v.client.KVv2(vaultMountPath).Get(context.Background(), vaultVerifierPath) + if err != nil { + return nil, errors.Wrap(err, "failed to get secret") + } + + if err := figure. + Out(&conf). + With(figure.BaseHooks). + From(secret.Data). + Please(); err != nil { + return nil, errors.Wrap(err, "failed to figure out") + } + + blinder, ok := new(big.Int).SetString(conf.Blinder, 10) + if !ok { + return nil, errors.New("failed to set string to big.Int") + } + + return blinder, nil +}