Hello community,

here is the log from the commit of package ghc-HsOpenSSL for openSUSE:Factory 
checked in at 2016-11-10 13:19:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-HsOpenSSL (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-HsOpenSSL.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-HsOpenSSL"

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-HsOpenSSL/ghc-HsOpenSSL.changes      
2016-09-24 15:21:34.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.ghc-HsOpenSSL.new/ghc-HsOpenSSL.changes 
2016-11-10 13:19:20.000000000 +0100
@@ -1,0 +2,15 @@
+Thu Oct 27 15:55:02 UTC 2016 - [email protected]
+
+- Update to version 0.11.3.2 with cabal2obs.
+
+-------------------------------------------------------------------
+Mon Oct 17 15:37:38 UTC 2016 - [email protected]
+
+- Update to version 0.11.3.1 with cabal2obs.
+
+-------------------------------------------------------------------
+Tue Oct 11 08:49:43 UTC 2016 - [email protected]
+
+- Update to version 0.11.2.4 with cabal2obs.
+
+-------------------------------------------------------------------

Old:
----
  1.cabal
  HsOpenSSL-0.11.1.1.tar.gz

New:
----
  HsOpenSSL-0.11.3.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-HsOpenSSL.spec ++++++
--- /var/tmp/diff_new_pack.nqPwgk/_old  2016-11-10 13:19:21.000000000 +0100
+++ /var/tmp/diff_new_pack.nqPwgk/_new  2016-11-10 13:19:21.000000000 +0100
@@ -19,29 +19,20 @@
 %global pkg_name HsOpenSSL
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        0.11.1.1
+Version:        0.11.3.2
 Release:        0
 Summary:        Partial OpenSSL binding for Haskell
 License:        SUSE-Public-Domain
-Group:          System/Libraries
+Group:          Development/Languages/Other
 Url:            https://hackage.haskell.org/package/%{pkg_name}
 Source0:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz
-Source1:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/revision/1.cabal
 BuildRequires:  ghc-Cabal-devel
-# Begin cabal-rpm deps:
 BuildRequires:  ghc-bytestring-devel
 BuildRequires:  ghc-network-devel
-BuildRequires:  ghc-old-locale-devel
 BuildRequires:  ghc-rpm-macros
 BuildRequires:  ghc-time-devel
 BuildRequires:  libopenssl-devel
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
-%if %{with tests}
-BuildRequires:  ghc-HUnit-devel
-BuildRequires:  ghc-test-framework-devel
-BuildRequires:  ghc-test-framework-hunit-devel
-%endif
-# End cabal-rpm deps
 
 %description
 HsOpenSSL is an OpenSSL binding for Haskell. It can generate RSA and DSA keys,
@@ -59,33 +50,24 @@
 Group:          Development/Libraries/Other
 Requires:       %{name} = %{version}-%{release}
 Requires:       ghc-compiler = %{ghc_version}
-# Begin cabal-rpm deps:
 Requires:       libopenssl-devel
 Requires(post): ghc-compiler = %{ghc_version}
 Requires(postun): ghc-compiler = %{ghc_version}
-# End cabal-rpm deps
 
 %description devel
 This package provides the Haskell %{pkg_name} library development files.
 
 %prep
 %setup -q -n %{pkg_name}-%{version}
-cp -p %{SOURCE1} %{pkg_name}.cabal
-
 
 %build
 %ghc_lib_build
 
-
 %install
 %ghc_lib_install
 
-
 %check
-%if %{with tests}
-%{cabal} test
-%endif
-
+%cabal_test
 
 %post devel
 %ghc_pkg_recache
@@ -99,6 +81,6 @@
 
 %files devel -f %{name}-devel.files
 %defattr(-,root,root,-)
-%doc AUTHORS ChangeLog README.rst examples
+%doc AUTHORS ChangeLog README.md examples
 
 %changelog

++++++ HsOpenSSL-0.11.1.1.tar.gz -> HsOpenSSL-0.11.3.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/ChangeLog 
new/HsOpenSSL-0.11.3.2/ChangeLog
--- old/HsOpenSSL-0.11.1.1/ChangeLog    2015-01-06 08:36:45.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/ChangeLog    2016-10-17 16:11:02.000000000 +0200
@@ -1,3 +1,96 @@
+2016-10-17  Vladimir Shabanov  <[email protected]>
+
+       * HsOpenSSL.cabal (Version): Bump version to 0.11.3.2
+
+       * Test/*, HsOpenSSL.cabal (Build-Depends):
+       Removed HUnit, test-framework and test-framework-hunit dependencies.
+
+2016-10-15  Vladimir Shabanov  <[email protected]>
+
+       * HsOpenSSL.cabal (Version): Bump version to 0.11.3.1
+
+       * OpenSSL/Session.hsc: Detect failure of SSL_CTX_new,
+       by Eric Mertens @glguy (#13)
+
+2016-10-14  Vladimir Shabanov  <[email protected]>
+
+       * HsOpenSSL.cabal (Version): Bump version to 0.11.3
+
+       * HsOpenSSL.cabal (Build-Depends): Bump HUnit upper bound,
+
+       * OpenSSL/RSA.hsc, OpenSSL/DER.hsc: moved DER function from RSA to DER
+       module. Added encoding/decoding of private keys in ASN.1 DER.
+       by @shak-mar (#12).
+
+2016-10-08  Vladimir Shabanov  <[email protected]>
+
+       * HsOpenSSL.cabal (Version): Bump version to 0.11.2.4
+
+       * Setup.hs: Fixed handling of 'cabal configure' errors
+       in Homebrew/MacPorts OpenSSL autodetection.
+
+2016-10-06  Vladimir Shabanov  <[email protected]>
+
+       * HsOpenSSL.cabal (Version): Bump version to 0.11.2.3
+
+       * HsOpenSSL.cabal, Setup.hs:
+       Automatic detection of Homebrew or MacPorts OpenSSL on macOS
+       with helpful (I hope ;) error messages (phonohawk#41).
+       Previous approach caused ld warning 'directory not found',
+       wasn't informative when OpenSSL is not installed and could
+       potentially prevent linking with OpenSSL from another source.
+
+       * HsOpenSSL.cabal: Bump Cabal-Version to 1.12 (bundled with GHC 7.2.2).
+
+       * OpenSSL/Session.hsc: Exposed OpenSSL.Session internal types,
+       by Eric Mertens @glguy (#10).
+
+2016-10-05  Vladimir Shabanov  <[email protected]>
+
+       * HsOpenSSL.cabal (Version): Bump version to 0.11.2.2
+
+       * HsOpenSSL.cabal: Added Include-Dirs and Extra-Lib-Dirs for building
+       with Homebrew/MacPorts OpenSSL on Mac OS X 10.11+ (phonohawk#41)
+
+2016-10-04  Vladimir Shabanov  <[email protected]>
+
+       * HsOpenSSL.cabal (Version): Bump version to 0.11.2.1
+
+       * HsOpenSSL.cabal (Build-Depends):
+       base >= 4.4 && < 5 (GHC >= 7.2) instead of == 4.* (GHC >= 6.10)
+
+       * OpenSSL/RSA.hsc: fixed incompatibility with GHC < 7.10
+
+       * .travis.yml: Added Travis Job, by Herbert Valerio Riedel @hvr (#8).
+
+2016-10-04  Vladimir Shabanov  <[email protected]>
+
+       * HsOpenSSL.cabal (Version): Bump version to 0.11.2
+
+       * HsOpenSSL.cabal: New maintainer and GitHub repo path.
+
+       * HsOpenSSL.cabal: removed old-locale dependency (requires time >= 1.5).
+
+        * examples/Client.hs: Added client example, by @mirokuratczyk (#7).
+
+       * OpenSSL/EVP/Internal.hsc: Added cipherSetPadding function,
+       by @SX91 (#6).
+
+       * OpenSSL/BN.hsc: prandInteger functions now use BN_pseudo_rand_range,
+       by @Pamelloes (#5).
+
+       * OpenSSL/RSA.hsc, OpenSSL/X509.hs, OpenSSL/X509/Request.hs, 
Test/OpenSSL/RSA.hs, HsOpenSSL.cabal:
+       DER reading/writing for X509, X509Req & RSA,
+       by @newsham, @shak-mar, @afcady (#4)
+
+       * HsOpenSSL.cabal (Includes): Added openssl/asn1.h, by phadej (#3).
+
+       * HsOpenSSL.cabal (Build-Depends): Bump HUnit upper bound,
+       by phadej (#2).
+
+       * 10 files: Fixed GHC 7.10 warnings,
+       by Mikhail Glushenkov @23Skidoo (#1).
+
 2015-01-06  PHO  <[email protected]>
 
        * HsOpenSSL.cabal (Version): Bump version to 0.11.1.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/HsOpenSSL.cabal 
new/HsOpenSSL-0.11.3.2/HsOpenSSL.cabal
--- old/HsOpenSSL-0.11.1.1/HsOpenSSL.cabal      2015-01-06 08:36:45.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/HsOpenSSL.cabal      2016-10-17 16:11:02.000000000 
+0200
@@ -12,22 +12,23 @@
     <http://hackage.haskell.org/package/tls>, which is a pure Haskell
     implementation of SSL.
     .
-Version:       0.11.1.1
+Version:       0.11.3.2
 License:       PublicDomain
 License-File:  COPYING
 Author:        Adam Langley, Mikhail Vorozhtsov, PHO, Taru Karttunen
-Maintainer:    PHO <pho at cielonegro dot org>
+Maintainer:    Vladimir Shabanov <[email protected]>
 Stability:     stable
-Homepage:      https://github.com/phonohawk/HsOpenSSL
-Bug-Reports:   https://github.com/phonohawk/HsOpenSSL/issues
+Homepage:      https://github.com/vshabanov/HsOpenSSL
+Bug-Reports:   https://github.com/vshabanov/HsOpenSSL/issues
 Category:      Cryptography
-Tested-With:   GHC == 7.6.2
-Cabal-Version: >= 1.8
-Build-Type:    Simple
+Cabal-Version: >= 1.12
+Tested-With:
+    GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2, GHC==7.2.2
+Build-Type:    Custom
 Extra-Source-Files:
     AUTHORS
     ChangeLog
-    README.rst
+    README.md
     cbits/HsOpenSSL.h
     cbits/mutex.h
     examples/Makefile
@@ -40,23 +41,32 @@
 
 Source-Repository head
     Type: git
-    Location: git://github.com/phonohawk/HsOpenSSL.git
+    Location: git://github.com/vshabanov/HsOpenSSL.git
 
 Flag fast-bignum
     Description:
-        Enable fast moving of bignums between OpenSSL and GMP (GHC Only).
+        Enable fast moving of bignums between OpenSSL and GMP (GHC only).
     Default:
         True
 
+Flag homebrew-openssl
+    Description:
+        Use Homebrew version of OpenSSL (macOS only).
+    Default:
+        False
+
+Flag macports-openssl
+    Description:
+        Use MacPorts version of OpenSSL (macOS only).
+    Default:
+        False
+
 Library
     Build-Depends:
-        base       == 4.*,
+        base       >= 4.4 && < 5,
         bytestring >= 0.9   && < 0.11,
         network    >= 2.1   && < 2.7,
-        old-locale >= 1.0   && < 1.1,
-        time       >= 1.1.1 && < 1.6
-        -- old-locale is only needed if time < 1.5, but Cabal does not
-        -- allow us to express conditional dependencies like this.
+        time       >= 1.5   && < 1.7
 
     if flag(fast-bignum)
         CPP-Options: -DFAST_BIGNUM
@@ -64,9 +74,18 @@
             -- TODO: integer-gmp >= 1 is not supported yet.
             -- https://github.com/phonohawk/HsOpenSSL/issues/36
             Build-Depends: integer-gmp >= 0.2 && < 1
+            -- Doesn't work since GHC 7.10.1 (integer-gmp-1.0.0.0)
         else
             Build-Depends: ghc-prim, integer
 
+    if os(darwin) && flag(homebrew-openssl)
+        Include-Dirs: /usr/local/opt/openssl/include
+        Extra-Lib-Dirs: /usr/local/opt/openssl/lib
+
+    if os(darwin) && flag(macports-openssl)
+        Include-Dirs: /opt/local/include
+        Extra-Lib-Dirs: /opt/local/lib
+
     if os(mingw32)
         Extra-Libraries: eay32 ssl32
         C-Sources:       cbits/mutex-win.c
@@ -81,6 +100,7 @@
     Exposed-Modules:
         OpenSSL
         OpenSSL.BN
+        OpenSSL.DER
         OpenSSL.EVP.Base64
         OpenSSL.EVP.Cipher
         OpenSSL.EVP.Digest
@@ -113,48 +133,64 @@
         OpenSSL.Utils
         OpenSSL.X509.Name
         OpenSSL.DH.Internal
+    Default-Language:
+        Haskell2010
     GHC-Options:
         -Wall
     C-Sources:
         cbits/HsOpenSSL.c
     Include-Dirs:
         cbits
+    Includes:
+        openssl/asn1.h
 
 Test-Suite test-cipher
     Type:    exitcode-stdio-1.0
     Main-Is: Test/OpenSSL/Cipher.hs
+    Other-Modules: Test.OpenSSL.TestUtils
     Build-Depends:
         HsOpenSSL,
-        HUnit                >= 1.0 && < 1.3,
-        base                 == 4.*,
-        bytestring           >= 0.9 && < 0.11,
-        test-framework       >= 0.8 && < 0.9,
-        test-framework-hunit >= 0.3 && < 0.4
+        base                 >= 4.4 && < 5,
+        bytestring           >= 0.9 && < 0.11
+    Default-Language:
+        Haskell2010
     GHC-Options:
         -Wall
 
 Test-Suite test-dsa
     Type:    exitcode-stdio-1.0
     Main-Is: Test/OpenSSL/DSA.hs
+    Other-Modules: Test.OpenSSL.TestUtils
+    Build-Depends:
+        HsOpenSSL,
+        base                 >= 4.4 && < 5,
+        bytestring           >= 0.9 && < 0.11
+    Default-Language:
+        Haskell2010
+    GHC-Options:
+        -Wall
+
+Test-Suite test-der
+    Type:    exitcode-stdio-1.0
+    Main-Is: Test/OpenSSL/DER.hs
+    Other-Modules: Test.OpenSSL.TestUtils
     Build-Depends:
         HsOpenSSL,
-        HUnit                >= 1.0 && < 1.3,
-        base                 == 4.*,
-        bytestring           >= 0.9 && < 0.11,
-        test-framework       >= 0.8 && < 0.9,
-        test-framework-hunit >= 0.3 && < 0.4
+        base                 >= 4.4 && < 5
+    Default-Language:
+        Haskell2010
     GHC-Options:
         -Wall
 
 Test-Suite test-evp-base64
     Type:    exitcode-stdio-1.0
     Main-Is: Test/OpenSSL/EVP/Base64.hs
+    Other-Modules: Test.OpenSSL.TestUtils
     Build-Depends:
         HsOpenSSL,
-        HUnit                >= 1.0 && < 1.3,
-        base                 == 4.*,
-        bytestring           >= 0.9 && < 0.11,
-        test-framework       >= 0.8 && < 0.9,
-        test-framework-hunit >= 0.3 && < 0.4
+        base                 >= 4.4 && < 5,
+        bytestring           >= 0.9 && < 0.11
+    Default-Language:
+        Haskell2010
     GHC-Options:
         -Wall
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/ASN1.hsc 
new/HsOpenSSL-0.11.3.2/OpenSSL/ASN1.hsc
--- old/HsOpenSSL-0.11.1.1/OpenSSL/ASN1.hsc     2015-01-06 08:36:45.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/ASN1.hsc     2016-10-17 16:11:02.000000000 
+0200
@@ -28,9 +28,6 @@
 import           OpenSSL.BIO
 import           OpenSSL.BN
 import           OpenSSL.Utils
-#if !MIN_VERSION_time(1,5,0)
-import           System.Locale
-#endif
 
 {- ASN1_OBJECT --------------------------------------------------------------- 
-}
 
@@ -128,11 +125,7 @@
              _ASN1_TIME_print bioPtr time
                   >>= failIf_ (/= 1)
          timeStr <- bioRead bio
-#if MIN_VERSION_time(1,5,0)
          case parseTimeM True locale "%b %e %H:%M:%S %Y %Z" timeStr of
-#else
-         case parseTime locale "%b %e %H:%M:%S %Y %Z" timeStr of
-#endif
            Just utc -> return utc
            Nothing  -> fail ("peekASN1Time: failed to parse time string: " ++ 
timeStr)
     where
@@ -144,17 +137,12 @@
                                             , "Jul", "Aug", "Sep", "Oct", 
"Nov", "Dec"
                                             ]
                                ]
-#if !MIN_VERSION_time(1,5,0)
-               , intervals   = undefined
-#endif
                , amPm        = undefined
                , dateTimeFmt = undefined
                , dateFmt     = undefined
                , timeFmt     = undefined
                , time12Fmt   = undefined
-#if MIN_VERSION_time(1,5,0)
                , knownTimeZones = []
-#endif
                }
 
 
@@ -168,4 +156,4 @@
     = allocaASN1Time $ \ time ->
       do _ASN1_TIME_set time (fromIntegral (round $ utcTimeToPOSIXSeconds utc 
:: Integer))
               >>= failIfNull_
-         m time
\ No newline at end of file
+         m time
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/BN.hsc 
new/HsOpenSSL-0.11.3.2/OpenSSL/BN.hsc
--- old/HsOpenSSL-0.11.1.1/OpenSSL/BN.hsc       2015-01-06 08:36:44.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/BN.hsc       2016-10-17 16:11:02.000000000 
+0200
@@ -339,7 +339,7 @@
 prandIntegerUptoNMinusOneSuchThat f range = withBN range (\bnRange -> (do
   r <- newBN 0
   let try = do
-        _BN_rand_range (unwrapBN r) (unwrapBN bnRange) >>= failIf_ (/= 1)
+        _BN_pseudo_rand_range (unwrapBN r) (unwrapBN bnRange) >>= failIf_ (/= 
1)
         i <- bnToInteger r
         if f i
            then return i
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/DER.hsc 
new/HsOpenSSL-0.11.3.2/OpenSSL/DER.hsc
--- old/HsOpenSSL-0.11.1.1/OpenSSL/DER.hsc      1970-01-01 01:00:00.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/DER.hsc      2016-10-17 16:11:02.000000000 
+0200
@@ -0,0 +1,89 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- |Encoding and decoding of RSA keys using the ASN.1 DER format
+module OpenSSL.DER
+    ( toDERPub
+    , fromDERPub
+    , toDERPriv
+    , fromDERPriv
+    )
+    where
+
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative ((<$>))
+#endif
+import           OpenSSL.RSA                (RSA, RSAKey, RSAKeyPair, 
RSAPubKey,
+                                             absorbRSAPtr, withRSAPtr)
+
+import           Data.ByteString            (ByteString)
+import qualified Data.ByteString            as B  (useAsCStringLen)
+import qualified Data.ByteString.Internal   as BI (createAndTrim)
+import           Foreign.Ptr                (Ptr, nullPtr)
+import           Foreign.C.String           (CString)
+import           Foreign.C.Types            (CLong(..), CInt(..))
+import           Foreign.Marshal.Alloc      (alloca)
+import           Foreign.Storable           (poke)
+import           GHC.Word                   (Word8)
+import           System.IO.Unsafe           (unsafePerformIO)
+
+type CDecodeFun = Ptr (Ptr RSA) -> Ptr CString -> CLong -> IO (Ptr RSA)
+type CEncodeFun = Ptr RSA -> Ptr (Ptr Word8) -> IO CInt
+
+foreign import ccall unsafe "d2i_RSAPublicKey"
+  _fromDERPub :: CDecodeFun
+
+foreign import ccall unsafe "i2d_RSAPublicKey"
+  _toDERPub :: CEncodeFun
+
+foreign import ccall unsafe "d2i_RSAPrivateKey"
+  _fromDERPriv :: CDecodeFun
+
+foreign import ccall unsafe "i2d_RSAPrivateKey"
+  _toDERPriv :: CEncodeFun
+
+-- | Generate a function that decodes a key from ASN.1 DER format
+makeDecodeFun :: RSAKey k => CDecodeFun -> ByteString -> Maybe k
+makeDecodeFun fun bs = unsafePerformIO . usingConvedBS $ \(csPtr, ci) -> do
+  -- When you pass a null pointer to this function, it will allocate the memory
+  -- space required for the RSA key all by itself.  It will be freed whenever
+  -- the haskell object is garbage collected, as they are stored in ForeignPtrs
+  -- internally.
+  rsaPtr <- fun nullPtr csPtr ci
+  if rsaPtr == nullPtr then return Nothing else absorbRSAPtr rsaPtr
+  where usingConvedBS io = B.useAsCStringLen bs $ \(cs, len) ->
+          alloca $ \csPtr -> poke csPtr cs >> io (csPtr, fromIntegral len)
+
+-- | Generate a function that encodes a key in ASN.1 DER format
+makeEncodeFun :: RSAKey k => CEncodeFun -> k -> ByteString
+makeEncodeFun fun k = unsafePerformIO $ do
+  -- When you pass a null pointer to this function, it will only compute the
+  -- required buffer size.  See https://www.openssl.org/docs/faq.html#PROG3
+  requiredSize <- withRSAPtr k $ flip fun nullPtr
+  -- It’s too sad BI.createAndTrim is considered internal, as it does a great
+  -- job here.  See 
https://hackage.haskell.org/package/bytestring-0.9.1.4/docs/Data-ByteString-Internal.html#v%3AcreateAndTrim
+  BI.createAndTrim (fromIntegral requiredSize) $ \ptr ->
+    alloca $ \pptr ->
+      (fromIntegral <$>) . withRSAPtr k $ \key ->
+        poke pptr ptr >> fun key pptr
+
+-- | Dump a public key to ASN.1 DER format
+toDERPub :: RSAKey k
+         => k          -- ^ You can pass either 'RSAPubKey' or 'RSAKeyPair'
+                       --   because both contain the necessary information.
+         -> ByteString -- ^ The public key information encoded in ASN.1 DER
+toDERPub = makeEncodeFun _toDERPub
+
+-- | Parse a public key from ASN.1 DER format
+fromDERPub :: ByteString -> Maybe RSAPubKey
+fromDERPub = makeDecodeFun _fromDERPub
+
+-- | Dump a private key to ASN.1 DER format
+toDERPriv :: RSAKeyPair -> ByteString
+toDERPriv = makeEncodeFun _toDERPriv
+
+-- | Parse a private key from ASN.1 DER format
+fromDERPriv :: RSAKey k
+            => ByteString -- ^ The private key information encoded in ASN.1 DER
+            -> Maybe k    -- ^ This can return either 'RSAPubKey' or
+                          --   'RSAKeyPair' because there’s sufficient
+                          --   information for both.
+fromDERPriv = makeDecodeFun _fromDERPriv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/DH/Internal.hs 
new/HsOpenSSL-0.11.3.2/OpenSSL/DH/Internal.hs
--- old/HsOpenSSL-0.11.1.1/OpenSSL/DH/Internal.hs       2015-01-06 
08:36:45.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/DH/Internal.hs       2016-10-17 
16:11:02.000000000 +0200
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP                      #-}
 {-# LANGUAGE EmptyDataDecls           #-}
 {-# LANGUAGE ForeignFunctionInterface #-}
 module OpenSSL.DH.Internal (
@@ -14,11 +15,14 @@
     asDHP
   ) where
 
-import Control.Applicative ((<$>))
 import Foreign.Ptr (Ptr)
 import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)
 import qualified Foreign.Concurrent as FC
 
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative ((<$>))
+#endif
+
 data DH_
 newtype DHP = DHP (ForeignPtr DH_)
 
@@ -50,4 +54,3 @@
 
 foreign import ccall "DH_free"
   _DH_free :: Ptr DH_ -> IO ()
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/DH.hs 
new/HsOpenSSL-0.11.3.2/OpenSSL/DH.hs
--- old/HsOpenSSL-0.11.1.1/OpenSSL/DH.hs        2015-01-06 08:36:45.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/DH.hs        2016-10-17 16:11:02.000000000 
+0200
@@ -17,7 +17,9 @@
 import Data.Word (Word8)
 import Data.ByteString (ByteString)
 import qualified Data.ByteString.Internal as BS
+#if !MIN_VERSION_base(4,8,0)
 import Control.Applicative ((<$>))
+#endif
 import Foreign.Ptr (Ptr, nullPtr)
 #if MIN_VERSION_base(4,5,0)
 import Foreign.C.Types (CInt(..))
@@ -96,4 +98,3 @@
   _DH_get_pub_key :: Ptr DH_ -> IO (Ptr BIGNUM)
 foreign import ccall unsafe "HsOpenSSL_DH_length"
   _DH_length :: Ptr DH_ -> IO CInt
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/EVP/Base64.hs 
new/HsOpenSSL-0.11.3.2/OpenSSL/EVP/Base64.hs
--- old/HsOpenSSL-0.11.1.1/OpenSSL/EVP/Base64.hs        2015-01-06 
08:36:44.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/EVP/Base64.hs        2016-10-17 
16:11:02.000000000 +0200
@@ -93,7 +93,7 @@
               remain                  = if B8.null leftover then
                                             remain'
                                         else
-                                           L8.fromChunks [leftover] 
`L8.append` remain'
+                                            L8.fromChunks [leftover] 
`L8.append` remain'
               encodedBlock             = encodeBlock block
               encodedRemain            = encodeBase64LBS remain
           in
@@ -143,7 +143,7 @@
               remain                  = if B8.null leftover then
                                             remain'
                                         else
-                                           L8.fromChunks [leftover] 
`L8.append` remain'
+                                            L8.fromChunks [leftover] 
`L8.append` remain'
               decodedBlock            = decodeBlock block
               decodedRemain           = decodeBase64LBS remain
           in
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/EVP/Cipher.hs 
new/HsOpenSSL-0.11.3.2/OpenSSL/EVP/Cipher.hs
--- old/HsOpenSSL-0.11.1.1/OpenSSL/EVP/Cipher.hs        2015-01-06 
08:36:44.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/EVP/Cipher.hs        2016-10-17 
16:11:02.000000000 +0200
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP                      #-}
 {-# LANGUAGE ForeignFunctionInterface #-}
 -- |An interface to symmetric cipher algorithms.
 module OpenSSL.EVP.Cipher
@@ -15,12 +16,15 @@
     where
 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.EVP.Internal
 
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid
+#endif
+
 foreign import ccall unsafe "EVP_get_cipherbyname"
         _get_cipherbyname :: CString -> IO (Ptr EVP_CIPHER)
 
@@ -93,4 +97,3 @@
 cipherLBS c key iv mode input
     = do ctx <- cipherInitBS c key iv mode
          cipherLazily ctx input
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/EVP/Digest.hsc 
new/HsOpenSSL-0.11.3.2/OpenSSL/EVP/Digest.hsc
--- old/HsOpenSSL-0.11.1.1/OpenSSL/EVP/Digest.hsc       2015-01-06 
08:36:44.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/EVP/Digest.hsc       2016-10-17 
16:11:02.000000000 +0200
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP                      #-}
 {-# LANGUAGE ForeignFunctionInterface #-}
 -- |An interface to message digest algorithms.
 module OpenSSL.EVP.Digest
@@ -18,7 +19,9 @@
 import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
 import qualified Data.ByteString.Char8 as B8
 import qualified Data.ByteString.Lazy.Char8 as L8
+#if !MIN_VERSION_base(4,8,0)
 import Control.Applicative ((<$>))
+#endif
 import Foreign.C.String (CString, withCString)
 #if MIN_VERSION_base(4,5,0)
 import Foreign.C.Types (CChar(..), CInt(..), CSize(..), CUInt(..))
@@ -118,4 +121,3 @@
                           -> Ptr CChar -> CInt
                           -> CInt -> CInt -> Ptr CChar
                           -> IO CInt
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/EVP/Internal.hsc 
new/HsOpenSSL-0.11.3.2/OpenSSL/EVP/Internal.hsc
--- old/HsOpenSSL-0.11.1.1/OpenSSL/EVP/Internal.hsc     2015-01-06 
08:36:44.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/EVP/Internal.hsc     2016-10-17 
16:11:02.000000000 +0200
@@ -14,6 +14,7 @@
     withNewCipherCtxPtr,
 
     CryptoMode(..),
+    cipherSetPadding,
     cipherInitBS,
     cipherUpdateBS,
     cipherFinalBS,
@@ -52,7 +53,9 @@
 import qualified Data.ByteString.Char8 as B8
 import qualified Data.ByteString.Lazy.Char8 as L8
 import qualified Data.ByteString.Lazy.Internal as L8
+#if !MIN_VERSION_base(4,8,0)
 import Control.Applicative ((<$>))
+#endif
 import Control.Exception (mask, mask_, bracket_, onException)
 import Foreign.C.Types (CChar)
 #if MIN_VERSION_base(4,5,0)
@@ -132,6 +135,16 @@
 fromCryptoMode Encrypt = 1
 fromCryptoMode Decrypt = 0
 
+foreign import ccall unsafe "EVP_CIPHER_CTX_set_padding"
+  _SetPadding :: Ptr EVP_CIPHER_CTX -> CInt -> IO CInt
+
+cipherSetPadding :: CipherCtx -> Int -> IO CipherCtx
+cipherSetPadding ctx pad 
+  = do withCipherCtxPtr ctx $ \ctxPtr ->
+           _SetPadding ctxPtr (fromIntegral pad)
+               >>= failIf_ (/= 1)
+       return ctx
+
 foreign import ccall unsafe "EVP_CipherInit"
         _CipherInit :: Ptr EVP_CIPHER_CTX
                     -> Ptr EVP_CIPHER
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/EVP/Sign.hs 
new/HsOpenSSL-0.11.3.2/OpenSSL/EVP/Sign.hs
--- old/HsOpenSSL-0.11.1.1/OpenSSL/EVP/Sign.hs  2015-01-06 08:36:44.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/EVP/Sign.hs  2016-10-17 16:11:02.000000000 
+0200
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP                      #-}
 {-# LANGUAGE ForeignFunctionInterface #-}
 -- |Message signing using asymmetric cipher and message digest
 -- algorithm. This is an opposite of "OpenSSL.EVP.Verify".
@@ -10,7 +11,9 @@
 import qualified Data.ByteString.Char8 as B8
 import qualified Data.ByteString.Internal as B8
 import qualified Data.ByteString.Lazy.Char8 as L8
+#if !MIN_VERSION_base(4,8,0)
 import           Control.Applicative ((<$>))
+#endif
 import           Foreign
 import           Foreign.C
 import           OpenSSL.EVP.Digest
@@ -64,4 +67,3 @@
     = do ctx <- digestLazily md input
          sig <- signFinal ctx pkey
          return $ L8.fromChunks [sig]
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/RSA.hsc 
new/HsOpenSSL-0.11.3.2/OpenSSL/RSA.hsc
--- old/HsOpenSSL-0.11.1.1/OpenSSL/RSA.hsc      2015-01-06 08:36:45.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/RSA.hsc      2016-10-17 16:11:02.000000000 
+0200
@@ -28,7 +28,11 @@
     where
 #include "HsOpenSSL.h"
 import Control.Monad
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative ((<$>))
+#endif
 import Data.Typeable
+
 #if MIN_VERSION_base(4,5,0)
 import Foreign.C.Types (CInt(..))
 #else
@@ -104,7 +108,7 @@
          p <- (#peek RSA, p) rsaPtr
          q <- (#peek RSA, q) rsaPtr
          return (d /= nullPtr && p /= nullPtr && q /= nullPtr)
-                                               
+
 
 
 foreign import ccall unsafe "&RSA_free"
@@ -233,7 +237,6 @@
 rsaIQMP :: RSAKeyPair -> Maybe Integer
 rsaIQMP = peekMI (#peek RSA, iqmp)
 
-
 {- instances ---------------------------------------------------------------- 
-}
 
 instance Eq RSAPubKey where
@@ -277,7 +280,7 @@
                  , "rsaN = ", show (rsaN a), ", "
                  , "rsaE = ", show (rsaE a)
                  , "}"
-                 ] 
+                 ]
 
 instance Show RSAKeyPair where
     show a
@@ -288,4 +291,4 @@
                  , "rsaP = ", show (rsaP a), ", "
                  , "rsaQ = ", show (rsaQ a)
                  , "}"
-                 ] 
+                 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/Session.hsc 
new/HsOpenSSL-0.11.3.2/OpenSSL/Session.hsc
--- old/HsOpenSSL-0.11.1.1/OpenSSL/Session.hsc  2015-01-06 08:36:45.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/Session.hsc  2016-10-17 16:11:02.000000000 
+0200
@@ -37,6 +37,7 @@
   , fdConnection
   , addOption
   , removeOption
+  , setTlsextHostName
   , accept
   , tryAccept
   , connect
@@ -66,6 +67,13 @@
   , SomeSSLException
   , ConnectionAbruptlyTerminated
   , ProtocolError(..)
+
+    -- * Direct access to OpenSSL objects
+  , SSLContext_
+  , withContext
+  , SSL_
+  , withSSL
+
   ) where
 
 #include "openssl/ssl.h"
@@ -78,11 +86,10 @@
 import Control.Concurrent (threadWaitWrite, threadWaitRead, runInBoundThread)
 import Control.Concurrent.MVar
 import Control.Exception
-import Control.Applicative ((<$>), (<$))
 import Control.Monad (unless)
+import Data.Foldable (mapM_, forM_)
+import Data.Traversable (mapM)
 import Data.Typeable
-import Data.Foldable (Foldable, mapM_, forM_)
-import Data.Traversable (Traversable, mapM)
 import Data.Maybe (fromMaybe)
 import Data.IORef
 import Foreign
@@ -96,6 +103,12 @@
 import System.Posix.Types (Fd(..))
 import Network.Socket (Socket(..))
 
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative ((<$>), (<$))
+import Data.Foldable (Foldable)
+import Data.Traversable (Traversable)
+#endif
+
 import OpenSSL.ERR
 import OpenSSL.EVP.PKey
 import OpenSSL.EVP.Internal
@@ -128,7 +141,7 @@
 -- | Create a new SSL context.
 context :: IO SSLContext
 context = mask_ $ do
-  ctx   <- _ssl_method >>= _ssl_ctx_new
+  ctx   <- _ssl_method >>= _ssl_ctx_new >>= failIfNull
   cbRef <- newIORef Nothing
   mvar  <- newMVar ctx
 #if MIN_VERSION_base(4,6,0)
@@ -370,6 +383,7 @@
 fdConnection :: SSLContext -> Fd -> IO SSL
 fdConnection context fd = connection' context fd Nothing
 
+-- | Run continuation with exclusive access to the underlying SSL object.
 withSSL :: SSL -> (Ptr SSL_ -> IO a) -> IO a
 withSSL = withMVar . sslMVar
 
@@ -379,6 +393,9 @@
 foreign import ccall unsafe "HsOpenSSL_SSL_clear_options"
     _SSL_clear_options :: Ptr SSL_ -> CLong -> IO CLong
 
+foreign import ccall unsafe "HsOpenSSL_SSL_set_tlsext_host_name"
+    _SSL_set_tlsext_host_name :: Ptr SSL_ -> CString -> IO CLong
+
 -- | Add a protocol option to the SSL connection.
 addOption :: SSL -> SSLOption -> IO ()
 addOption ssl opt =
@@ -391,6 +408,13 @@
     withSSL ssl $ \sslPtr ->
         _SSL_clear_options sslPtr (optionToIntegral opt) >> return ()
 
+-- | Set host name for Server Name Indication (SNI)
+setTlsextHostName :: SSL -> String -> IO ()
+setTlsextHostName ssl h =
+    withSSL ssl $ \sslPtr ->
+    withCString h $ \ hPtr ->
+        _SSL_set_tlsext_host_name sslPtr hPtr >> return ()
+
 foreign import ccall "SSL_accept" _ssl_accept :: Ptr SSL_ -> IO CInt
 foreign import ccall "SSL_connect" _ssl_connect :: Ptr SSL_ -> IO CInt
 foreign import ccall unsafe "SSL_get_error" _ssl_get_error :: Ptr SSL_ -> CInt 
-> IO CInt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/X509/Request.hs 
new/HsOpenSSL-0.11.3.2/OpenSSL/X509/Request.hs
--- old/HsOpenSSL-0.11.1.1/OpenSSL/X509/Request.hs      2015-01-06 
08:36:45.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/X509/Request.hs      2016-10-17 
16:11:02.000000000 +0200
@@ -16,6 +16,7 @@
     , verifyX509Req
 
     , printX509Req
+    , writeX509ReqDER
 
     , makeX509FromReq
 
@@ -28,6 +29,8 @@
 
     , getPublicKey
     , setPublicKey
+
+    , addExtensions
     )
     where
 
@@ -44,12 +47,15 @@
 import           OpenSSL.X509 (X509)
 import qualified OpenSSL.X509 as Cert
 import           OpenSSL.X509.Name
+import           Data.ByteString.Lazy (ByteString)
+import           OpenSSL.Stack
 
 -- |@'X509Req'@ is an opaque object that represents PKCS#10
 -- certificate request.
 newtype X509Req  = X509Req (ForeignPtr X509_REQ)
 data    X509_REQ
 
+data    X509_EXT
 
 foreign import ccall unsafe "X509_REQ_new"
         _new :: IO (Ptr X509_REQ)
@@ -66,6 +72,9 @@
 foreign import ccall unsafe "X509_REQ_print"
         _print :: Ptr BIO_ -> Ptr X509_REQ -> IO CInt
 
+foreign import ccall unsafe "i2d_X509_REQ_bio"
+        _req_to_der :: Ptr BIO_ -> Ptr X509_REQ -> IO CInt
+
 foreign import ccall unsafe "HsOpenSSL_X509_REQ_get_version"
         _get_version :: Ptr X509_REQ -> IO CLong
 
@@ -84,6 +93,13 @@
 foreign import ccall unsafe "X509_REQ_set_pubkey"
         _set_pubkey :: Ptr X509_REQ -> Ptr EVP_PKEY -> IO CInt
 
+foreign import ccall unsafe "X509V3_EXT_nconf_nid"
+        _ext_create :: Ptr a -> Ptr b -> CInt -> CString -> IO (Ptr X509_EXT)
+
+foreign import ccall unsafe "X509_REQ_add_extensions"
+        _req_add_extensions :: Ptr X509_REQ -> Ptr STACK -> IO CInt
+
+
 -- |@'newX509Req'@ creates an empty certificate request. You must set
 -- the following properties to and sign it (see 'signX509Req') to
 -- actually use the certificate request.
@@ -152,6 +168,19 @@
                       >>= failIf_ (/= 1)
          bioRead mem
 
+{- DER encoding ------------------------------------------------------------- 
-}
+
+-- |@'writeX509ReqDER' req@ writes a PKCS#10 certificate request to DER string.
+writeX509ReqDER :: X509Req -> IO ByteString
+writeX509ReqDER req
+    = do mem <- newMem
+         withBioPtr mem $ \ memPtr ->
+             withX509ReqPtr req $ \ reqPtr ->
+                 _req_to_der memPtr reqPtr
+                      >>= failIf_ (< 0)
+         bioReadLBS mem
+
+
 -- |@'getVersion' req@ returns the version number of certificate
 -- request.
 getVersion :: X509Req -> IO Int
@@ -211,6 +240,21 @@
            >>  return ()
 
 
+-- |@'addExtensions' req [(nid, str)]@
+--
+-- E.g., nid 85 = 'subjectAltName' 
http://osxr.org:8080/openssl/source/crypto/objects/objects.h#0476
+--
+-- (TODO: more docs; NID type)
+addExtensions :: X509Req -> [(Int, String)] -> IO CInt
+addExtensions req exts =
+  withX509ReqPtr req $ \reqPtr -> do
+    extPtrs <- forM exts make
+    withStack extPtrs $ _req_add_extensions reqPtr
+
+  where
+    make (nid, str) = withCString str $ _ext_create nullPtr nullPtr 
(fromIntegral nid)
+
+
 -- |@'makeX509FromReq' req cert@ creates an empty X.509 certificate
 -- and copies as much data from the request as possible. The resulting
 -- certificate doesn't have the following data and it isn't signed so
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/X509/Store.hs 
new/HsOpenSSL-0.11.3.2/OpenSSL/X509/Store.hs
--- old/HsOpenSSL-0.11.1.1/OpenSSL/X509/Store.hs        2015-01-06 
08:36:45.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/X509/Store.hs        2016-10-17 
16:11:02.000000000 +0200
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP                      #-}
 {-# LANGUAGE EmptyDataDecls           #-}
 {-# LANGUAGE ForeignFunctionInterface #-}
 {-# OPTIONS_HADDOCK prune             #-}
@@ -26,7 +27,9 @@
     , getStoreCtxChain
     )
     where
+#if !MIN_VERSION_base(4,8,0)
 import Control.Applicative ((<$>))
+#endif
 import Control.Exception (throwIO, mask_)
 import Foreign
 import Foreign.C
@@ -142,4 +145,3 @@
 getStoreCtxChain ctx = withX509StoreCtxPtr ctx $ \pCtx -> do
   stack <- _store_ctx_get_chain pCtx
   (`mapStack` stack) $ \pCert -> mask_ $ _x509_ref pCert >> wrapX509 pCert
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/OpenSSL/X509.hs 
new/HsOpenSSL-0.11.3.2/OpenSSL/X509.hs
--- old/HsOpenSSL-0.11.1.1/OpenSSL/X509.hs      2015-01-06 08:36:45.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/OpenSSL/X509.hs      2016-10-17 16:11:02.000000000 
+0200
@@ -16,6 +16,8 @@
     , unsafeX509ToPtr -- private
     , touchX509 -- private
 
+    , writeDerX509
+    , readDerX509
     , compareX509
 
     , signX509
@@ -68,6 +70,7 @@
 import OpenSSL.Utils
 import OpenSSL.Stack
 import OpenSSL.X509.Name
+import Data.ByteString.Lazy (ByteString)
 
 -- |@'X509'@ is an opaque object that represents X.509 certificate.
 newtype X509  = X509 (ForeignPtr X509_)
@@ -140,6 +143,16 @@
 foreign import ccall unsafe "X509_verify"
         _verify :: Ptr X509_ -> Ptr EVP_PKEY -> IO CInt
 
+foreign import ccall safe "i2d_X509_bio"
+        _write_bio_X509 :: Ptr BIO_
+                        -> Ptr X509_
+                        -> IO CInt
+
+foreign import ccall safe "d2i_X509_bio"
+        _read_bio_X509 :: Ptr BIO_
+                       -> Ptr (Ptr X509_)
+                       -> IO (Ptr X509_)
+
 -- |@'newX509'@ creates an empty certificate. You must set the
 -- following properties to and sign it (see 'signX509') to actually
 -- use the certificate.
@@ -179,6 +192,33 @@
 touchX509 :: X509 -> IO ()
 touchX509 (X509 x509) = touchForeignPtr x509
 
+writeX509' :: BIO -> X509 -> IO ()
+writeX509' bio x509
+    = withBioPtr bio   $ \ bioPtr ->
+      withX509Ptr x509 $ \ x509Ptr ->
+      _write_bio_X509 bioPtr x509Ptr
+           >>= failIf (< 0)
+           >>  return ()
+
+-- |@'writeDerX509' cert@ writes an X.509 certificate to DER string.
+writeDerX509 :: X509 -> IO ByteString
+writeDerX509 x509
+    = do mem <- newMem
+         writeX509' mem x509
+         bioReadLBS mem
+
+readX509' :: BIO -> IO X509
+readX509' bio
+    = withBioPtr bio $ \ bioPtr ->
+      _read_bio_X509 bioPtr nullPtr 
+           >>= failIfNull
+           >>= wrapX509 
+
+-- |@'readDerX509' der@ reads in a certificate.
+readDerX509 :: ByteString -> IO X509
+readDerX509 derStr
+    = newConstMemLBS derStr >>= readX509'
+
 -- |@'compareX509' cert1 cert2@ compares two certificates.
 compareX509 :: X509 -> X509 -> IO Ordering
 compareX509 cert1 cert2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/README.md 
new/HsOpenSSL-0.11.3.2/README.md
--- old/HsOpenSSL-0.11.1.1/README.md    1970-01-01 01:00:00.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/README.md    2016-10-17 16:11:02.000000000 +0200
@@ -0,0 +1,9 @@
+HsOpenSSL
+==========
+
+[![Build 
Status](https://travis-ci.org/vshabanov/HsOpenSSL.svg?branch=master)](https://travis-ci.org/vshabanov/HsOpenSSL)
+
+HsOpenSSL is an (incomplete) OpenSSL binding for Haskell. It can
+generate RSA and DSA keys, read and write PEM files, generate message
+digests, sign and verify messages, encrypt and decrypt messages. It
+also has some capabilities of creating SSL clients and servers.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/README.rst 
new/HsOpenSSL-0.11.3.2/README.rst
--- old/HsOpenSSL-0.11.1.1/README.rst   2015-01-06 08:36:45.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/README.rst   1970-01-01 01:00:00.000000000 +0100
@@ -1,8 +0,0 @@
-======
-README
-======
-
-HsOpenSSL is an (incomplete) OpenSSL binding for Haskell. It can
-generate RSA and DSA keys, read and write PEM files, generate message
-digests, sign and verify messages, encrypt and decrypt messages. It
-also has some capabilities of creating SSL clients and servers.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/Setup.hs 
new/HsOpenSSL-0.11.3.2/Setup.hs
--- old/HsOpenSSL-0.11.1.1/Setup.hs     2015-01-06 08:36:45.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/Setup.hs     2016-10-17 16:11:02.000000000 +0200
@@ -1,4 +1,92 @@
 #!/usr/bin/env runghc
 
+{-# LANGUAGE TupleSections #-}
+
 import Distribution.Simple
-main = defaultMain
+import Distribution.Simple.Setup (ConfigFlags(..), toFlag)
+import Distribution.Simple.LocalBuildInfo (localPkgDescr)
+import Distribution.PackageDescription (FlagName(..))
+import Distribution.Verbosity (silent)
+import System.Info (os)
+import qualified Control.Exception as E (tryJust, throw)
+import System.IO.Error (isUserError)
+import Control.Monad (forM)
+import Data.List
+
+-- On macOS we're checking whether OpenSSL library is avaiable
+-- and if not, we're trying to find Homebrew or MacPorts OpenSSL installations.
+--
+-- Method is dumb -- set homebrew-openssl or macports-openssl flag and try
+-- to configure and check C libs.
+--
+-- If no or multiple libraries are found we display error message
+-- with instructions.
+
+main
+    | os == "darwin" =
+        defaultMainWithHooks simpleUserHooks { confHook = conf }
+    | otherwise =
+        defaultMain
+
+flags = ["homebrew-openssl", "macports-openssl"]
+
+conf descr cfg = do
+    c <- tryConfig descr cfg
+    case c of
+        Right lbi -> return lbi -- library was found
+        Left e
+            | configConfigurationsFlags cfg
+              `intersect` [(FlagName f, True) | f <- flags] /= [] ->
+                E.throw e
+                -- flag was set but library still wasn't found
+            | otherwise -> do
+                r <- forM flags $ \ f ->
+                    fmap (f,) $ tryConfig descr $
+                    setFlag f cfg { configVerbosity = toFlag silent }
+                    -- TODO: configure is a long operation
+                    -- while checkForeignDeps is fast.
+                    -- Perhaps there is a way to configure once
+                    -- and only apply flags to result and check.
+                    -- However, additional `configure`s happen only on macOS
+                    -- and only when library wasn't found.
+                case [(f,r) | (f, Right r) <- r] of
+                    [(_,lbi)] ->
+                        return lbi -- library was found
+                    [] ->
+                        fail notFound
+                    fs ->
+                        fail $ multipleFound fs
+
+notFound =
+    "Can't find OpenSSL library,\n\
+    \install it via 'brew install openssl' or 'port install openssl'\n\
+    \or use --extra-include-dirs= and --extra-lib-dirs=\n\
+    \to specify location of installed OpenSSL library."
+
+multipleFound fs =
+    "Multiple OpenSSL libraries were found,\n\
+    \use " ++ intercalate " or " ["'-f " ++ f ++ "'" | (f,_) <- fs] ++ "\n\
+    \to specify location of installed OpenSSL library."
+
+setFlag f c = c { configConfigurationsFlags = go (configConfigurationsFlags c) 
}
+    where go [] = []
+          go (x@(FlagName n, _):xs)
+              | n == f = (FlagName f, True) : xs
+              | otherwise = x : go xs
+
+tryConfig descr flags = do
+    lbi <- confHook simpleUserHooks descr flags
+    -- confHook simpleUserHooks == Distribution.Simple.Configure.configure
+
+    -- Testing whether C lib and header dependencies are working.
+    -- We check exceptions only here, to check C libs errors but not other
+    -- configuration problems like not resolved .cabal dependencies.
+    E.tryJust ue $ do
+        postConf simpleUserHooks [] flags (localPkgDescr lbi) lbi
+        -- postConf simpleUserHooks ~==
+        --   Distribution.Simple.Configure.checkForeignDeps
+
+        return lbi
+
+    where ue e | isUserError e = Just e
+               | otherwise = Nothing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/Test/OpenSSL/Cipher.hs 
new/HsOpenSSL-0.11.3.2/Test/OpenSSL/Cipher.hs
--- old/HsOpenSSL-0.11.1.1/Test/OpenSSL/Cipher.hs       2015-01-06 
08:36:45.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/Test/OpenSSL/Cipher.hs       2016-10-17 
16:11:02.000000000 +0200
@@ -1,10 +1,9 @@
 -- | Tests for the non-EVP ciphers
 module Main (main) where
+
 import qualified Data.ByteString as BS
 import OpenSSL.Cipher
-import qualified Test.Framework as TF
-import qualified Test.Framework.Providers.HUnit as TF
-import Test.HUnit
+import Test.OpenSSL.TestUtils
 
 -- | Convert a hex string to a ByteString (e.g. "0011" == BS.pack [0, 0x11])
 hexToBS :: String -> BS.ByteString
@@ -64,15 +63,12 @@
           (hexToBS 
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223")
           (hexToBS 
"EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8") ]
 
-runCtrTest :: CTRTest -> Test
-runCtrTest (CTRTest key iv plaintext ciphertext) =
-    TestCase $ do
-      ctx <- newAESCtx Encrypt key iv
-      ct  <- aesCTR ctx plaintext
-      assertEqual "" ciphertext ct
-
-tests :: Test
-tests = TestList $ map runCtrTest ctrTests
+runCtrTest :: CTRTest -> IO ()
+runCtrTest (CTRTest key iv plaintext ciphertext) = do
+    ctx <- newAESCtx Encrypt key iv
+    ct  <- aesCTR ctx plaintext
+    assertEqual "" ciphertext ct
 
 main :: IO ()
-main = TF.defaultMain $ TF.hUnitTestToTests tests
+main =
+    mapM_ runCtrTest ctrTests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/Test/OpenSSL/DER.hs 
new/HsOpenSSL-0.11.3.2/Test/OpenSSL/DER.hs
--- old/HsOpenSSL-0.11.1.1/Test/OpenSSL/DER.hs  1970-01-01 01:00:00.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/Test/OpenSSL/DER.hs  2016-10-17 16:11:02.000000000 
+0200
@@ -0,0 +1,11 @@
+module Main (main) where
+
+import OpenSSL.RSA
+import OpenSSL.DER
+import Test.OpenSSL.TestUtils
+
+main :: IO ()
+main = do
+    keyPair <- generateRSAKey 1024 3 Nothing
+    pubKey <- rsaCopyPublic keyPair
+    assertEqual "encodeDecode" (Just pubKey) (fromDERPub (toDERPub keyPair))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/Test/OpenSSL/DSA.hs 
new/HsOpenSSL-0.11.3.2/Test/OpenSSL/DSA.hs
--- old/HsOpenSSL-0.11.1.1/Test/OpenSSL/DSA.hs  2015-01-06 08:36:45.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/Test/OpenSSL/DSA.hs  2016-10-17 16:11:02.000000000 
+0200
@@ -1,14 +1,13 @@
 module Main (main) where
+
 import qualified Data.ByteString as BS
 import OpenSSL.DSA
-import qualified Test.Framework as TF
-import qualified Test.Framework.Providers.HUnit as TF
-import Test.HUnit
+import Test.OpenSSL.TestUtils
 
 -- | This function just runs the example DSA generation, as given in FIP 186-2,
 --   app 5.
-test_generateParameters :: Test
-test_generateParameters = TestCase $ do
+test_generateParameters :: IO ()
+test_generateParameters = do
   let seed = BS.pack [0xd5, 0x01, 0x4e, 0x4b,
                       0x60, 0xef, 0x2b, 0xa8,
                       0xb6, 0x21, 0x1b, 0x40,
@@ -25,15 +24,14 @@
 testMessage :: BS.ByteString
 testMessage = BS.pack [1..20]
 
-test_signVerify :: Test
-test_signVerify = TestCase $ do
+test_signVerify :: IO ()
+test_signVerify = do
   dsa    <- generateDSAParametersAndKey 512 Nothing
   (a, b) <- signDigestedDataWithDSA dsa testMessage
   valid  <- verifyDigestedDataWithDSA dsa testMessage (a, b)
   assertBool "signVerify" valid
 
-tests :: Test
-tests = TestList [test_generateParameters, test_signVerify]
-
 main :: IO ()
-main = TF.defaultMain $ TF.hUnitTestToTests tests
+main = do
+    test_generateParameters
+    test_signVerify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/Test/OpenSSL/EVP/Base64.hs 
new/HsOpenSSL-0.11.3.2/Test/OpenSSL/EVP/Base64.hs
--- old/HsOpenSSL-0.11.1.1/Test/OpenSSL/EVP/Base64.hs   2015-01-06 
08:36:45.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/Test/OpenSSL/EVP/Base64.hs   2016-10-17 
16:11:02.000000000 +0200
@@ -9,9 +9,7 @@
 import qualified Data.ByteString as BS
 import qualified Data.ByteString.Lazy as BSL
 import OpenSSL.EVP.Base64
-import qualified Test.Framework as TF
-import qualified Test.Framework.Providers.HUnit as TF
-import Test.HUnit
+import Test.OpenSSL.TestUtils
 
 -- NOTE: bytestring-0.9.0.4 has these instances too, while
 -- bytestring-0.9.0.3 does not. If our bytestring is 0.9.0.4 we'll
@@ -26,10 +24,9 @@
   fromString = BSL.fromChunks . map (BS.singleton . fromIntegral . ord)
 #endif
 
-encodeTests :: Test
+encodeTests :: IO ()
 encodeTests =
-    TestLabel "encode" $
-    TestList $ map (\(a, v) -> encodeBase64BS a ~?= v) pairs
+    assertFunction "encodeBase64BS" encodeBase64BS pairs
     where
       pairs :: [(BS.ByteString, BS.ByteString)]
       pairs = [ (""   , ""    )
@@ -38,10 +35,9 @@
               , ("aaa", "YWFh")
               ]
 
-lazyEncodeTests :: Test
+lazyEncodeTests :: IO ()
 lazyEncodeTests =
-    TestLabel "lazyEncode" $
-    TestList $ map (\(a, v) -> encodeBase64LBS a ~?= v) pairs
+    assertFunction "encodeBase64LBS" encodeBase64LBS pairs
     where
       pairs :: [(BSL.ByteString, BSL.ByteString)]
       pairs = [ (""   , ""    )
@@ -50,10 +46,9 @@
               , ("aaa", "YWFh")
               ]
 
-decodeTests :: Test
+decodeTests :: IO ()
 decodeTests =
-    TestLabel "decode" $
-    TestList $ map (\(a, v) -> decodeBase64BS a ~?= v) pairs
+    assertFunction "decodeBase64BS" decodeBase64BS pairs
     where
       pairs :: [(BS.ByteString, BS.ByteString)]
       pairs = [ (""                  , ""           )
@@ -62,12 +57,8 @@
               , ("YWJjZGVmZ2hpams=\n", "abcdefghijk")
               ]
 
-tests :: Test
-tests = TestList
-        [ encodeTests
-        , lazyEncodeTests
-        , decodeTests
-        ]
-
 main :: IO ()
-main = TF.defaultMain $ TF.hUnitTestToTests tests
+main = do
+    encodeTests
+    lazyEncodeTests
+    decodeTests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/Test/OpenSSL/TestUtils.hs 
new/HsOpenSSL-0.11.3.2/Test/OpenSSL/TestUtils.hs
--- old/HsOpenSSL-0.11.1.1/Test/OpenSSL/TestUtils.hs    1970-01-01 
01:00:00.000000000 +0100
+++ new/HsOpenSSL-0.11.3.2/Test/OpenSSL/TestUtils.hs    2016-10-17 
16:11:02.000000000 +0200
@@ -0,0 +1,25 @@
+module Test.OpenSSL.TestUtils where
+
+import qualified Control.Exception as E
+import Control.Monad
+
+assertBool :: String -> Bool -> IO ()
+assertBool n ok =
+    unless ok $ E.throw $ E.AssertionFailed $ "Assertion failed: " ++ n
+
+assertEqual :: (Show a, Eq a) => String -> a -> a -> IO ()
+assertEqual n a b =
+    assertBool (n ++ "\n" ++ show a ++ " /= " ++ show b) (a == b)
+
+assertFunction
+    :: (Show x, Show y, Eq y) => String -> (x -> y) -> [(x, y)] -> IO ()
+assertFunction n f points =
+    forM_ points $ \ (x, y) ->
+        let r = f x in
+        assertBool
+            (n ++ " " ++ showsPrec 11 x "" ++ " == " ++ show r
+             ++ " /= " ++ show y)
+            (r == y)
+
+--  assertFunction "asdf" (fmap (+1)) [(Just 1, Nothing)]
+--  *** Exception: Assertion failed: asdf (Just 1) == Just 2 /= Nothing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/cbits/HsOpenSSL.c 
new/HsOpenSSL-0.11.3.2/cbits/HsOpenSSL.c
--- old/HsOpenSSL-0.11.1.1/cbits/HsOpenSSL.c    2015-01-06 08:36:45.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/cbits/HsOpenSSL.c    2016-10-17 16:11:02.000000000 
+0200
@@ -282,6 +282,15 @@
     return SSL_set_options(ssl, options);
 }
 
+/* OpenSSL < 1.0.0 does not have SSL_set_tlsext_host_name() */
+long HsOpenSSL_SSL_set_tlsext_host_name(SSL* ssl, char* host_name) {
+#if defined(SSL_set_tlsext_host_name)
+    return SSL_set_tlsext_host_name(ssl, host_name);
+#else
+    return 0;
+#endif
+}
+
 /* OpenSSL < 0.9.8m does not have SSL_clear_options() */
 long HsOpenSSL_SSL_clear_options(SSL* ssl, long options) {
 #if defined(SSL_clear_options)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/cbits/HsOpenSSL.h 
new/HsOpenSSL-0.11.3.2/cbits/HsOpenSSL.h
--- old/HsOpenSSL-0.11.1.1/cbits/HsOpenSSL.h    2015-01-06 08:36:45.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/cbits/HsOpenSSL.h    2016-10-17 16:11:02.000000000 
+0200
@@ -93,5 +93,6 @@
 long HsOpenSSL_SSL_CTX_clear_options(SSL_CTX* ctx, long options);
 long HsOpenSSL_SSL_set_options(SSL* ssl, long options);
 long HsOpenSSL_SSL_clear_options(SSL* ssl, long options);
+long HsOpenSSL_SSL_set_tlsext_host_name(SSL* ssl, char* host_name);
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/HsOpenSSL-0.11.1.1/examples/Makefile 
new/HsOpenSSL-0.11.3.2/examples/Makefile
--- old/HsOpenSSL-0.11.1.1/examples/Makefile    2015-01-06 08:36:45.000000000 
+0100
+++ new/HsOpenSSL-0.11.3.2/examples/Makefile    2016-10-17 16:11:02.000000000 
+0200
@@ -5,12 +5,13 @@
        ghc $(GHCFLAGS) --make HelloWorld
        ghc $(GHCFLAGS) --make PKCS7
        ghc $(GHCFLAGS) --make -threaded Server
+       ghc $(GHCFLAGS) --make Client
 
 run: build
        ./PKCS7
 #      ./HelloWorld
 
 clean:
-       rm -f HelloWorld GenRSAKey PKCS7 Server *.hi *.o
+       rm -f HelloWorld GenRSAKey PKCS7 Server Client *.hi *.o
 
 .PHONY: build run clean


Reply via email to