Skip to content
This repository has been archived by the owner on Jan 18, 2020. It is now read-only.

Commit

Permalink
Deprecate many functions that take or return String containing some b…
Browse files Browse the repository at this point in the history
…inary data.
  • Loading branch information
depressed-pho committed Jul 13, 2014
1 parent 67846d5 commit 61fd9ef
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 103 deletions.
54 changes: 50 additions & 4 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,11 +1,57 @@
2014-07-13 PHO <[email protected]>

* OpenSSL/EVP/Cipher.hsc: Expose cipherInit, Patch by rons.
* OpenSSL/EVP/Base64.hsc (encodeBase64, decodeBase64): Mark as
deprecated.

* HsOpenSSL.cabal (Exposed-Modules): Expose OpenSSL.EVP.Internal,
Patch by rnos.
* OpenSSL/EVP/Cipher.hsc (cipherInit): Removed. Use
OpenSSL.EVP.Internal.cipherInitBS instead. This is a
backward-incompatible change.

* HsOpenSSL.cabal (Version): Bump version to 0.10.5
* OpenSSL/EVP/Cipher.hsc (cipher): Mark as deprecated.

* OpenSSL/EVP/Digest.hsc (digest): Mark as deprecated.

* OpenSSL/EVP/Digest.hsc (digestBS): Changed the return type from
String to strict ByteString. This is a backward-incompatible
change.

