diff options
Diffstat (limited to 'lib/Compat.hs')
-rw-r--r-- | lib/Compat.hs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/lib/Compat.hs b/lib/Compat.hs new file mode 100644 index 0000000..3b77851 --- /dev/null +++ b/lib/Compat.hs | |||
@@ -0,0 +1,58 @@ | |||
1 | {-# LANGUAGE CPP #-} | ||
2 | module Compat where | ||
3 | |||
4 | import Data.Bits | ||
5 | import Data.Word | ||
6 | import Data.ASN1.Types | ||
7 | import Data.ASN1.Encoding | ||
8 | import Data.ASN1.BinaryEncoding | ||
9 | import Crypto.PubKey.RSA as RSA | ||
10 | |||
11 | #if defined(VERSION_cryptonite) | ||
12 | |||
13 | instance ASN1Object PublicKey where | ||
14 | toASN1 pubKey = \xs -> Start Sequence | ||
15 | : IntVal (public_n pubKey) | ||
16 | : IntVal (public_e pubKey) | ||
17 | : End Sequence | ||
18 | : xs | ||
19 | fromASN1 (Start Sequence:IntVal smodulus:IntVal pubexp:End Sequence:xs) = | ||
20 | Right (PublicKey { public_size = calculate_modulus modulus 1 | ||
21 | , public_n = modulus | ||
22 | , public_e = pubexp | ||
23 | } | ||
24 | , xs) | ||
25 | where calculate_modulus n i = if (2 ^ (i * 8)) > n then i else calculate_modulus n (i+1) | ||
26 | -- some bad implementation will not serialize ASN.1 integer properly, leading | ||
27 | -- to negative modulus. if that's the case, we correct it. | ||
28 | modulus = toPositive smodulus | ||
29 | fromASN1 ( Start Sequence | ||
30 | : IntVal 0 | ||
31 | : Start Sequence | ||
32 | : OID [1, 2, 840, 113549, 1, 1, 1] | ||
33 | : Null | ||
34 | : End Sequence | ||
35 | : OctetString bs | ||
36 | : xs | ||
37 | ) = let inner = either strError fromASN1 $ decodeASN1' BER bs | ||
38 | strError = Left . | ||
39 | ("fromASN1: RSA.PublicKey: " ++) . show | ||
40 | in either Left (\(k, _) -> Right (k, xs)) inner | ||
41 | fromASN1 _ = | ||
42 | Left "fromASN1: RSA.PublicKey: unexpected format" | ||
43 | |||
44 | #endif | ||
45 | |||
46 | toPositive :: Integer -> Integer | ||
47 | toPositive int | ||
48 | | int < 0 = uintOfBytes $ bytesOfInt int | ||
49 | | otherwise = int | ||
50 | where uintOfBytes = foldl (\acc n -> (acc `shiftL` 8) + fromIntegral n) 0 | ||
51 | bytesOfInt :: Integer -> [Word8] | ||
52 | bytesOfInt n = if testBit (head nints) 7 then nints else 0xff : nints | ||
53 | where nints = reverse $ plusOne $ reverse $ map complement $ bytesOfUInt (abs n) | ||
54 | plusOne [] = [1] | ||
55 | plusOne (x:xs) = if x == 0xff then 0 : plusOne xs else (x+1) : xs | ||
56 | bytesOfUInt x = reverse (list x) | ||
57 | where list i = if i <= 0xff then [fromIntegral i] else (fromIntegral i .&. 0xff) : list (i `shiftR` 8) | ||
58 | |||