Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 422 lines (369 sloc) 18.555 kb
adb0b18 @phonohawk OpenSSL.PKCS7
authored
1 {- -*- haskell -*- -}
2
2e1ce26 @phonohawk I think I have entirely written the document.
authored
3 -- #prune
4
5 -- |An interface to PKCS#7 structure and S\/MIME message.
6
adb0b18 @phonohawk OpenSSL.PKCS7
authored
7 #include "HsOpenSSL.h"
8
9 module OpenSSL.PKCS7
2e1ce26 @phonohawk I think I have entirely written the document.
authored
10 ( -- * Types
11 Pkcs7
12 , PKCS7 -- private
adb0b18 @phonohawk OpenSSL.PKCS7
authored
13 , Pkcs7Flag(..)
2e1ce26 @phonohawk I think I have entirely written the document.
authored
14 , Pkcs7VerifyStatus(..)
581a78d @phonohawk ForeignPtr and Ptr should be encapsulated not to accept nullPtr from …
authored
15 , wrapPkcs7Ptr -- private
16 , withPkcs7Ptr -- private
adb0b18 @phonohawk OpenSSL.PKCS7
authored
17
2e1ce26 @phonohawk I think I have entirely written the document.
authored
18 -- * Encryption and Signing
adb0b18 @phonohawk OpenSSL.PKCS7
authored
19 , pkcs7Sign
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
20 , pkcs7Verify
21 , pkcs7Encrypt
22 , pkcs7Decrypt
adb0b18 @phonohawk OpenSSL.PKCS7
authored
23
2e1ce26 @phonohawk I think I have entirely written the document.
authored
24 -- * S\/MIME
adb0b18 @phonohawk OpenSSL.PKCS7
authored
25 , writeSmime
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
26 , readSmime
adb0b18 @phonohawk OpenSSL.PKCS7
authored
27 )
28 where
29
30 import Data.List
31 import Data.Traversable
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
32 import Data.Typeable
adb0b18 @phonohawk OpenSSL.PKCS7
authored
33 import Foreign
34 import Foreign.C
35 import OpenSSL.BIO
0f5a6a5 @phonohawk Added -Wall to the ghc-options.
authored
36 import OpenSSL.EVP.Cipher hiding (cipher)
adb0b18 @phonohawk OpenSSL.PKCS7
authored
37 import OpenSSL.EVP.PKey
b2c35c8 @mvv Moved all EVP-related private functions to OpenSSL.EVP.Internal.
mvv authored
38 import OpenSSL.EVP.Internal
adb0b18 @phonohawk OpenSSL.PKCS7
authored
39 import OpenSSL.Stack
40 import OpenSSL.Utils
41 import OpenSSL.X509
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
42 import OpenSSL.X509.Store
adb0b18 @phonohawk OpenSSL.PKCS7
authored
43
44
45 {- PKCS#7 -------------------------------------------------------------------- -}
46
2e1ce26 @phonohawk I think I have entirely written the document.
authored
47 -- |@'Pkcs7'@ represents an abstract PKCS#7 structure. The concrete
48 -- type of structure is hidden in the object: such polymorphism isn't
49 -- very haskellish but please get it out of your mind since OpenSSL is
50 -- written in C.
581a78d @phonohawk ForeignPtr and Ptr should be encapsulated not to accept nullPtr from …
authored
51 newtype Pkcs7 = Pkcs7 (ForeignPtr PKCS7)
2e1ce26 @phonohawk I think I have entirely written the document.
authored
52 data PKCS7
adb0b18 @phonohawk OpenSSL.PKCS7
authored
53
2e1ce26 @phonohawk I think I have entirely written the document.
authored
54 -- |@'Pkcs7Flag'@ is a set of flags that are used in many operations
55 -- related to PKCS#7.
adb0b18 @phonohawk OpenSSL.PKCS7
authored
56 data Pkcs7Flag = Pkcs7Text
57 | Pkcs7NoCerts
58 | Pkcs7NoSigs
59 | Pkcs7NoChain
60 | Pkcs7NoIntern
61 | Pkcs7NoVerify
62 | Pkcs7Detached
63 | Pkcs7Binary
64 | Pkcs7NoAttr
65 | Pkcs7NoSmimeCap
66 | Pkcs7NoOldMimeType
67 | Pkcs7CRLFEOL
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
68 deriving (Show, Eq, Typeable)
adb0b18 @phonohawk OpenSSL.PKCS7
authored
69
f070547 @phonohawk Fix breakage on 64-bit architectures.
authored
70 flagToInt :: Pkcs7Flag -> CInt
adb0b18 @phonohawk OpenSSL.PKCS7
authored
71 flagToInt Pkcs7Text = #const PKCS7_TEXT
72 flagToInt Pkcs7NoCerts = #const PKCS7_NOCERTS
73 flagToInt Pkcs7NoSigs = #const PKCS7_NOSIGS
74 flagToInt Pkcs7NoChain = #const PKCS7_NOCHAIN
75 flagToInt Pkcs7NoIntern = #const PKCS7_NOINTERN
76 flagToInt Pkcs7NoVerify = #const PKCS7_NOVERIFY
77 flagToInt Pkcs7Detached = #const PKCS7_DETACHED
78 flagToInt Pkcs7Binary = #const PKCS7_BINARY
79 flagToInt Pkcs7NoAttr = #const PKCS7_NOATTR
80 flagToInt Pkcs7NoSmimeCap = #const PKCS7_NOSMIMECAP
81 flagToInt Pkcs7NoOldMimeType = #const PKCS7_NOOLDMIMETYPE
82 flagToInt Pkcs7CRLFEOL = #const PKCS7_CRLFEOL
83
2e1ce26 @phonohawk I think I have entirely written the document.
authored
84 -- |@'Pkcs7VerifyStatus'@ represents a result of PKCS#7
85 -- verification. See 'pkcs7Verify'.
86 data Pkcs7VerifyStatus
87 = Pkcs7VerifySuccess (Maybe String) -- ^ Nothing if the PKCS#7
88 -- signature was a detached
89 -- signature, and @Just content@
90 -- if it wasn't.
91 | Pkcs7VerifyFailure
92 deriving (Show, Eq, Typeable)
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
93
94
f070547 @phonohawk Fix breakage on 64-bit architectures.
authored
95 flagListToInt :: [Pkcs7Flag] -> CInt
adb0b18 @phonohawk OpenSSL.PKCS7
authored
96 flagListToInt = foldl' (.|.) 0 . map flagToInt
97
98
99 foreign import ccall "&PKCS7_free"
100 _free :: FunPtr (Ptr PKCS7 -> IO ())
101
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
102 foreign import ccall "HsOpenSSL_PKCS7_is_detached"
103 _is_detached :: Ptr PKCS7 -> IO CLong
104
adb0b18 @phonohawk OpenSSL.PKCS7
authored
105 foreign import ccall "PKCS7_sign"
f070547 @phonohawk Fix breakage on 64-bit architectures.
authored
106 _sign :: Ptr X509_ -> Ptr EVP_PKEY -> Ptr STACK -> Ptr BIO_ -> CInt -> IO (Ptr PKCS7)
adb0b18 @phonohawk OpenSSL.PKCS7
authored
107
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
108 foreign import ccall "PKCS7_verify"
f070547 @phonohawk Fix breakage on 64-bit architectures.
authored
109 _verify :: Ptr PKCS7 -> Ptr STACK -> Ptr X509_STORE -> Ptr BIO_ -> Ptr BIO_ -> CInt -> IO CInt
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
110
111 foreign import ccall "PKCS7_encrypt"
f070547 @phonohawk Fix breakage on 64-bit architectures.
authored
112 _encrypt :: Ptr STACK -> Ptr BIO_ -> Ptr EVP_CIPHER -> CInt -> IO (Ptr PKCS7)
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
113
114 foreign import ccall "PKCS7_decrypt"
f070547 @phonohawk Fix breakage on 64-bit architectures.
authored
115 _decrypt :: Ptr PKCS7 -> Ptr EVP_PKEY -> Ptr X509_ -> Ptr BIO_ -> CInt -> IO CInt
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
116
adb0b18 @phonohawk OpenSSL.PKCS7
authored
117
581a78d @phonohawk ForeignPtr and Ptr should be encapsulated not to accept nullPtr from …
authored
118 wrapPkcs7Ptr :: Ptr PKCS7 -> IO Pkcs7
be44eaa @phonohawk Cosmetic changes suggested by hlint.
authored
119 wrapPkcs7Ptr = fmap Pkcs7 . newForeignPtr _free
581a78d @phonohawk ForeignPtr and Ptr should be encapsulated not to accept nullPtr from …
authored
120
121
122 withPkcs7Ptr :: Pkcs7 -> (Ptr PKCS7 -> IO a) -> IO a
123 withPkcs7Ptr (Pkcs7 pkcs7) = withForeignPtr pkcs7
adb0b18 @phonohawk OpenSSL.PKCS7
authored
124
125
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
126 isDetachedSignature :: Pkcs7 -> IO Bool
127 isDetachedSignature pkcs7
128 = withPkcs7Ptr pkcs7 $ \ pkcs7Ptr ->
be44eaa @phonohawk Cosmetic changes suggested by hlint.
authored
129 fmap (== 1) (_is_detached pkcs7Ptr)
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
130
131
5d1dd45 @phonohawk Increase type-safety of asymmetric key pairs.
authored
132 pkcs7Sign' :: KeyPair key => X509 -> key -> [X509] -> BIO -> [Pkcs7Flag] -> IO Pkcs7
adb0b18 @phonohawk OpenSSL.PKCS7
authored
133 pkcs7Sign' signCert pkey certs input flagList
581a78d @phonohawk ForeignPtr and Ptr should be encapsulated not to accept nullPtr from …
authored
134 = withX509Ptr signCert $ \ signCertPtr ->
5d1dd45 @phonohawk Increase type-safety of asymmetric key pairs.
authored
135 withPKeyPtr' pkey $ \ pkeyPtr ->
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
136 withX509Stack certs $ \ certStack ->
137 withBioPtr input $ \ inputPtr ->
138 _sign signCertPtr pkeyPtr certStack inputPtr (flagListToInt flagList)
139 >>= failIfNull
140 >>= wrapPkcs7Ptr
adb0b18 @phonohawk OpenSSL.PKCS7
authored
141
2e1ce26 @phonohawk I think I have entirely written the document.
authored
142 -- |@'pkcs7Sign'@ creates a PKCS#7 signedData structure.
5d1dd45 @phonohawk Increase type-safety of asymmetric key pairs.
authored
143 pkcs7Sign :: KeyPair key =>
144 X509 -- ^ certificate to sign with
145 -> key -- ^ corresponding private key
2e1ce26 @phonohawk I think I have entirely written the document.
authored
146 -> [X509] -- ^ optional additional set of certificates
147 -- to include in the PKCS#7 structure (for
148 -- example any intermediate CAs in the
149 -- chain)
150 -> String -- ^ data to be signed
151 -> [Pkcs7Flag] -- ^ An optional set of flags:
152 --
153 -- ['Pkcs7Text'] Many S\/MIME clients
154 -- expect the signed content to include
155 -- valid MIME headers. If the 'Pkcs7Text'
156 -- flag is set MIME headers for type
157 -- \"text\/plain\" are prepended to the
158 -- data.
159 --
160 -- ['Pkcs7NoCerts'] If 'Pkcs7NoCerts' is
161 -- set the signer's certificate will not be
162 -- included in the PKCS#7 structure, the
163 -- signer's certificate must still be
164 -- supplied in the parameter though. This
165 -- can reduce the size of the signature if
166 -- the signer's certificate can be obtained
167 -- by other means: for example a previously
168 -- signed message.
169 --
170 -- ['Pkcs7Detached'] The data being signed
171 -- is included in the PKCS#7 structure,
172 -- unless 'Pkcs7Detached' is set in which
173 -- case it is ommited. This is used for
174 -- PKCS#7 detached signatures which are
175 -- used in S\/MIME plaintext signed message
176 -- for example.
177 --
178 -- ['Pkcs7Binary'] Normally the supplied
179 -- content is translated into MIME
180 -- canonical format (as required by the
181 -- S\/MIME specifications) but if
182 -- 'Pkcs7Binary' is set no translation
183 -- occurs. This option should be uesd if
184 -- the supplied data is in binary format
185 -- otherwise the translation will corrupt
186 -- it.
187 --
188 -- ['Pkcs7NoAttr']
189 --
190 -- ['Pkcs7NoSmimeCap'] The signedData
191 -- structure includes several PKCS#7
192 -- authenticatedAttributes including the
193 -- signing time, the PKCS#7 content type
194 -- and the supported list of ciphers in an
195 -- SMIMECapabilities attribute. If
196 -- 'Pkcs7NoAttr' is set then no
197 -- authenticatedAttributes will be used. If
198 -- Pkcs7NoSmimeCap is set then just the
199 -- SMIMECapabilities are omitted.
200 -> IO Pkcs7
adb0b18 @phonohawk OpenSSL.PKCS7
authored
201 pkcs7Sign signCert pkey certs input flagList
202 = do mem <- newConstMem input
203 pkcs7Sign' signCert pkey certs mem flagList
204
205
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
206 pkcs7Verify' :: Pkcs7 -> [X509] -> X509Store -> Maybe BIO -> [Pkcs7Flag] -> IO (Maybe BIO, Bool)
207 pkcs7Verify' pkcs7 certs store inData flagList
208 = withPkcs7Ptr pkcs7 $ \ pkcs7Ptr ->
209 withX509Stack certs $ \ certStack ->
210 withX509StorePtr store $ \ storePtr ->
211 withBioPtr' inData $ \ inDataPtr ->
212 do isDetached <- isDetachedSignature pkcs7
213 outData <- if isDetached then
214 return Nothing
215 else
be44eaa @phonohawk Cosmetic changes suggested by hlint.
authored
216 fmap Just newMem
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
217 withBioPtr' outData $ \ outDataPtr ->
218 _verify pkcs7Ptr certStack storePtr inDataPtr outDataPtr (flagListToInt flagList)
219 >>= interpret outData
220 where
f070547 @phonohawk Fix breakage on 64-bit architectures.
authored
221 interpret :: Maybe BIO -> CInt -> IO (Maybe BIO, Bool)
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
222 interpret bio 1 = return (bio , True )
223 interpret _ _ = return (Nothing, False)
224
2e1ce26 @phonohawk I think I have entirely written the document.
authored
225 -- |@'pkcs7Verify'@ verifies a PKCS#7 signedData structure.
226 pkcs7Verify :: Pkcs7 -- ^ A PKCS#7 structure to verify.
227 -> [X509] -- ^ Set of certificates in which to
228 -- search for the signer's
229 -- certificate.
230 -> X509Store -- ^ Trusted certificate store (used
231 -- for chain verification).
232 -> Maybe String -- ^ Signed data if the content is not
233 -- present in the PKCS#7 structure
234 -- (that is it is detached).
235 -> [Pkcs7Flag] -- ^ An optional set of flags:
236 --
237 -- ['Pkcs7NoIntern'] If
238 -- 'Pkcs7NoIntern' is set the
239 -- certificates in the message itself
240 -- are not searched when locating the
241 -- signer's certificate. This means
242 -- that all the signers certificates
243 -- must be in the second argument
244 -- (['X509']).
245 --
246 -- ['Pkcs7Text'] If the 'Pkcs7Text'
247 -- flag is set MIME headers for type
248 -- \"text\/plain\" are deleted from
249 -- the content. If the content is not
250 -- of type \"text\/plain\" then an
251 -- error is returned.
252 --
253 -- ['Pkcs7NoVerify'] If
254 -- 'Pkcs7NoVerify' is set the
255 -- signer's certificates are not
256 -- chain verified.
257 --
258 -- ['Pkcs7NoChain'] If 'Pkcs7NoChain'
259 -- is set then the certificates
260 -- contained in the message are not
261 -- used as untrusted CAs. This means
262 -- that the whole verify chain (apart
263 -- from the signer's certificate)
264 -- must be contained in the trusted
265 -- store.
266 --
267 -- ['Pkcs7NoSigs'] If 'Pkcs7NoSigs'
268 -- is set then the signatures on the
269 -- data are not checked.
270 -> IO Pkcs7VerifyStatus
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
271 pkcs7Verify pkcs7 certs store inData flagList
272 = do inDataBio <- forM inData newConstMem
273 (outDataBio, isSuccess) <- pkcs7Verify' pkcs7 certs store inDataBio flagList
274 if isSuccess then
275 do outData <- forM outDataBio bioRead
2e1ce26 @phonohawk I think I have entirely written the document.
authored
276 return $ Pkcs7VerifySuccess outData
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
277 else
2e1ce26 @phonohawk I think I have entirely written the document.
authored
278 return Pkcs7VerifyFailure
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
279
280
2e1ce26 @phonohawk I think I have entirely written the document.
authored
281 pkcs7Encrypt' :: [X509] -> BIO -> Cipher -> [Pkcs7Flag] -> IO Pkcs7
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
282 pkcs7Encrypt' certs input cipher flagList
283 = withX509Stack certs $ \ certsPtr ->
284 withBioPtr input $ \ inputPtr ->
285 withCipherPtr cipher $ \ cipherPtr ->
286 _encrypt certsPtr inputPtr cipherPtr (flagListToInt flagList)
287 >>= failIfNull
288 >>= wrapPkcs7Ptr
289
2e1ce26 @phonohawk I think I have entirely written the document.
authored
290 -- |@'pkcs7Encrypt'@ creates a PKCS#7 envelopedData structure.
291 pkcs7Encrypt :: [X509] -- ^ A list of recipient certificates.
292 -> String -- ^ The content to be encrypted.
293 -> Cipher -- ^ The symmetric cipher to use.
294 -> [Pkcs7Flag] -- ^ An optional set of flags:
295 --
296 -- ['Pkcs7Text'] If the 'Pkcs7Text' flag
297 -- is set MIME headers for type
298 -- \"text\/plain\" are prepended to the
299 -- data.
300 --
301 -- ['Pkcs7Binary'] Normally the supplied
302 -- content is translated into MIME
303 -- canonical format (as required by the
304 -- S\/MIME specifications) if
305 -- 'Pkcs7Binary' is set no translation
306 -- occurs. This option should be used if
307 -- the supplied data is in binary format
308 -- otherwise the translation will
309 -- corrupt it. If 'Pkcs7Binary' is set
310 -- then 'Pkcs7Text' is ignored.
311 -> IO Pkcs7
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
312 pkcs7Encrypt certs input cipher flagList
313 = do mem <- newConstMem input
314 pkcs7Encrypt' certs mem cipher flagList
315
316
5d1dd45 @phonohawk Increase type-safety of asymmetric key pairs.
authored
317 pkcs7Decrypt' :: KeyPair key => Pkcs7 -> key -> X509 -> BIO -> [Pkcs7Flag] -> IO ()
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
318 pkcs7Decrypt' pkcs7 pkey cert output flagList
319 = withPkcs7Ptr pkcs7 $ \ pkcs7Ptr ->
5d1dd45 @phonohawk Increase type-safety of asymmetric key pairs.
authored
320 withPKeyPtr' pkey $ \ pkeyPtr ->
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
321 withX509Ptr cert $ \ certPtr ->
322 withBioPtr output $ \ outputPtr ->
323 _decrypt pkcs7Ptr pkeyPtr certPtr outputPtr (flagListToInt flagList)
324 >>= failIf (/= 1)
325 >> return ()
326
2e1ce26 @phonohawk I think I have entirely written the document.
authored
327 -- |@'pkcs7Decrypt'@ decrypts content from PKCS#7 envelopedData
328 -- structure.
5d1dd45 @phonohawk Increase type-safety of asymmetric key pairs.
authored
329 pkcs7Decrypt :: KeyPair key =>
330 Pkcs7 -- ^ The PKCS#7 structure to decrypt.
331 -> key -- ^ The private key of the recipient.
2e1ce26 @phonohawk I think I have entirely written the document.
authored
332 -> X509 -- ^ The recipient's certificate.
333 -> [Pkcs7Flag] -- ^ An optional set of flags:
334 --
335 -- ['Pkcs7Text'] If the 'Pkcs7Text' flag
336 -- is set MIME headers for type
337 -- \"text\/plain\" are deleted from the
338 -- content. If the content is not of
339 -- type \"text\/plain\" then an error is
340 -- thrown.
341 -> IO String -- ^ The decrypted content.
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
342 pkcs7Decrypt pkcs7 pkey cert flagList
343 = do mem <- newMem
344 pkcs7Decrypt' pkcs7 pkey cert mem flagList
345 bioRead mem
346
347
adb0b18 @phonohawk OpenSSL.PKCS7
authored
348 {- S/MIME -------------------------------------------------------------------- -}
349
350 foreign import ccall unsafe "SMIME_write_PKCS7"
f070547 @phonohawk Fix breakage on 64-bit architectures.
authored
351 _SMIME_write_PKCS7 :: Ptr BIO_ -> Ptr PKCS7 -> Ptr BIO_ -> CInt -> IO CInt
adb0b18 @phonohawk OpenSSL.PKCS7
authored
352
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
353 foreign import ccall unsafe "SMIME_read_PKCS7"
354 _SMIME_read_PKCS7 :: Ptr BIO_ -> Ptr (Ptr BIO_) -> IO (Ptr PKCS7)
355
2e1ce26 @phonohawk I think I have entirely written the document.
authored
356 -- |@'writeSmime'@ writes PKCS#7 structure to S\/MIME message.
357 writeSmime :: Pkcs7 -- ^ A PKCS#7 structure to be written.
358 -> Maybe String -- ^ If cleartext signing
359 -- (multipart\/signed) is being used then
360 -- the signed data must be supplied here.
361 -> [Pkcs7Flag] -- ^ An optional set of flags:
362 --
363 -- ['Pkcs7Detached'] If 'Pkcs7Detached'
364 -- is set then cleartext signing will be
365 -- used, this option only makes sense for
366 -- signedData where 'Pkcs7Detached' is
367 -- also set when 'pkcs7Sign' is also
368 -- called.
369 --
370 -- ['Pkcs7Text'] If the 'Pkcs7Text' flag
371 -- is set MIME headers for type
372 -- \"text\/plain\" are added to the
373 -- content, this only makes sense if
374 -- 'Pkcs7Detached' is also set.
375 -> IO String -- ^ The result S\/MIME message.
adb0b18 @phonohawk OpenSSL.PKCS7
authored
376 writeSmime pkcs7 dataStr flagList
377 = do outBio <- newMem
378 dataBio <- forM dataStr newConstMem
379 writeSmime' outBio pkcs7 dataBio flagList
380 bioRead outBio
381
382
383 writeSmime' :: BIO -> Pkcs7 -> Maybe BIO -> [Pkcs7Flag] -> IO ()
384 writeSmime' outBio pkcs7 dataBio flagList
581a78d @phonohawk ForeignPtr and Ptr should be encapsulated not to accept nullPtr from …
authored
385 = withBioPtr outBio $ \ outBioPtr ->
386 withPkcs7Ptr pkcs7 $ \ pkcs7Ptr ->
387 withBioPtr' dataBio $ \ dataBioPtr ->
adb0b18 @phonohawk OpenSSL.PKCS7
authored
388 _SMIME_write_PKCS7 outBioPtr pkcs7Ptr dataBioPtr (flagListToInt flagList)
389 >>= failIf (/= 1)
581a78d @phonohawk ForeignPtr and Ptr should be encapsulated not to accept nullPtr from …
authored
390 >> return ()
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
391
2e1ce26 @phonohawk I think I have entirely written the document.
authored
392 -- |@'readSmime'@ parses S\/MIME message.
393 readSmime :: String -- ^ The message to be read.
394 -> IO (Pkcs7, Maybe String) -- ^ (The result PKCS#7
395 -- structure, @Just content@
396 -- if the PKCS#7 structure was
397 -- a cleartext signature and
398 -- @Nothing@ if it wasn't.)
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
399 readSmime input
400 = do inBio <- newConstMem input
401 (pkcs7, outBio) <- readSmime' inBio
402 output <- forM outBio bioRead
403 return (pkcs7, output)
404
405
406 readSmime' :: BIO -> IO (Pkcs7, Maybe BIO)
407 readSmime' inBio
408 = withBioPtr inBio $ \ inBioPtr ->
409 alloca $ \ outBioPtrPtr ->
410 do poke outBioPtrPtr nullPtr
411
412 pkcs7 <- _SMIME_read_PKCS7 inBioPtr outBioPtrPtr
413 >>= failIfNull
414 >>= wrapPkcs7Ptr
415 outBioPtr <- peek outBioPtrPtr
416 outBio <- if outBioPtr == nullPtr then
417 return Nothing
418 else
be44eaa @phonohawk Cosmetic changes suggested by hlint.
authored
419 fmap Just (wrapBioPtr outBioPtr)
2fb4c2a @phonohawk PKCS#7 (en|de)cryption
authored
420
421 return (pkcs7, outBio)
Something went wrong with that request. Please try again.