hopenssl (empty) → 1.0
raw patch · 7 files changed
+353/−0 lines, 7 filesdep +basedep +mtlsetup-changed
Dependencies added: base, mtl
Files
- LICENSE +26/−0
- OpenSSL/Digest.hs +235/−0
- README +42/−0
- Setup.lhs +8/−0
- hopenssl.cabal +18/−0
- package.conf.in +20/−0
- prologue.txt +4/−0
+ LICENSE view
@@ -0,0 +1,26 @@+Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.++ * The names of its contributors may not be used to endorse or promote+ products derived from this software without specific prior written+ permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ OpenSSL/Digest.hs view
@@ -0,0 +1,235 @@+{-# INCLUDE <openssl/evp.h> #-}+{-# LANGUAGE ForeignFunctionInterface, GeneralizedNewtypeDeriving, DeriveDataTypeable #-}++{- |+ Module : OpenSSL.Digest+ Copyright : (c) 2008 by Peter Simons+ License : BSD3++ Maintainer : simons@cryp.to+ Stability : provisional+ Portability : portable++ This module proivdes a high-level API to the message+ digest algorithms found in OpenSSL's @crypto@ library.+ Link with @-lcrypto@ when using this module.++ Here is a short example program which runs all available+ digests on a string:++ > example :: (Enum a) => [a] -> IO [String]+ > example input = mapM hash [minBound .. maxBound]+ > where+ > hash f = fmap (fmt f) (digest f (toWord input))+ > fmt f = shows f . (": \t"++) . (>>=toHex)+ > toWord = map (toEnum . fromEnum)++ And when called, the function prints:++ > *Digest> example "open sesame" >>= putStr . unlines+ > Null:+ > MD2: a22a0b245bdddb00b5293ad590297b25+ > MD5: 54ef36ec71201fdf9d1423fd26f97f6b+ > SHA: 2ccefef64c76ac0d42ca1657457977675890c42f+ > SHA1: 5bcaff7f22ff533ca099b3408ead876c0ebba9a7+ > DSS: 5bcaff7f22ff533ca099b3408ead876c0ebba9a7+ > DSS1: 5bcaff7f22ff533ca099b3408ead876c0ebba9a7+ > MDC2: 112db2200ce1e9db3c2d132aea4ef7d0+ > RIPEMD160: bdb2bba6ec93bd566dc1181cadbc92176aa78382+-}++module OpenSSL.Digest where++import Control.Exception ( bracket )+import Foreign+import Foreign.C+import Control.Monad.State+import Numeric ( showHex )+import Data.Typeable++-- * High-level API++-- |The message digest algorithms we support.++data MessageDigest+ = Null -- ^ 0 bit+ | MD2 -- ^ 128 bit+ | MD5 -- ^ 128 bit+ | SHA -- ^ 160 bit+ | SHA1 -- ^ 160 bit+ | DSS -- ^ 160 bit (SHA1)+ | DSS1 -- ^ 160 bit (SHA1)+ | MDC2 -- ^ 128 bit+ | RIPEMD160 -- ^ 160 bit+ deriving (Show, Eq, Enum, Bounded)++-- |A convenience wrapper which computes the given digest+-- over a list of 'Word8'. Unlike the monadic interface,+-- this function does not allow the computation to be+-- restarted.++digest :: MessageDigest -> [Word8] -> IO [Word8]+digest mdType xs =+ mkDigest mdType $ evalStateT (update xs >> final)++-- |A monadic interface to the digest computation.++type Digest a = StateT DigestState IO a++-- |The internal EVP context.++newtype DigestState = DST (Ptr OpaqueContext)+ deriving (Typeable)++-- |Run an 'IO' computation with an initialized+-- 'DigestState'. All resources will be freed when the+-- computation returns.++mkDigest :: MessageDigest -> (DigestState -> IO a) -> IO a+mkDigest mdType f =+ bracket ctxCreate ctxDestroy $ \ctx -> do+ when (ctx == nullPtr) (fail "Digest.mkDigest: ctxCreate failed")+ md <- toMDEngine mdType+ when (md == nullPtr) (fail ("Digest.mkDigest: can't access "++show mdType))+ rc <- digestInit ctx md+ when (rc == 0) (fail ("Digest.mkDigest: can't initialize "++show mdType))+ f (DST ctx)++-- |Update the internal state with a block of data. This+-- function is just a wrapper for 'update'', which creates+-- an array in memory using 'withArray'.++update :: [Word8] -> Digest ()+update xs = do+ st <- get+ liftIO $+ withArray xs $ \p ->+ evalStateT (update' (p, length xs)) st++-- |Update the internal state with a block of data from+-- memory. This is the /faster/ version of 'update'.++update' :: (Ptr Word8, Int) -> Digest ()+update' (p,n) = do+ DST ctx <- get+ rc <- liftIO $ digestUpdate ctx p (toEnum (fromEnum n))+ when (rc == 0) (fail "Digest.update failed")++-- |Wrap up the computation, add padding, do whatever has to+-- be done, and return the final hash. The length of the+-- result depends on the chosen 'MessageDigest'. Do not call+-- more than once!++final :: Digest [Word8]+final = do+ DST ctx <- get+ liftIO $+ allocaArray maxMDSize $ \p ->+ allocaArray (sizeOf (undefined :: CUInt)) $ \i -> do+ rc <- digestFinal ctx p i+ when (rc == 0) (fail "Digest.Final failed")+ i' <- peek i+ peekArray (fromEnum i') p++-- * Low-level API++-- |The EVP context used by OpenSSL is opaque for us; we+-- only access it through a 'Ptr'.++data OpaqueContext = OpaqueContext+type Context = Ptr OpaqueContext++-- |The message digest engines are opaque for us as well.++data OpaqueMDEngine = OpaqueMDEngine+type MDEngine = Ptr OpaqueMDEngine++-- |Maximum size of all message digests supported by+-- OpenSSL. Allocate a buffer of this size for 'digestFinal'+-- if you want to stay generic.++maxMDSize :: Int+maxMDSize = 36++-- |Create an EVP context. May be 'nullPtr'.++foreign import ccall unsafe "EVP_MD_CTX_create" ctxCreate ::+ IO Context++-- |Initialize an EVP context.++foreign import ccall unsafe "EVP_MD_CTX_init" ctxInit ::+ Context -> IO ()++-- |Destroy an EVP context and free the allocated resources.++foreign import ccall unsafe "EVP_MD_CTX_destroy" ctxDestroy ::+ Context -> IO ()++-- |Set the message digest engine for 'digestUpdate' calls.+-- Returns @\/=0@ in case of an error.++foreign import ccall unsafe "EVP_DigestInit" digestInit ::+ Context -> MDEngine -> IO CInt++-- |Update the internal context with a block of input.+-- Returns @\/=0@ in case of an error.++foreign import ccall unsafe "EVP_DigestUpdate" digestUpdate ::+ Context -> Ptr Word8 -> CUInt -> IO CInt++-- |Wrap up the digest computation and return the final+-- digest. Do not call repeatedly on the same context!+-- Returns @\/=0@ in case of an error. The pointer to the+-- unsigned integer may be 'nullPtr'. If it is not,+-- 'digestFinal' will store the length of the computed+-- digest there.++foreign import ccall unsafe "EVP_DigestFinal" digestFinal ::+ Context -> Ptr Word8 -> Ptr CUInt -> IO CInt++-- ** Message Digest Engines++foreign import ccall unsafe "EVP_md_null" mdNull :: IO MDEngine+foreign import ccall unsafe "EVP_md2" mdMD2 :: IO MDEngine+foreign import ccall unsafe "EVP_md5" mdMD5 :: IO MDEngine+foreign import ccall unsafe "EVP_sha" mdSHA :: IO MDEngine+foreign import ccall unsafe "EVP_sha1" mdSHA1 :: IO MDEngine+foreign import ccall unsafe "EVP_dss" mdDSS :: IO MDEngine+foreign import ccall unsafe "EVP_dss1" mdDSS1 :: IO MDEngine+foreign import ccall unsafe "EVP_mdc2" mdMDC2 :: IO MDEngine+foreign import ccall unsafe "EVP_ripemd160" mdRIPEMD160 :: IO MDEngine++-- |Map a 'MessageDigest' type into the the corresponding+-- 'MDEngine'.++toMDEngine :: MessageDigest -> IO MDEngine+toMDEngine Null = mdNull+toMDEngine MD2 = mdMD2+toMDEngine MD5 = mdMD5+toMDEngine SHA = mdSHA+toMDEngine SHA1 = mdSHA1+toMDEngine DSS = mdDSS+toMDEngine DSS1 = mdDSS1+toMDEngine MDC2 = mdMDC2+toMDEngine RIPEMD160 = mdRIPEMD160++-- * Helper Functions++-- |Neat helper to print digests with:+-- @+-- \\ws :: [Word8] -> ws >>= toHex+-- @++toHex :: Word8 -> String+toHex w = case showHex w "" of+ w1:w2:[] -> w1:w2:[]+ w2:[] -> '0':w2:[]+ _ -> error "showHex returned []"+++-- ----- Configure Emacs -----+--+-- Local Variables: ***+-- haskell-program-name: "ghci -ignore-package hopenssl -Wall -lcrypto" ***+-- End: ***
+ README view
@@ -0,0 +1,42 @@+hOpenSSL+========++:Latest Release: hopenssl-1.0.tar.gz_+:Darcs: darcs_ get --partial http://cryp.to/hopenssl/++Synopsis+--------++ This library will some day provide nice Haskell bindings+ to OpenSSL_. Until then, it provides nice Haskell bindings+ to the message digest algorithms found in OpenSSL's+ ``crypto`` library. Currently supported are: MD2, MD5,+ SHA, SHA1, DSS, DSS1, MDC2, and RIPEMD160.++Documentation+-------------++ `Reference Documentation`_+ Haddock-generated reference of all exported+ functions.++Copyleft+--------++ Copyright (c) 2008 Peter Simons <simons@cryp.to>. All rights+ reserved. This software is released under `BSD-style license+ <LICENSE>`_.++-----------------------------------------------------------------++`[Homepage] <http://cryp.to/>`_++.. _Haskell: http://haskell.org/++.. _OpenSSL: http://www.openssl.org/++.. _darcs: http://abridgegame.org/darcs/++.. _hopenssl-1.0.tar.gz: http://cryp.to/hopenssl/hopenssl-1.0.tar.gz++.. _Reference Documentation: docs/index.html
+ Setup.lhs view
@@ -0,0 +1,8 @@+#!/usr/bin/env runhaskell++> module Main (main) where+>+> import Distribution.Simple+>+> main :: IO ()+> main = defaultMain
+ hopenssl.cabal view
@@ -0,0 +1,18 @@+Name: hopenssl+Version: 1.0+Author: Peter Simons <simons@cryp.to>+Synopsis: FFI bindings to OpenSSL's EVP digest interface+Description: FFI bindings to OpenSSL's EVP digest interface+Category: Cryptography+License: BSD3+License-file: LICENSE+Maintainer: Peter Simons <simons@cryp.to>+Homepage: http://cryp.to/hopenssl/+Build-Depends: base, mtl+Extra-Libraries: crypto+Includes: "<openssl/evp.h>"+Extensions: ForeignFunctionInterface+Build-Type: Simple+Exposed-Modules: OpenSSL.Digest+Data-files: README, prologue.txt+Ghc-Options: -Wall
+ package.conf.in view
@@ -0,0 +1,20 @@+name: PACKAGE+version: VERSION+license: GPL+maintainer: simons@cryp.to+exposed: True++exposed-modules:+ OpenSSL.Digest++hidden-modules:++import-dirs: IMPORT_DIR+library-dirs: LIB_DIR+hs-libraries: "HShopenssl"+depends: base, mtl+extra-libs: "crypto"+includes: "<openssl/evp.h>"++haddock-interfaces: HADDOCK_IFACE+haddock-html: HTML_DIR
+ prologue.txt view
@@ -0,0 +1,4 @@+Foreign-Function bindings to the OpenSSL library+<http://www.openssl.org/>. Currently provides access to the+messages digests MD2, MD5, SHA, SHA1, DSS, DSS1, MDC2, and+RIPEMD160.