* OpenSSL/EVP/Digest.hsc (digestBS'): Removed. Use digestBS
instead. This is a backward-incompatible change.

* OpenSSL/EVP/Digest.hsc (digestLBS): Change the return type from
String to strict ByteString. This is a backward-incompatible
change.

* OpenSSL/EVP/Open.hsc (open): Mark as deprecated.

* OpenSSL/EVP/Open.hsc (openBS, openLBS): Take key and IV as a
strict ByteString intead of String. This is a
backward-incompatible change.

* OpenSSL/EVP/Seal.hsc (seal): Mark as deprecated.

* OpenSSL/EVP/Seal.hsc (sealBS, sealLBS): Return key and IV as a
strict ByteString intead of String. This is a
backward-incompatible change.

* OpenSSL/EVP/Sign.hsc (sign): Mark as deprecated.

* OpenSSL/EVP/Verify.hsc (verify): Mark as deprecated.

* OpenSSL/EVP/Verify.hsc (verifyBS, verifyLBS): Take signature as
a strict ByteString instead of String. This is a
backward-incompatible change.

* HsOpenSSL.cabal (Version): Bump version to 0.11

2014-07-13 PHO <[email protected]>

* OpenSSL/EVP/Cipher.hsc: Expose cipherInit, Patch by rons.

* HsOpenSSL.cabal (Exposed-Modules): Expose OpenSSL.EVP.Internal,
Patch by rnos.

* HsOpenSSL.cabal (Version): Bump version to 0.10.5

2013-12-25 PHO <[email protected]>

Expand Down
2 changes: 1 addition & 1 deletion HsOpenSSL.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Description:
<http://hackage.haskell.org/package/tls>, which is a pure Haskell
implementation of SSL.
.
Version: 0.10.5
Version: 0.11
License: PublicDomain
License-File: COPYING
Author: Adam Langley, Mikhail Vorozhtsov, PHO, Taru Karttunen
Expand Down
2 changes: 2 additions & 0 deletions OpenSSL/EVP/Base64.hsc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ encodeBlock inBS
-- Base64. The string doesn't have to be finite. Note that the string
-- must not contain any letters which aren't in the range of U+0000 -
-- U+00FF.
{-# DEPRECATED encodeBase64 "Use encodeBase64BS or encodeBase64LBS instead." #-}
encodeBase64 :: String -> String
encodeBase64 = L8.unpack . encodeBase64LBS . L8.pack

Expand Down Expand Up @@ -117,6 +118,7 @@ decodeBlock inBS

-- |@'decodeBase64' str@ lazilly decodes a stream of data from
-- Base64. The string doesn't have to be finite.
{-# DEPRECATED decodeBase64 "Use decodeBase64BS or decodeBase64LBS instead." #-}
decodeBase64 :: String -> String
decodeBase64 = L8.unpack . decodeBase64LBS . L8.pack

Expand Down
61 changes: 18 additions & 43 deletions OpenSSL/EVP/Cipher.hsc
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,18 @@ module OpenSSL.EVP.Cipher

, CryptoMode(..)

, cipherInit
, cipher
, cipherBS
, cipherLBS
, cipherStrictLBS
)
where
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import qualified Data.ByteString.Char8 as B8
import qualified Data.ByteString.Lazy.Char8 as L8
import Data.Monoid
import Foreign
import Foreign.C
import OpenSSL.Objects
import OpenSSL.Utils
import OpenSSL.EVP.Internal

foreign import ccall unsafe "EVP_get_cipherbyname"
Expand All @@ -49,42 +47,18 @@ getCipherNames = getObjNames CipherMethodType True

{- encrypt/decrypt ----------------------------------------------------------- -}

-- |@CryptoMode@ represents instruction to 'cipher' and such like.
data CryptoMode = Encrypt | Decrypt

cryptoModeToInt :: CryptoMode -> CInt
cryptoModeToInt Encrypt = 1
cryptoModeToInt Decrypt = 0

foreign import ccall unsafe "EVP_CipherInit"
_CipherInit :: Ptr EVP_CIPHER_CTX -> Ptr EVP_CIPHER -> CString -> CString -> CInt -> IO CInt

cipherInit :: Cipher -> String -> String -> CryptoMode -> IO CipherCtx
cipherInit (Cipher c) key iv mode
= do ctx <- newCipherCtx
withCipherCtxPtr ctx $ \ ctxPtr ->
withCString key $ \ keyPtr ->
withCString iv $ \ ivPtr ->
_CipherInit ctxPtr c keyPtr ivPtr (cryptoModeToInt mode)
>>= failIf_ (/= 1)
return ctx

-- | Encrypt a lazy bytestring in a strict manner. Does not leak the keys.
cipherStrictLBS :: Cipher -- ^ Cipher
-> B8.ByteString -- ^ Key
-> B8.ByteString -- ^ IV
-> CryptoMode -- ^ Encrypt\/Decrypt
-> L8.ByteString -- ^ Input
-> IO L8.ByteString
cipherStrictLBS (Cipher c) key iv mode input =
withNewCipherCtxPtr $ \cptr ->
unsafeUseAsCStringLen key $ \(keyp,_) ->
unsafeUseAsCStringLen iv $ \(ivp, _) -> do
failIf_ (/= 1) =<< _CipherInit cptr c keyp ivp (cryptoModeToInt mode)
cc <- fmap CipherCtx (newForeignPtr_ cptr)
rr <- cipherUpdateBS cc `mapM` L8.toChunks input
rf <- cipherFinalBS cc
return $ L8.fromChunks (rr++[rf])
cipherStrictLBS c key iv mode input =
do ctx <- cipherInitBS c key iv mode
xs <- cipherUpdateBS ctx `mapM` L8.toChunks input
x <- cipherFinalBS ctx
return $ L8.fromChunks (xs `mappend` [x])

-- |@'cipher'@ lazilly encrypts or decrypts a stream of data. The
-- input string doesn't necessarily have to be finite.
Expand All @@ -97,29 +71,30 @@ cipher :: Cipher -- ^ algorithm to use
-- which aren't in the range of U+0000 -
-- U+00FF.
-> IO String -- ^ the result string
{-# DEPRECATED cipher "Use cipherBS, cipherLBS or cipherStrictLBS." #-}
cipher c key iv mode input
= fmap L8.unpack $ cipherLBS c key iv mode $ L8.pack input
= fmap L8.unpack $ cipherLBS c (B8.pack key) (B8.pack iv) mode (L8.pack input)

-- |@'cipherBS'@ strictly encrypts or decrypts a chunk of data.
cipherBS :: Cipher -- ^ algorithm to use
-> String -- ^ symmetric key
-> String -- ^ IV
-> CryptoMode -- ^ operation
cipherBS :: Cipher -- ^ algorithm to use
-> B8.ByteString -- ^ symmetric key
-> B8.ByteString -- ^ IV
-> CryptoMode -- ^ operation
-> B8.ByteString -- ^ input string to encrypt\/decrypt
-> IO B8.ByteString -- ^ the result string
cipherBS c key iv mode input
= do ctx <- cipherInit c key iv mode
= do ctx <- cipherInitBS c key iv mode
cipherStrictly ctx input

-- |@'cipherLBS'@ lazilly encrypts or decrypts a stream of data. The
-- input string doesn't necessarily have to be finite.
cipherLBS :: Cipher -- ^ algorithm to use
-> String -- ^ symmetric key
-> String -- ^ IV
-> CryptoMode -- ^ operation
cipherLBS :: Cipher -- ^ algorithm to use
-> B8.ByteString -- ^ symmetric key
-> B8.ByteString -- ^ IV
-> CryptoMode -- ^ operation
-> L8.ByteString -- ^ input string to encrypt\/decrypt
-> IO L8.ByteString -- ^ the result string
cipherLBS c key iv mode input
= do ctx <- cipherInit c key iv mode
= do ctx <- cipherInitBS c key iv mode
cipherLazily ctx input

15 changes: 5 additions & 10 deletions OpenSSL/EVP/Digest.hsc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ module OpenSSL.EVP.Digest

, digest
, digestBS
, digestBS'
, digestLBS

, hmacBS
Expand Down Expand Up @@ -56,23 +55,19 @@ getDigestNames = getObjNames MDMethodType True
-- not contain any letters which aren't in the range of U+0000 -
-- U+00FF.
digest :: Digest -> String -> String
{-# DEPRECATED digest "Use digestBS or digestLBS instead." #-}
digest md input
= digestLBS md $ L8.pack input
= B8.unpack $ digestLBS md $ L8.pack input

-- |@'digestBS'@ digests a chunk of data.
digestBS :: Digest -> B8.ByteString -> String
digestBS :: Digest -> B8.ByteString -> B8.ByteString
digestBS md input
= unsafePerformIO $ digestStrictly md input >>= digestFinal

-- |Same as 'digestBS' but returns 'B8.ByteString' instead.
digestBS' :: Digest -> B8.ByteString -> B8.ByteString
digestBS' md input
= unsafePerformIO $ digestStrictly md input >>= digestFinalBS

-- |@'digestLBS'@ digests a stream of data.
digestLBS :: Digest -> L8.ByteString -> String
digestLBS :: Digest -> L8.ByteString -> B8.ByteString
digestLBS md input
= unsafePerformIO $ digestLazily md input >>= digestFinal
= unsafePerformIO $ digestLazily md input >>= digestFinalBS

{- HMAC ---------------------------------------------------------------------- -}

Expand Down
33 changes: 32 additions & 1 deletion OpenSSL/EVP/Internal.hsc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ module OpenSSL.EVP.Internal (
withCipherCtxPtr,
withNewCipherCtxPtr,

CryptoMode(..),
cipherInitBS,
cipherUpdateBS,
cipherFinalBS,
cipherStrictly,
Expand Down Expand Up @@ -57,7 +59,7 @@ import Foreign.C.Types (CInt(..), CUInt(..), CSize(..))
import Foreign.C.Types (CInt, CUInt, CSize)
#endif
import Foreign.Ptr (Ptr, castPtr, FunPtr)
import Foreign.C.String (peekCStringLen)
import Foreign.C.String (CString, peekCStringLen)
import Foreign.ForeignPtr
#if MIN_VERSION_base(4,4,0)
import Foreign.ForeignPtr.Unsafe as Unsafe
Expand Down Expand Up @@ -121,6 +123,35 @@ withNewCipherCtxPtr f =

{- encrypt/decrypt ----------------------------------------------------------- -}

-- |@CryptoMode@ represents instruction to 'cipher' and such like.
data CryptoMode = Encrypt | Decrypt

fromCryptoMode :: Num a => CryptoMode -> a
fromCryptoMode Encrypt = 1
fromCryptoMode Decrypt = 0

foreign import ccall unsafe "EVP_CipherInit"
_CipherInit :: Ptr EVP_CIPHER_CTX
-> Ptr EVP_CIPHER
-> CString
-> CString
-> CInt
-> IO CInt

cipherInitBS :: Cipher
-> B8.ByteString -- ^ key
-> B8.ByteString -- ^ IV
-> CryptoMode
-> IO CipherCtx
cipherInitBS (Cipher c) key iv mode
= do ctx <- newCipherCtx
withCipherCtxPtr ctx $ \ ctxPtr ->
B8.unsafeUseAsCString key $ \ keyPtr ->
B8.unsafeUseAsCString iv $ \ ivPtr ->
_CipherInit ctxPtr c keyPtr ivPtr (fromCryptoMode mode)
>>= failIf_ (/= 1)
return ctx

foreign import ccall unsafe "EVP_CipherUpdate"
_CipherUpdate :: Ptr EVP_CIPHER_CTX -> Ptr CChar -> Ptr CInt
-> Ptr CChar -> CInt -> IO CInt
Expand Down
31 changes: 19 additions & 12 deletions OpenSSL/EVP/Open.hsc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module OpenSSL.EVP.Open

import qualified Data.ByteString.Char8 as B8
import qualified Data.ByteString.Lazy.Char8 as L8
import qualified Data.ByteString.Unsafe as B8
import Foreign hiding (unsafePerformIO)
import System.IO.Unsafe (unsafePerformIO)
import Foreign.C
Expand All @@ -31,12 +32,17 @@ foreign import ccall unsafe "EVP_OpenInit"
-> IO CInt


openInit :: KeyPair key => Cipher -> String -> String -> key -> IO CipherCtx
openInit :: KeyPair key =>
Cipher
-> B8.ByteString
-> B8.ByteString
-> key
-> IO CipherCtx
openInit cipher encKey iv pkey
= do ctx <- newCipherCtx
withCipherCtxPtr ctx $ \ ctxPtr ->
withCStringLen encKey $ \ (encKeyPtr, encKeyLen) ->
withCString iv $ \ ivPtr ->
B8.unsafeUseAsCStringLen encKey $ \ (encKeyPtr, encKeyLen) ->
B8.unsafeUseAsCString iv $ \ ivPtr ->
withPKeyPtr' pkey $ \ pkeyPtr ->
_OpenInit ctxPtr cipher encKeyPtr (fromIntegral encKeyLen) ivPtr pkeyPtr
>>= failIf_ (== 0)
Expand All @@ -51,15 +57,16 @@ open :: KeyPair key =>
-> key -- ^ private key to decrypt the symmetric key
-> String -- ^ input string to decrypt
-> String -- ^ decrypted string
{-# DEPRECATED open "Use openBS or openLBS instead." #-}
open cipher encKey iv pkey input
= L8.unpack $ openLBS cipher encKey iv pkey $ L8.pack input
= L8.unpack $ openLBS cipher (B8.pack encKey) (B8.pack iv) pkey (L8.pack input)

-- |@'openBS'@ decrypts a chunk of data.
openBS :: KeyPair key =>
Cipher -- ^ symmetric cipher algorithm to use
-> String -- ^ encrypted symmetric key to decrypt the input string
-> String -- ^ IV
-> key -- ^ private key to decrypt the symmetric key
Cipher -- ^ symmetric cipher algorithm to use
-> B8.ByteString -- ^ encrypted symmetric key to decrypt the input string
-> B8.ByteString -- ^ IV
-> key -- ^ private key to decrypt the symmetric key
-> B8.ByteString -- ^ input string to decrypt
-> B8.ByteString -- ^ decrypted string
openBS cipher encKey iv pkey input
Expand All @@ -70,10 +77,10 @@ openBS cipher encKey iv pkey input
-- |@'openLBS'@ lazilly decrypts a stream of data. The input string
-- doesn't necessarily have to be finite.
openLBS :: KeyPair key =>
Cipher -- ^ symmetric cipher algorithm to use
-> String -- ^ encrypted symmetric key to decrypt the input string
-> String -- ^ IV
-> key -- ^ private key to decrypt the symmetric key
Cipher -- ^ symmetric cipher algorithm to use
-> B8.ByteString -- ^ encrypted symmetric key to decrypt the input string
-> B8.ByteString -- ^ IV
-> key -- ^ private key to decrypt the symmetric key
-> L8.ByteString -- ^ input string to decrypt
-> L8.ByteString -- ^ decrypted string
openLBS cipher encKey iv pkey input
Expand Down
Loading

0 comments on commit 61fd9ef

Please sign in to comment.