password 3.1.0.2 → 3.1.1.0
raw patch · 7 files changed
+64/−65 lines, 7 filesdep +ramdep ~crypton
Dependencies added: ram
Dependency ranges changed: crypton
Files
- ChangeLog.md +11/−1
- password.cabal +25/−11
- src/Data/Password/Argon2.hs +6/−7
- src/Data/Password/Bcrypt.hs +7/−11
- src/Data/Password/Internal.hs +1/−14
- src/Data/Password/PBKDF2.hs +8/−14
- src/Data/Password/Scrypt.hs +6/−7
ChangeLog.md view
@@ -1,12 +1,22 @@ # Changelog for `password` +## 3.1.1.0++- Support `crypton` dependency to include `^>= 1.1.0`.+ Added the `memory-dep` flag to be able to enforce building with `memory`+ instead of `ram` when constrained to lower versions of `crypton`.+- Removed converting to and from `Bytes`, especially since `ram >= 0.21.0`+ (a dependency of `crypton >= 1.1`) has it as a newtype over `ByteString`.+ Thanks to [@Vlix](https://github.com/Vlix)+ [#91](https://github.com/cdepillabout/password/pull/91)+ ## 3.1.0.2 - Added reference to [password-cli](https://github.com/cdepillabout/password/tree/master/password-cli) package in modules and README. ## 3.1.0.1 -- Redo the conditionals in the `password.cabal` file so that the scrypt+- Redo the conditionals in the `password.cabal` file so that the `scrypt` library is only included as a test dependency on `x86_64`. This generally shouldn't affect users of the `password` library. Thanks to [@sternenseemann](https://github.com/sternenseemann)
password.cabal view
@@ -1,8 +1,8 @@ cabal-version: 1.12 name: password-version: 3.1.0.2-category: Data+version: 3.1.1.0+category: Security synopsis: Hashing and checking of passwords description: A library providing functionality for working with plain-text and hashed passwords@@ -69,6 +69,13 @@ default: False manual: True +flag memory-dep+ description: Compile with [memory] dependency instead of [ram]+ default: False+ -- This should NOT be manual, so that constraint solvers+ -- can figure out which version of 'crypton' is used.+ manual: False+ flag pbkdf2 description: Compile with PBKDF2 support? default: True@@ -81,9 +88,9 @@ custom-setup setup-depends:- base <5- , Cabal <4- , cabal-doctest >=1.0.6 && <1.1+ base < 5+ , Cabal < 4+ , cabal-doctest >= 1.0.6 && < 1.1 source-repository head type: git@@ -113,7 +120,6 @@ base >= 4.9 && < 5 , base64 >= 0.3 && < 1.1 , bytestring >= 0.9 && < 0.13- , memory < 1 , password-types < 2 , template-haskell >= 2.2 && < 3 , text >= 1.2.2 && < 3@@ -121,12 +127,20 @@ -Wall default-language: Haskell2010+ -- 'cryptonite' always means 'memory' if flag(cryptonite) build-depends:- cryptonite >= 0.15.1 && < 0.31+ cryptonite >= 0.15.1 && < 0.31,+ memory < 1 else- build-depends:- crypton >= 0.31 && < 1.1+ if flag(memory-dep)+ build-depends:+ crypton >= 0.31 && < 1.1,+ memory < 1+ else+ build-depends:+ crypton >= 1.1 && < 1.2,+ ram < 1 test-suite doctests type:@@ -138,7 +152,7 @@ ghc-options: -threaded -O2 -rtsopts -with-rtsopts=-N build-depends:- base >=4.9 && <5+ base >= 4.9 && < 5 , base-compat , doctest , QuickCheck@@ -188,7 +202,7 @@ -threaded -O2 -rtsopts -with-rtsopts=-N build-depends:- base >=4.9 && <5+ base >= 4.9 && < 5 , base64 , password-types , bytestring
src/Data/Password/Argon2.hs view
@@ -86,7 +86,7 @@ #if MIN_VERSION_base64(1,0,0) import Data.Base64.Types (extractBase64) #endif-import Data.ByteArray (Bytes, constEq, convert)+import Data.ByteArray (constEq) import Data.ByteString as B (ByteString, length) import Data.ByteString.Base64 (encodeBase64) import Data.Maybe (fromMaybe)@@ -94,6 +94,7 @@ import Data.Semigroup ((<>)) #endif import Data.Text (Text)+import Data.Text.Encoding (encodeUtf8) import qualified Data.Text as T (dropWhileEnd, intercalate, split, splitAt, stripPrefix) import Data.Word (Word32) @@ -102,7 +103,6 @@ from64, readT, showT,- toBytes, unsafePad64, ) import Data.Password.Types (@@ -232,14 +232,13 @@ -- | Only for internal use hashPasswordWithSalt' :: Argon2Params -> Salt Argon2 -> Password -> ByteString hashPasswordWithSalt' Argon2Params{..} (Salt salt) pass =- convert (argon2Hash :: Bytes)- where- argon2Hash = throwCryptoError $+ throwCryptoError $ Argon2.hash options- (toBytes $ unsafeShowPassword pass)- (convert salt :: Bytes)+ (encodeUtf8 $ unsafeShowPassword pass)+ salt $ fromIntegral argon2OutputLength+ where options = Argon2.Options { iterations = argon2TimeCost, memory = argon2MemoryCost,
src/Data/Password/Bcrypt.hs view
@@ -86,8 +86,8 @@ import Control.Monad (guard) import Control.Monad.IO.Class (MonadIO(liftIO)) import Crypto.KDF.BCrypt as Bcrypt (bcrypt, validatePassword)-import Data.ByteArray (Bytes, convert) import qualified Data.Text as T+import Data.Text.Encoding (encodeUtf8, decodeUtf8) import Text.Read (readMaybe) import Data.Password.Types (@@ -97,11 +97,7 @@ , unsafeShowPassword , Salt(..) )-import Data.Password.Internal (- PasswordCheck(..)- , fromBytes- , toBytes- )+import Data.Password.Internal (PasswordCheck(..)) import qualified Data.Password.Internal (newSalt) @@ -169,9 +165,9 @@ hashPasswordWithSalt cost (Salt salt) pass = let hash = Bcrypt.bcrypt cost- (convert salt :: Bytes)- (toBytes $ unsafeShowPassword pass)- in PasswordHash $ fromBytes hash+ salt+ (encodeUtf8 $ unsafeShowPassword pass)+ in PasswordHash $ decodeUtf8 hash -- | Hash a password using the /bcrypt/ algorithm with the given cost. --@@ -214,8 +210,8 @@ checkPassword :: Password -> PasswordHash Bcrypt -> PasswordCheck checkPassword pass (PasswordHash passHash) = if Bcrypt.validatePassword- (toBytes $ unsafeShowPassword pass)- (toBytes passHash)+ (encodeUtf8 $ unsafeShowPassword pass)+ (encodeUtf8 passHash) then PasswordCheckSuccess else PasswordCheckFail
src/Data/Password/Internal.hs view
@@ -14,8 +14,6 @@ PasswordCheck(..) , newSalt -- * Utility- , toBytes- , fromBytes , from64 , unsafePad64 , readT@@ -26,7 +24,6 @@ import Control.Monad.IO.Class (MonadIO (liftIO)) import Crypto.Random (getRandomBytes)-import Data.ByteArray (Bytes, convert) import Data.ByteString (ByteString) #if MIN_VERSION_base64(1,0,0) import Data.ByteString.Base64 (decodeBase64Untyped)@@ -44,7 +41,7 @@ unpack, ) import Data.Password.Types (Salt(..))-import Data.Text.Encoding (decodeUtf8, encodeUtf8)+import Data.Text.Encoding (encodeUtf8) import Text.Read (readMaybe) -- $setup@@ -82,16 +79,6 @@ -- ^ The password check failed. The plain-text password does not match the -- hashed password. deriving (Eq, Read, Show)---- | Converting 'Text' to 'Bytes'-toBytes :: Text -> Bytes-toBytes = convert . encodeUtf8-{-# INLINE toBytes #-}---- | Converting 'Bytes' to 'Text'-fromBytes :: Bytes -> Text-fromBytes = decodeUtf8 . convert-{-# INLINE fromBytes #-} -- | Decodes a base64 'Text' to a regular 'ByteString' (if possible) from64 :: Text -> Maybe ByteString
src/Data/Password/PBKDF2.hs view
@@ -85,13 +85,14 @@ #if MIN_VERSION_base64(1,0,0) import Data.Base64.Types (extractBase64) #endif-import Data.ByteArray (ByteArray, ByteArrayAccess, Bytes, constEq, convert)+import Data.ByteArray (constEq) import Data.ByteString (ByteString) import Data.ByteString.Base64 (encodeBase64) import qualified Data.ByteString.Char8 as C8 (length) import Data.Maybe (fromMaybe) import Data.Text (Text) import qualified Data.Text as T (intercalate, pack, split, stripPrefix)+import Data.Text.Encoding (encodeUtf8) import Data.Word (Word32) import Data.Password.Types (@@ -101,12 +102,7 @@ , unsafeShowPassword , Salt(..) )-import Data.Password.Internal (- PasswordCheck(..)- , from64- , readT- , toBytes- )+import Data.Password.Internal (PasswordCheck(..), from64, readT) import qualified Data.Password.Internal (newSalt) @@ -209,13 +205,12 @@ -- | Only for internal use hashPasswordWithSalt' :: PBKDF2Params -> Salt PBKDF2 -> Password -> ByteString hashPasswordWithSalt' PBKDF2Params{..} (Salt salt) pass =- convert (pbkdf2Hash :: Bytes)- where- pbkdf2Hash = algToFunc+ algToFunc pbkdf2Algorithm params- (toBytes $ unsafeShowPassword pass)- (convert salt :: Bytes)+ (encodeUtf8 $ unsafeShowPassword pass)+ salt+ where params = PBKDF2.Parameters { PBKDF2.iterCounts = fromIntegral pbkdf2Iterations, PBKDF2.outputLength = fromIntegral $ maxOutputLength pbkdf2Algorithm pbkdf2OutputLength@@ -324,8 +319,7 @@ _ -> Nothing -- Which function to use, based on the given algorithm-algToFunc :: (ByteArrayAccess password, ByteArrayAccess salt, ByteArray hash)- => PBKDF2Algorithm -> PBKDF2.Parameters -> password -> salt -> hash+algToFunc :: PBKDF2Algorithm -> PBKDF2.Parameters -> ByteString -> ByteString -> ByteString algToFunc = \case PBKDF2_MD5 -> PBKDF2.generate (PBKDF2.prfHMAC Crypto.MD5) PBKDF2_SHA1 -> PBKDF2.fastPBKDF2_SHA1
src/Data/Password/Scrypt.hs view
@@ -78,12 +78,13 @@ #if MIN_VERSION_base64(1,0,0) import Data.Base64.Types (extractBase64) #endif-import Data.ByteArray (Bytes, constEq, convert)+import Data.ByteArray (constEq) import Data.ByteString (ByteString) import Data.ByteString.Base64 (encodeBase64) import qualified Data.ByteString.Char8 as C8 (length) import Data.Maybe (fromMaybe) import qualified Data.Text as T (intercalate, split)+import Data.Text.Encoding (encodeUtf8) import Data.Word (Word32) import Data.Password.Types (@@ -98,7 +99,6 @@ , from64 , readT , showT- , toBytes ) import qualified Data.Password.Internal (newSalt) @@ -207,12 +207,11 @@ -- | Only for internal use hashPasswordWithSalt' :: ScryptParams -> Salt Scrypt -> Password -> ByteString hashPasswordWithSalt' ScryptParams{..} (Salt salt) pass =- convert (scryptHash :: Bytes)- where- scryptHash = Scrypt.generate+ Scrypt.generate params- (toBytes $ unsafeShowPassword pass)- (convert salt :: Bytes)+ (encodeUtf8 $ unsafeShowPassword pass)+ salt+ where params = Scrypt.Parameters { n = 2 ^ scryptRounds, r = fromIntegral scryptBlockSize,