-
Notifications
You must be signed in to change notification settings - Fork 0
Identity Validation Review
The O Blockchain implements a generic identity validation system that supports multiple Proof of Personhood (PoP) providers. This document reviews the current implementation, identifies issues, and proposes improvements.
The system is designed to support multiple identity providers through a generic CUserVerificationData structure:
-
BrightID (
identity_provider == "brightid")- Social graph-based verification
- Most integrated provider (dedicated integration code)
-
KYC Providers (
identity_provider.starts_with("kyc_"))- Country-specific KYC providers
- Examples:
kyc_usa,kyc_fra,kyc_mex, etc. - Supports different providers per country
-
WorldCoin (
identity_provider == "worldcoin")- Orb-based biometric verification
- Mentioned in code but not fully implemented
-
Idena (
identity_provider == "idena")- Cryptographic verification protocol
- Mentioned in code but not fully implemented
-
Unknown/Custom Providers
- Currently accepted with minimal validation
- No whitelist enforcement
CUserVerificationData (src/primitives/o_transactions.h):
-
user_id: Unique identifier from identity provider -
identity_provider: Provider identifier (string) -
country_code: ISO 3166-1 alpha-3 country code -
birth_currency: O currency code (e.g., "OUSD", "OEUR") - IMMUTABLE -
verification_data: JSON proof from provider -
provider_sig: Identity provider's signature -
user_sig: User's signature (proves ownership ofo_pubkey) -
o_pubkey: O Blockchain public key to link
-
Structure Validation (
CUserVerificationData::IsValid())- Checks required fields are present
- Validates country code format (3 letters)
- Validates birth currency format (starts with "O", 4-5 chars)
- Checks signatures exist
-
Provider Signature Validation (
ValidateProviderSignature())β οΈ INCOMPLETE: Only checks signature size (>= 64 bytes)- TODO comments indicate need for actual cryptographic verification
- Should verify against provider's public key
-
User Signature Validation (
ValidateUserSignature())β οΈ INCOMPLETE: Only checks signature size (>= 64 bytes)- TODO: Verify ECDSA signature of
data.GetHash()byo_pubkey
-
Database Storage (
ProcessUserVerification())- Creates unique key:
provider:user_id - Stores in
g_brightid_db(named for BrightID but used generically) - Uses
BrightIDUserstructure (should be renamed toVerifiedUser)
- Creates unique key:
-
Incomplete Signature Validation
-
Location:
src/consensus/o_tx_validation.cpp:309-352 - Problem: Provider and user signatures are not cryptographically verified
- Impact: Security vulnerability - invalid signatures can pass validation
- Fix: Implement proper ECDSA signature verification
-
Location:
-
No Provider Whitelist
-
Location:
src/consensus/o_tx_validation.cpp:335-337 - Problem: Any provider string with a signature is accepted
- Impact: Malicious or untrusted providers can be used
- Fix: Implement provider registry/whitelist
-
Location:
-
Missing Provider Public Key Management
- Problem: No mechanism to store/retrieve provider public keys
- Impact: Cannot verify provider signatures even if verification code exists
- Fix: Create provider registry with public keys
-
Misnamed Database/Structures
- Location: Throughout codebase
-
Problem:
g_brightid_dbandBrightIDUserare generic but named for BrightID - Impact: Confusing for developers, suggests BrightID-only
-
Fix: Rename to
g_identity_dbandVerifiedUser
-
Generic Provider Support Not Documented
- Problem: Code supports generic providers but documentation focuses on BrightID
- Impact: Developers may not realize extensibility
- Fix: Add comprehensive documentation
-
Inconsistent Provider-Specific Logic
- Problem: BrightID has dedicated integration, others don't
- Impact: Unequal support for different providers
- Fix: Create provider plugin/interface system
-
TODOs Scattered Throughout Code
- Multiple TODO comments for incomplete implementations
- Should be tracked as issues/tickets
-
Hardcoded Provider Checks
- Provider detection uses string comparisons
- Could use enum/registry for better type safety
-
src/primitives/o_transactions.h:CUserVerificationDatastructure definition -
src/primitives/o_transactions.cpp: Validation logic for data structure -
src/consensus/o_tx_validation.cpp:-
ProcessUserVerification(): Main processing logic -
ValidateProviderSignature(): Provider signature validation (incomplete) -
ValidateUserSignature(): User signature validation (incomplete)
-
-
src/consensus/brightid_integration.h/cpp: BrightID-specific API integration -
src/consensus/o_brightid_db.h/cpp: Database for storing verified users
-
src/consensus/user_consensus.h/cpp: Alternative user verification system (seems separate, uses endorsements)
-
Implement Signature Verification
// Pseudocode bool ValidateProviderSignature(const CUserVerificationData& data) { // Get provider's public key from registry auto provider_key = GetProviderPublicKey(data.identity_provider); if (!provider_key) return false; // Verify signature uint256 hash = data.GetHash(); return VerifyECDSA(hash, data.provider_sig, provider_key); }
-
Implement User Signature Verification
bool ValidateUserSignature(const CUserVerificationData& data) { uint256 hash = data.GetHash(); return data.o_pubkey.Verify(hash, data.user_sig); }
-
Create Provider Registry
- Store approved providers with their public keys
- Support on-chain provider registration (future)
- Maintain off-chain whitelist for now
-
Rename Generic Structures
-
g_brightid_dbβg_identity_db -
BrightIDUserβVerifiedUser - Update all references
-
-
Create Provider Interface
class IIdentityProvider { public: virtual bool ValidateSignature(const CUserVerificationData& data) = 0; virtual CPubKey GetPublicKey() = 0; virtual bool IsProviderSupported() = 0; };
-
Implement Provider Plugins
- BrightIDProvider, KYCProvider, WorldCoinProvider, etc.
- Registry maps provider string to plugin instance
-
Document Provider Integration
- How to add new providers
- Provider requirements
- Signature format specifications
-
Add Comprehensive Tests
- Unit tests for signature validation
- Integration tests for each provider
- Security tests for invalid inputs
For a provider to be integrated, it must:
-
Provide Cryptographic Proof
- Signed verification data
- Verifiable signature using standard crypto (ECDSA/secp256k1)
-
Unique User Identification
- Each user has unique ID within provider
- ID cannot be reused (prevents duplicate registrations)
-
User Consent
- User must sign verification with their O Blockchain key
- Links provider identity to blockchain identity
-
Country & Currency Information
- Must provide country code (ISO 3166-1 alpha-3)
- Must specify birth currency (OUSD, OEUR, etc.)
-
Expiration Support (optional)
- Can specify verification expiration
- Supports re-verification workflow
The codebase contains two separate identity verification systems:
-
Structure:
CUserVerificationData -
Storage:
g_brightid_db(misnamed, stores all providers) - Providers: BrightID, KYC, WorldCoin, Idena, etc.
- Verification: External provider signs verification
- Speed: Fast (instant verification if provider approves)
-
Structure:
OfficialUser(user_consensus.h) - Storage: Unknown (seems unimplemented or separate)
- Verification: Peer-to-peer endorsements from verified users
-
Requirements:
- Government ID hash for uniqueness
- 5+ endorsements from different countries
- Geographic diversity requirement
- Speed: Slow (requires multiple endorsements)
- Decentralization: More decentralized, no external dependency
Question: Are both systems active? Should they be unified or remain separate?
-
Provider Approval Process
- Who approves new providers?
- On-chain governance vs. off-chain whitelist?
- Criteria for provider approval?
-
Signature Format Standardization
- All providers use same format? (ECDSA/secp256k1)
- Or provider-specific formats?
-
Provider-Specific Features
- Some providers may need custom validation logic
- How to handle provider-specific fields in
verification_dataJSON?
-
Migration Path
- How to migrate existing BrightID users to generic system?
- Backward compatibility considerations?
-
Dual System Architecture
- Why two separate identity systems?
- Should
OfficialUserendorsement system be integrated? - Can users use both? (e.g., BrightID + endorsements for higher trust)
- Which system is actually being used in production?
- β Review current implementation (this document)
- β³ Implement signature verification
- β³ Create provider registry
- β³ Rename generic structures
- β³ Add comprehensive tests
- β³ Document provider integration process
Β© O International
A Nonprofit Association Focused on the Creation of a Water Price-Based Stable Coin
Association de Loi 1901 β France NumΓ©ro de Siret (French SIREN): 924 014 467 00014