diff --git a/go.mod b/go.mod index 51461f9..45af64d 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/rarimo/certificate-transparency-go v0.0.0-20240305114501-050b1f19639a github.com/rubenv/sql-migrate v1.6.1 + github.com/stretchr/testify v1.8.4 gitlab.com/distributed_lab/ape v1.7.1 gitlab.com/distributed_lab/figure/v3 v3.1.4 gitlab.com/distributed_lab/kit v1.11.3 @@ -35,6 +36,7 @@ require ( github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect @@ -68,6 +70,7 @@ require ( github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect diff --git a/go.sum b/go.sum index 461b85d..d1795f9 100644 --- a/go.sum +++ b/go.sum @@ -1543,8 +1543,6 @@ github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoG github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/jsonapi v0.0.0-20200226002910-c8283f632fb7 h1:aQ4kMXDAmP9IRIZHcSKB2orXHGwGiSxH4PX1BzKHR50= github.com/google/jsonapi v0.0.0-20200226002910-c8283f632fb7/go.mod h1:XSx4m2SziAqk9DXY9nz659easTq4q6TyrpYd9tHSm0g= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= diff --git a/internal/config/keys.go b/internal/config/keys.go index 15ce48a..fae7bda 100644 --- a/internal/config/keys.go +++ b/internal/config/keys.go @@ -26,7 +26,7 @@ type Keys struct { } type KeysConfig struct { - SignatureKey *ecdsa.PrivateKey `fig:"signature_key,required"` + SignatureKey *ecdsa.PrivateKey `fig:"signature_key"` } func (e *Keys) KeysConfig() KeysConfig { diff --git a/internal/config/vault.go b/internal/config/vault.go index cfc4339..8fb3f27 100644 --- a/internal/config/vault.go +++ b/internal/config/vault.go @@ -21,9 +21,8 @@ type VaultConfiger interface { } type VaultConfig struct { - MountPath string `json:"VAULT_MOUNT_PATH"` - PrivateKeyPath string `json:"VAULT_PRIVATE_KEY_PATH"` - SecretPath string `json:"VAULT_SECRET_PATH"` + MountPath string `json:"VAULT_MOUNT_PATH"` + SecretPath string `json:"VAULT_SECRET_PATH"` } type ClientKeysCredentialsConfig struct { diff --git a/internal/service/api/handlers/register.go b/internal/service/api/handlers/register.go index 703127f..3320982 100644 --- a/internal/service/api/handlers/register.go +++ b/internal/service/api/handlers/register.go @@ -14,6 +14,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/google/jsonapi" "github.com/iden3/go-iden3-crypto/poseidon" + "github.com/iden3/go-rapidsnark/verifier" errors2 "github.com/pkg/errors" "github.com/rarimo/passport-identity-provider/internal/config" "github.com/rarimo/passport-identity-provider/internal/data" @@ -121,16 +122,16 @@ func Register(w http.ResponseWriter, r *http.Request) { verifierCfg := api.VerifierConfig(r) - //if err := verifier.VerifyGroth16( - // req.Data.Attributes.ZkProof, - // verifierCfg.VerificationKeys[algorithmPair.HashAlgorithm], - //); err != nil { - // log.WithError(err).Error("failed to verify zk proof") - // jsonError = problems.BadRequest(validation.Errors{ - // "zk_proof": err, - // }) - // return - //} + if err := verifier.VerifyGroth16( + req.Data.Attributes.ZkProof, + verifierCfg.VerificationKeys[algorithmPair.HashAlgorithm], + ); err != nil { + log.WithError(err).Error("failed to verify zk proof") + jsonError = problems.BadRequest(validation.Errors{ + "zk_proof": err, + }) + return + } signedAttributes, err := hex.DecodeString(utils.TruncateHexPrefix(documentSOD.SignedAttributes)) if err != nil { @@ -330,12 +331,12 @@ func Register(w http.ResponseWriter, r *http.Request) { } func verifySod( - signedAttributes []byte, - encapsulatedContent []byte, - signature []byte, - cert *x509.Certificate, - algorithmPair types.AlgorithmPair, - cfg *config.VerifierConfig, + signedAttributes []byte, + encapsulatedContent []byte, + signature []byte, + cert *x509.Certificate, + algorithmPair types.AlgorithmPair, + cfg *config.VerifierConfig, ) error { if err := validateSignedAttributes(signedAttributes, encapsulatedContent, algorithmPair.HashAlgorithm); err != nil { return &types.SodError{ @@ -396,9 +397,9 @@ func parseCertificate(pemFile []byte) (*x509.Certificate, error) { } func validateSignedAttributes( - signedAttributes, - encapsulatedContent []byte, - hashAlgorithm types.HashAlgorithm, + signedAttributes, + encapsulatedContent []byte, + hashAlgorithm types.HashAlgorithm, ) error { signedAttributesASN1 := make([]asn1.RawValue, 0) @@ -436,10 +437,10 @@ func validateSignedAttributes( } func verifySignature( - signature []byte, - cert *x509.Certificate, - signedAttributes []byte, - algorithmPair types.AlgorithmPair, + signature []byte, + cert *x509.Certificate, + signedAttributes []byte, + algorithmPair types.AlgorithmPair, ) error { h := types.GeneralHash(algorithmPair.HashAlgorithm) h.Write(signedAttributes) diff --git a/internal/utils/asn1_operations.go b/internal/utils/asn1_operations.go index 7d4a78a..43e6a75 100644 --- a/internal/utils/asn1_operations.go +++ b/internal/utils/asn1_operations.go @@ -59,8 +59,8 @@ func TruncateHexPrefix(hexString string) string { } func BuildSignedData( - contract, verifier *common.Address, - passportHash, dg1Commitment, publicKey [32]byte, + contract, verifier *common.Address, + passportHash, dg1Commitment, publicKey [32]byte, ) ([]byte, error) { return abiEncodePacked(types.RegistrationSimplePrefix, contract, passportHash[:], dg1Commitment[:], publicKey[:], verifier) } @@ -135,7 +135,7 @@ func ToEthSignedMessageHash(data []byte) []byte { } func TruncateDg1Hash(dg1Hash []byte) (dg1Truncated [32]byte) { - truncateStart := types.DG1TruncateLength - len(dg1Hash) + truncateStart := 32 - len(dg1Hash) dg1HashStart := 0 if len(dg1Hash) > types.DG1TruncateLength { dg1HashStart = len(dg1Hash) - types.DG1TruncateLength diff --git a/internal/utils/asn1_operations_test.go b/internal/utils/asn1_operations_test.go new file mode 100644 index 0000000..0578fd8 --- /dev/null +++ b/internal/utils/asn1_operations_test.go @@ -0,0 +1,81 @@ +package utils + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTruncateDg1Hash(t *testing.T) { + tests := []struct { + name string + inputHash []byte + expected [32]byte + }{ + { + name: "16-byte hash", + inputHash: bytes.Repeat([]byte{0xDD}, 16), // Example: 16 bytes of 0xDD + expected: func() [32]byte { + var result [32]byte + copy(result[32-16:], bytes.Repeat([]byte{0xDD}, 32)) + return result + }(), + }, + { + name: "20-byte hash", + inputHash: bytes.Repeat([]byte{0xAA}, 20), // Example: 20 bytes of 0xAA + expected: func() [32]byte { + var result [32]byte + copy(result[32-20:], bytes.Repeat([]byte{0xAA}, 32)) + return result + }(), + }, + { + name: "32-byte hash", + inputHash: bytes.Repeat([]byte{0xBB}, 32), // Example: 32 bytes of 0xBB + expected: func() [32]byte { + var result [32]byte + copy(result[1:], bytes.Repeat([]byte{0xBB}, 32)) + return result + }(), + }, + { + name: "48-byte hash", + inputHash: bytes.Repeat([]byte{0xBB}, 48), // Example: 48 bytes of 0xBB + expected: func() [32]byte { + var result [32]byte + copy(result[1:], bytes.Repeat([]byte{0xBB}, 32)) + return result + }(), + }, + { + name: "64-byte hash", + inputHash: bytes.Repeat([]byte{0xCC}, 64), // Example: 64 bytes of 0xCC + expected: func() [32]byte { + var result [32]byte + copy(result[1:], bytes.Repeat([]byte{0xCC}, 32)) + return result + }(), + }, + { + name: "128-byte hash", + inputHash: bytes.Repeat([]byte{0xCC}, 128), // Example: 128 bytes of 0xCC (I don't know if this even possible, but just in case) + expected: func() [32]byte { + var result [32]byte + copy(result[1:], bytes.Repeat([]byte{0xCC}, 32)) + return result + }(), + }, + + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := TruncateDg1Hash(tt.inputHash) + t.Logf("Input Hash: \t\t0x%X", tt.inputHash) + t.Logf("Truncated Result:\t0x%X", result) + assert.Equal(t, tt.expected, result, "Truncated hash should match expected value") + }) + } +}