diff options
author | Stephen Paul Weber <singpolyma@singpolyma.net> | 2012-04-24 16:03:21 -0500 |
---|---|---|
committer | Stephen Paul Weber <singpolyma@singpolyma.net> | 2012-04-24 16:03:21 -0500 |
commit | d13c748885a3d637ee659b94892e1622127e67a6 (patch) | |
tree | 44e606b6eee362cdfd2301f08ffa501bb350385a /Data | |
parent | 31e12ded73e1bf58ab565e99ab32884cde8e2c8e (diff) |
actually handle encoding s2k count
Diffstat (limited to 'Data')
-rw-r--r-- | Data/OpenPGP.hs | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/Data/OpenPGP.hs b/Data/OpenPGP.hs index 233ff68..3e3eb9e 100644 --- a/Data/OpenPGP.hs +++ b/Data/OpenPGP.hs | |||
@@ -3,7 +3,7 @@ | |||
3 | -- The recommended way to import this module is: | 3 | -- The recommended way to import this module is: |
4 | -- | 4 | -- |
5 | -- > import qualified Data.OpenPGP as OpenPGP | 5 | -- > import qualified Data.OpenPGP as OpenPGP |
6 | module Data.OpenPGP (Message(..), Packet(..), SignatureSubpacket(..), HashAlgorithm(..), KeyAlgorithm(..), CompressionAlgorithm(..), MPI(..), fingerprint_material, signatures_and_data, signature_issuer, calculate_signature_trailer) where | 6 | module Data.OpenPGP (Message(..), Packet(..), SignatureSubpacket(..), HashAlgorithm(..), KeyAlgorithm(..), CompressionAlgorithm(..), MPI(..), fingerprint_material, signatures_and_data, signature_issuer, calculate_signature_trailer, decode_s2k_count, encode_s2k_count) where |
7 | 7 | ||
8 | import Control.Monad | 8 | import Control.Monad |
9 | import Data.Bits | 9 | import Data.Bits |
@@ -58,7 +58,7 @@ data Packet = | |||
58 | s2k_type::Word8, | 58 | s2k_type::Word8, |
59 | s2k_hash_algorithm::HashAlgorithm, | 59 | s2k_hash_algorithm::HashAlgorithm, |
60 | s2k_salt::Word64, | 60 | s2k_salt::Word64, |
61 | s2k_count::Word8, | 61 | s2k_count::Word32, |
62 | encrypted_data::LZ.ByteString, | 62 | encrypted_data::LZ.ByteString, |
63 | private_hash::Maybe LZ.ByteString -- the hash may be in the encrypted data | 63 | private_hash::Maybe LZ.ByteString -- the hash may be in the encrypted data |
64 | } | | 64 | } | |
@@ -214,12 +214,13 @@ put_packet (SecretKeyPacket { version = version, timestamp = timestamp, | |||
214 | s2k_type = s2k_type, | 214 | s2k_type = s2k_type, |
215 | s2k_hash_algorithm = s2k_hash_algo, | 215 | s2k_hash_algorithm = s2k_hash_algo, |
216 | s2k_salt = s2k_salt, | 216 | s2k_salt = s2k_salt, |
217 | s2k_count = s2k_count, | ||
217 | encrypted_data = encrypted_data }) = | 218 | encrypted_data = encrypted_data }) = |
218 | (LZ.concat $ [p, encode s2k_useage] ++ | 219 | (LZ.concat $ [p, encode s2k_useage] ++ |
219 | (if s2k_useage `elem` [255, 254] then | 220 | (if s2k_useage `elem` [255, 254] then |
220 | -- TODO: if s2k_type == 3 reverse ugly bit manipulation | ||
221 | [encode symmetric_type, encode s2k_type, encode s2k_hash_algo] ++ | 221 | [encode symmetric_type, encode s2k_type, encode s2k_hash_algo] ++ |
222 | if s2k_type `elem` [1, 3] then [encode s2k_salt] else [] | 222 | (if s2k_type `elem` [1, 3] then [encode s2k_salt] else []) ++ |
223 | if s2k_type == 3 then [encode $ encode_s2k_count s2k_count] else [] | ||
223 | else []) ++ | 224 | else []) ++ |
224 | (if s2k_useage > 0 then | 225 | (if s2k_useage > 0 then |
225 | [encrypted_data] | 226 | [encrypted_data] |
@@ -324,11 +325,8 @@ parse_packet 5 = do | |||
324 | s2k_hash_algorithm <- get | 325 | s2k_hash_algorithm <- get |
325 | s2k_salt <- if s2k_type `elem` [1, 3] then get | 326 | s2k_salt <- if s2k_type `elem` [1, 3] then get |
326 | else return undefined | 327 | else return undefined |
327 | s2k_count <- if s2k_type == 3 then do | 328 | s2k_count <- if s2k_type == 3 then fmap decode_s2k_count get else |
328 | c <- fmap fromIntegral (get :: Get Word8) | 329 | return undefined |
329 | return $ fromIntegral $ | ||
330 | (16 + (c .&. 15)) `shiftL` ((c `shiftR` 4) + 6) | ||
331 | else return undefined | ||
332 | return (k symmetric_type s2k_type s2k_hash_algorithm | 330 | return (k symmetric_type s2k_type s2k_hash_algorithm |
333 | s2k_salt s2k_count) | 331 | s2k_salt s2k_count) |
334 | _ | s2k_useage > 0 -> | 332 | _ | s2k_useage > 0 -> |
@@ -612,3 +610,19 @@ parse_signature_subpacket 16 = do | |||
612 | -- Fail nicely for unimplemented packets | 610 | -- Fail nicely for unimplemented packets |
613 | parse_signature_subpacket x = | 611 | parse_signature_subpacket x = |
614 | fail $ "Unimplemented OpenPGP signature subpacket tag " ++ show x ++ "." | 612 | fail $ "Unimplemented OpenPGP signature subpacket tag " ++ show x ++ "." |
613 | |||
614 | decode_s2k_count :: Word8 -> Word32 | ||
615 | decode_s2k_count c = (16 + (fromIntegral c .&. 15)) `shiftL` | ||
616 | ((fromIntegral c `shiftR` 4) + 6) | ||
617 | |||
618 | encode_s2k_count :: Word32 -> Word8 | ||
619 | encode_s2k_count iterations | ||
620 | | iterations >= 65011712 = 255 | ||
621 | | decode_s2k_count result < iterations = result+1 | ||
622 | | otherwise = result | ||
623 | where | ||
624 | result = fromIntegral $ (fromIntegral c `shiftL` 4) .|. (count - 16) | ||
625 | (count, c) = encode_s2k_count' (iterations `shiftR` 6) 0 | ||
626 | encode_s2k_count' count c | ||
627 | | count < 32 = (count, c) | ||
628 | | otherwise = encode_s2k_count' (count `shiftR` 1) (c+1) | ||