sd-jwt-0.1.0.0: src/SDJWT/Internal/Types.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
-- | Core data types for SD-JWT (Selective Disclosure for JSON Web Tokens).
--
-- This module defines all the data types used throughout the SD-JWT library,
-- including hash algorithms, disclosures, SD-JWT structures, and error types.
-- These types correspond to the structures defined in RFC 9901.
module SDJWT.Internal.Types
( HashAlgorithm(..)
, Salt(..)
, Digest(..)
, ObjectDisclosure(..)
, ArrayDisclosure(..)
, Disclosure(..)
, EncodedDisclosure(..)
, SDJWTPayload(..)
, KeyBindingInfo(..)
, SDJWT(..)
, SDJWTPresentation(..)
, ProcessedSDJWTPayload(..)
, SDJWTError(..)
) where
import Data.Aeson (Value, Object)
import qualified Data.Aeson.KeyMap as KeyMap
import Data.ByteString (ByteString)
import Data.Map.Strict (Map)
import Data.Text (Text)
import GHC.Generics (Generic)
-- | Hash algorithm identifier for computing disclosure digests.
--
-- All three algorithms (SHA-256, SHA-384, SHA-512) must be supported.
-- SHA-256 is the default when _sd_alg is not specified in the SD-JWT.
data HashAlgorithm
= SHA256 -- ^ SHA-256 (default, required)
| SHA384 -- ^ SHA-384
| SHA512 -- ^ SHA-512
deriving stock (Eq, Show, Read, Generic)
-- | Salt value (cryptographically secure random).
--
-- Salts are used when creating disclosures to prevent brute-force attacks.
-- RFC 9901 recommends 128 bits (16 bytes) of entropy.
newtype Salt = Salt { unSalt :: ByteString }
deriving stock (Eq, Show, Generic)
-- | Digest (base64url-encoded hash).
--
-- A digest is the base64url-encoded hash of a disclosure. Digests replace
-- claim values in the SD-JWT payload to enable selective disclosure.
newtype Digest = Digest { unDigest :: Text }
deriving stock (Eq, Show, Generic)
-- | Disclosure for object properties: [salt, claim_name, claim_value]
data ObjectDisclosure = ObjectDisclosure
{ disclosureSalt :: Salt
, disclosureName :: Text
, disclosureValue :: Value
}
deriving stock (Eq, Show, Generic)
-- | Disclosure for array elements: [salt, claim_value]
data ArrayDisclosure = ArrayDisclosure
{ arraySalt :: Salt
, arrayValue :: Value
}
deriving stock (Eq, Show, Generic)
-- | Unified disclosure type
data Disclosure
= DisclosureObject ObjectDisclosure
| DisclosureArray ArrayDisclosure
deriving stock (Eq, Show, Generic)
-- | Encoded disclosure (base64url string)
newtype EncodedDisclosure = EncodedDisclosure { unEncodedDisclosure :: Text }
deriving stock (Eq, Show, Generic)
-- | Key Binding information from cnf claim
--
-- The public key is stored as a JWK JSON string (Text), which is compatible
-- with 'SDJWT.Internal.JWT.JWKLike'. This allows users to work with JWKs
-- without requiring a direct dependency on the jose library.
newtype KeyBindingInfo = KeyBindingInfo
{ kbPublicKey :: Text -- ^ Holder's public key from cnf claim (JWK JSON string)
}
deriving stock (Eq, Show, Generic)
-- | SD-JWT payload structure
-- Note: This is a simplified representation. The actual payload
-- is a JSON object with _sd arrays and ... objects for arrays.
data SDJWTPayload = SDJWTPayload
{ sdAlg :: Maybe HashAlgorithm -- ^ _sd_alg claim
, payloadValue :: Value -- ^ The actual JSON payload
}
deriving stock (Eq, Show, Generic)
-- | Complete SD-JWT structure (as issued)
data SDJWT = SDJWT
{ issuerSignedJWT :: Text -- ^ The signed JWT (compact serialization)
, disclosures :: [EncodedDisclosure] -- ^ All disclosures
}
deriving stock (Eq, Show, Generic)
-- | SD-JWT presentation (with selected disclosures)
data SDJWTPresentation = SDJWTPresentation
{ presentationJWT :: Text
, selectedDisclosures :: [EncodedDisclosure]
, keyBindingJWT :: Maybe Text -- ^ KB-JWT if present
}
deriving stock (Eq, Show, Generic)
-- | Processed SD-JWT payload (after verification)
data ProcessedSDJWTPayload = ProcessedSDJWTPayload
{ processedClaims :: Object -- ^ Processed claims as a JSON object
, keyBindingInfo :: Maybe KeyBindingInfo -- ^ Key binding information if KB-JWT was present and verified
}
deriving stock (Eq, Show, Generic)
-- | SD-JWT errors
data SDJWTError
= InvalidDisclosureFormat Text
| InvalidDigest Text
| MissingDisclosure Text
| DuplicateDisclosure Text
| InvalidSignature Text
| InvalidKeyBinding Text
| InvalidHashAlgorithm Text
| InvalidClaimName Text
| SaltGenerationError Text
| JSONParseError Text
| SerializationError Text
| VerificationError Text
deriving stock (Eq, Show)