packages feed

crypton-2.0.0: Crypto/Debug.hs

-- |
-- Module      : Crypto.Debug
-- License     : BSD-style
-- Maintainer  : Kazu Yamamoto <kazu@iij.ad.jp>
-- Stability   : experimental
-- Portability : unknown
--
-- Printing secret key material, on purpose.
--
-- The 'Show' instance of a type that holds a secret does not print it.  That
-- is deliberate: 'Show' is what @print@, a message built with @error@, an
-- exception and a test framework's failure output all reach for, and a
-- private key reaching a log or a bug report that way is an accident nobody
-- asked for.  Those instances render the public part and write @\<secret\>@
-- for the rest.
--
-- This module is how you print one when printing it is what you mean.  What
-- 'debugShow' returns is what the derived 'Show' used to return, so for the
-- types that still have a 'Read' instance
--
-- > read (debugShow k) == k
--
-- and a call site that was serializing a key through @show@ moves by one
-- word.
--
-- Needing 'debugShow' in scope is the record of the intent: nothing here is
-- exported anywhere else, so a search for this module finds every place a key
-- can be revealed.  Do not leave a call to it where production code runs.
module Crypto.Debug (
    DebugShow (..),
    debugShowBytes,
) where

import Data.Bits (shiftR, (.&.))
import qualified Data.ByteArray as BA
import Data.Word (Word8)

-- | Rendering a value with its secret in place.
class DebugShow a where
    -- | Render the value, secret included.
    debugShow :: a -> String

-- | Render a secret that is held as bytes, in hexadecimal.  The secret keys
-- that keep theirs in a @ScrubbedBytes@ never had a 'Show' that printed it,
-- so unlike the rest of this module what comes back is for reading and not
-- for 'Prelude.read'.
debugShowBytes :: BA.ByteArrayAccess ba => String -> ba -> String
debugShowBytes con b = con ++ (' ' : concatMap hex (BA.unpack b))
  where
    hex :: Word8 -> String
    hex w = [digit (w `shiftR` 4), digit (w .&. 0x0f)]
    digit n = "0123456789abcdef" !! fromIntegral n