File: ASN1.hsc

package info (click to toggle)
haskell-hsopenssl 0.11.7.8-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 556 kB
  • sloc: haskell: 1,562; ansic: 451; makefile: 16
file content (152 lines) | stat: -rw-r--r-- 4,548 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
{-# LANGUAGE CPP #-}
{-# LANGUAGE EmptyDataDecls           #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE CApiFFI #-}
module OpenSSL.ASN1
    ( ASN1_OBJECT
    , obj2nid
    , nid2sn
    , nid2ln

    , ASN1_STRING
    , peekASN1String

    , ASN1_INTEGER
    , peekASN1Integer
    , withASN1Integer

    , ASN1_TIME
    , peekASN1Time
    , withASN1Time
    )
    where
#include "HsOpenSSL.h"
import           Control.Exception
import           Data.Time.Clock
import           Data.Time.Clock.POSIX
import           Data.Time.Format
import           Foreign
import           Foreign.C
import           OpenSSL.BIO
import           OpenSSL.BN
import           OpenSSL.Utils

#if !MIN_VERSION_time(1,5,0)
import System.Locale
#endif

{- ASN1_OBJECT --------------------------------------------------------------- -}

data {-# CTYPE "openssl/asn1.h" "ASN1_OBJECT" #-} ASN1_OBJECT

foreign import capi unsafe "openssl/objects.h OBJ_obj2nid"
        obj2nid :: Ptr ASN1_OBJECT -> IO CInt

foreign import capi unsafe "openssl/objects.h OBJ_nid2sn"
        _nid2sn :: CInt -> IO CString

foreign import capi unsafe "openssl/objects.h OBJ_nid2ln"
        _nid2ln :: CInt -> IO CString


nid2sn :: CInt -> IO String
nid2sn nid = _nid2sn nid >>= peekCString


nid2ln :: CInt -> IO String
nid2ln nid = _nid2ln nid >>= peekCString


{- ASN1_STRING --------------------------------------------------------------- -}

data {-# CTYPE "openssl/asn1.h" "ASN1_STRING" #-} ASN1_STRING

peekASN1String :: Ptr ASN1_STRING -> IO String
peekASN1String strPtr
    = do buf <- (#peek ASN1_STRING, data  ) strPtr
         len <- (#peek ASN1_STRING, length) strPtr :: IO CInt
         peekCStringLen (buf, fromIntegral len)


{- ASN1_INTEGER -------------------------------------------------------------- -}

data {-# CTYPE "openssl/asn1.h" "ASN1_INTEGER" #-} ASN1_INTEGER

foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_M_ASN1_INTEGER_new"
        _ASN1_INTEGER_new :: IO (Ptr ASN1_INTEGER)

foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_M_ASN1_INTEGER_free"
        _ASN1_INTEGER_free :: Ptr ASN1_INTEGER -> IO ()

foreign import capi unsafe "openssl/asn1.h ASN1_INTEGER_to_BN"
        _ASN1_INTEGER_to_BN :: Ptr ASN1_INTEGER -> Ptr BIGNUM -> IO (Ptr BIGNUM)

foreign import capi unsafe "openssl/asn1.h BN_to_ASN1_INTEGER"
        _BN_to_ASN1_INTEGER :: Ptr BIGNUM -> Ptr ASN1_INTEGER -> IO (Ptr ASN1_INTEGER)


peekASN1Integer :: Ptr ASN1_INTEGER -> IO Integer
peekASN1Integer intPtr
    = allocaBN $ \ bn ->
      do _ASN1_INTEGER_to_BN intPtr (unwrapBN bn)
              >>= failIfNull_
         peekBN bn


allocaASN1Integer :: (Ptr ASN1_INTEGER -> IO a) -> IO a
allocaASN1Integer
    = bracket _ASN1_INTEGER_new _ASN1_INTEGER_free


withASN1Integer :: Integer -> (Ptr ASN1_INTEGER -> IO a) -> IO a
withASN1Integer int m
    = withBN int $ \ bn ->
      allocaASN1Integer $ \ intPtr ->
      do _BN_to_ASN1_INTEGER (unwrapBN bn) intPtr
              >>= failIfNull_
         m intPtr


{- ASN1_TIME ---------------------------------------------------------------- -}

data {-# CTYPE "openssl/asn1.h" "ASN1_TIME" #-} ASN1_TIME

foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_M_ASN1_TIME_new"
        _ASN1_TIME_new :: IO (Ptr ASN1_TIME)

foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_M_ASN1_TIME_free"
        _ASN1_TIME_free :: Ptr ASN1_TIME -> IO ()

foreign import capi unsafe "openssl/asn1.h ASN1_TIME_set"
        _ASN1_TIME_set :: Ptr ASN1_TIME -> CTime -> IO (Ptr ASN1_TIME)

foreign import capi unsafe "openssl/asn1.h ASN1_TIME_print"
        _ASN1_TIME_print :: Ptr BIO_ -> Ptr ASN1_TIME -> IO CInt


peekASN1Time :: Ptr ASN1_TIME -> IO UTCTime -- asn1/t_x509.c
peekASN1Time time
    = do bio <- newMem
         withBioPtr bio $ \ bioPtr ->
             _ASN1_TIME_print bioPtr time
                  >>= failIf_ (/= 1)
         timeStr <- bioRead bio
#if MIN_VERSION_time(1,5,0)
         case parseTimeM True defaultTimeLocale "%b %e %H:%M:%S %Y %Z" timeStr of
#else
         case parseTime defaultTimeLocale "%b %e %H:%M:%S %Y %Z" timeStr of
#endif
           Just utc -> return utc
           Nothing  -> fail ("peekASN1Time: failed to parse time string: " ++ timeStr)

allocaASN1Time :: (Ptr ASN1_TIME -> IO a) -> IO a
allocaASN1Time
    = bracket _ASN1_TIME_new _ASN1_TIME_free


withASN1Time :: UTCTime -> (Ptr ASN1_TIME -> IO a) -> IO a
withASN1Time utc m
    = allocaASN1Time $ \ time ->
      do _ASN1_TIME_set time (fromIntegral (round $ utcTimeToPOSIXSeconds utc :: Integer))
              >>= failIfNull_
         m time