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 PHO OpenSSL.PKCS7
authored
1 {- -*- haskell -*- -}
2
2e1ce26 PHO 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 PHO OpenSSL.PKCS7
authored
7 #include "HsOpenSSL.h"
8
9 module OpenSSL.PKCS7
2e1ce26 PHO I think I have entirely written the document.
authored
10 ( -- * Types
11 Pkcs7
12 , PKCS7 -- private
adb0b18 PHO OpenSSL.PKCS7
authored
13 , Pkcs7Flag(..)
2e1ce26 PHO I think I have entirely written the document.
authored
14 , Pkcs7VerifyStatus(..)
581a78d PHO ForeignPtr and Ptr should be encapsulated not to accept nullPtr from use...
authored
15 , wrapPkcs7Ptr -- private
16 , withPkcs7Ptr -- private
adb0b18 PHO OpenSSL.PKCS7
authored
17
2e1ce26 PHO I think I have entirely written the document.
authored
18 -- * Encryption and Signing
adb0b18 PHO OpenSSL.PKCS7
authored
19 , pkcs7Sign
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
20 , pkcs7Verify
21 , pkcs7Encrypt
22 , pkcs7Decrypt
adb0b18 PHO OpenSSL.PKCS7
authored
23
2e1ce26 PHO I think I have entirely written the document.
authored
24 -- * S\/MIME
adb0b18 PHO OpenSSL.PKCS7
authored
25 , writeSmime
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
26 , readSmime
adb0b18 PHO OpenSSL.PKCS7
authored
27 )
28 where
29
30 import Data.List
31 import Data.Traversable
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
32 import Data.Typeable
adb0b18 PHO OpenSSL.PKCS7
authored
33 import Foreign
34 import Foreign.C
35 import OpenSSL.BIO
0f5a6a5 PHO Added -Wall to the ghc-options.
authored
36 import OpenSSL.EVP.Cipher hiding (cipher)
adb0b18 PHO OpenSSL.PKCS7
authored
37 import OpenSSL.EVP.PKey
b2c35c8 Mikhail Vorozhtsov Moved all EVP-related private functions to OpenSSL.EVP.Internal.
mvv authored
38 import OpenSSL.EVP.Internal
adb0b18 PHO OpenSSL.PKCS7
authored
39 import OpenSSL.Stack
40 import OpenSSL.Utils
41 import OpenSSL.X509
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
42 import OpenSSL.X509.Store
adb0b18 PHO OpenSSL.PKCS7
authored
43
44
45 {- PKCS#7 -------------------------------------------------------------------- -}
46
2e1ce26 PHO 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 PHO ForeignPtr and Ptr should be encapsulated not to accept nullPtr from use...
authored
51 newtype Pkcs7 = Pkcs7 (ForeignPtr PKCS7)
2e1ce26 PHO I think I have entirely written the document.
authored
52 data PKCS7
adb0b18 PHO OpenSSL.PKCS7
authored
53
2e1ce26 PHO 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 PHO 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 PHO PKCS#7 (en|de)cryption
authored
68 deriving (Show, Eq, Typeable)
adb0b18 PHO OpenSSL.PKCS7
authored
69
f070547 PHO Fix breakage on 64-bit architectures.
authored
70 flagToInt :: Pkcs7Flag -> CInt
adb0b18 PHO 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 PHO 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 PHO PKCS#7 (en|de)cryption
authored
93
94
f070547 PHO Fix breakage on 64-bit architectures.
authored
95 flagListToInt :: [Pkcs7Flag] -> CInt
adb0b18 PHO 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 PHO PKCS#7 (en|de)cryption
authored
102 foreign import ccall "HsOpenSSL_PKCS7_is_detached"
103 _is_detached :: Ptr PKCS7 -> IO CLong
104
adb0b18 PHO OpenSSL.PKCS7
authored
105 foreign import ccall "PKCS7_sign"
f070547 PHO Fix breakage on 64-bit architectures.
authored
106 _sign :: Ptr X509_ -> Ptr EVP_PKEY -> Ptr STACK -> Ptr BIO_ -> CInt -> IO (Ptr PKCS7)
adb0b18 PHO OpenSSL.PKCS7
authored
107
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
108 foreign import ccall "PKCS7_verify"
f070547 PHO Fix breakage on 64-bit architectures.
authored
109 _verify :: Ptr PKCS7 -> Ptr STACK -> Ptr X509_STORE -> Ptr BIO_ -> Ptr BIO_ -> CInt -> IO CInt
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
110
111 foreign import ccall "PKCS7_encrypt"
f070547 PHO Fix breakage on 64-bit architectures.
authored
112 _encrypt :: Ptr STACK -> Ptr BIO_ -> Ptr EVP_CIPHER -> CInt -> IO (Ptr PKCS7)
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
113
114 foreign import ccall "PKCS7_decrypt"
f070547 PHO Fix breakage on 64-bit architectures.
authored
115 _decrypt :: Ptr PKCS7 -> Ptr EVP_PKEY -> Ptr X509_ -> Ptr BIO_ -> CInt -> IO CInt
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
116
adb0b18 PHO OpenSSL.PKCS7
authored
117
581a78d PHO ForeignPtr and Ptr should be encapsulated not to accept nullPtr from use...
authored
118 wrapPkcs7Ptr :: Ptr PKCS7 -> IO Pkcs7
be44eaa PHO Cosmetic changes suggested by hlint.
authored
119 wrapPkcs7Ptr = fmap Pkcs7 . newForeignPtr _free
581a78d PHO ForeignPtr and Ptr should be encapsulated not to accept nullPtr from use...
authored
120
121
122 withPkcs7Ptr :: Pkcs7 -> (Ptr PKCS7 -> IO a) -> IO a
123 withPkcs7Ptr (Pkcs7 pkcs7) = withForeignPtr pkcs7
adb0b18 PHO OpenSSL.PKCS7
authored
124
125
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
126 isDetachedSignature :: Pkcs7 -> IO Bool
127 isDetachedSignature pkcs7
128 = withPkcs7Ptr pkcs7 $ \ pkcs7Ptr ->
be44eaa PHO Cosmetic changes suggested by hlint.
authored
129 fmap (== 1) (_is_detached pkcs7Ptr)
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
130
131
5d1dd45 PHO Increase type-safety of asymmetric key pairs.
authored
132 pkcs7Sign' :: KeyPair key => X509 -> key -> [X509] -> BIO -> [Pkcs7Flag] -> IO Pkcs7
adb0b18 PHO OpenSSL.PKCS7
authored
133 pkcs7Sign' signCert pkey certs input flagList
581a78d PHO ForeignPtr and Ptr should be encapsulated not to accept nullPtr from use...
authored
134 = withX509Ptr signCert $ \ signCertPtr ->
5d1dd45 PHO Increase type-safety of asymmetric key pairs.
authored
135 withPKeyPtr' pkey $ \ pkeyPtr ->
2fb4c2a PHO 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 PHO OpenSSL.PKCS7
authored
141
2e1ce26 PHO I think I have entirely written the document.
authored
142 -- |@'pkcs7Sign'@ creates a PKCS#7 signedData structure.
5d1dd45 PHO Increase type-safety of asymmetric key pairs.
authored
143 pkcs7Sign :: KeyPair key =>
144 X509 -- ^ certificate to sign with
145 -> key -- ^ corresponding private key
2e1ce26 PHO 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 PHO 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 PHO 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 PHO Cosmetic changes suggested by hlint.
authored
216 fmap Just newMem
2fb4c2a PHO 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 PHO Fix breakage on 64-bit architectures.
authored
221 interpret :: Maybe BIO -> CInt -> IO (Maybe BIO, Bool)
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
222 interpret bio 1 = return (bio , True )
223 interpret _ _ = return (Nothing, False)
224
2e1ce26 PHO 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 PHO 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 PHO I think I have entirely written the document.
authored
276 return $ Pkcs7VerifySuccess outData
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
277 else
2e1ce26 PHO I think I have entirely written the document.
authored
278 return Pkcs7VerifyFailure
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
279
280
2e1ce26 PHO I think I have entirely written the document.
authored
281 pkcs7Encrypt' :: [X509] -> BIO -> Cipher -> [Pkcs7Flag] -> IO Pkcs7
2fb4c2a PHO 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 PHO 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 PHO 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 PHO Increase type-safety of asymmetric key pairs.
authored
317 pkcs7Decrypt' :: KeyPair key => Pkcs7 -> key -> X509 -> BIO -> [Pkcs7Flag] -> IO ()
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
318 pkcs7Decrypt' pkcs7 pkey cert output flagList
319 = withPkcs7Ptr pkcs7 $ \ pkcs7Ptr ->
5d1dd45 PHO Increase type-safety of asymmetric key pairs.
authored
320 withPKeyPtr' pkey $ \ pkeyPtr ->
2fb4c2a PHO 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 PHO I think I have entirely written the document.
authored
327 -- |@'pkcs7Decrypt'@ decrypts content from PKCS#7 envelopedData
328 -- structure.
5d1dd45 PHO 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 PHO 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 PHO 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 PHO OpenSSL.PKCS7
authored
348 {- S/MIME -------------------------------------------------------------------- -}
349
350 foreign import ccall unsafe "SMIME_write_PKCS7"
f070547 PHO Fix breakage on 64-bit architectures.
authored
351 _SMIME_write_PKCS7 :: Ptr BIO_ -> Ptr PKCS7 -> Ptr BIO_ -> CInt -> IO CInt
adb0b18 PHO OpenSSL.PKCS7
authored
352
2fb4c2a PHO 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 PHO 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 PHO 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 PHO ForeignPtr and Ptr should be encapsulated not to accept nullPtr from use...
authored
385 = withBioPtr outBio $ \ outBioPtr ->
386 withPkcs7Ptr pkcs7 $ \ pkcs7Ptr ->
387 withBioPtr' dataBio $ \ dataBioPtr ->
adb0b18 PHO OpenSSL.PKCS7
authored
388 _SMIME_write_PKCS7 outBioPtr pkcs7Ptr dataBioPtr (flagListToInt flagList)
389 >>= failIf (/= 1)
581a78d PHO ForeignPtr and Ptr should be encapsulated not to accept nullPtr from use...
authored
390 >> return ()
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
391
2e1ce26 PHO 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 PHO 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 PHO Cosmetic changes suggested by hlint.
authored
419 fmap Just (wrapBioPtr outBioPtr)
2fb4c2a PHO PKCS#7 (en|de)cryption
authored
420
421 return (pkcs7, outBio)
Something went wrong with that request. Please try again.