summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Paul Weber <singpolyma@singpolyma.net>2012-12-29 11:14:38 -0500
committerStephen Paul Weber <singpolyma@singpolyma.net>2012-12-29 11:14:38 -0500
commit4b5e0e3d27973f8627ed3d83013f55c3b365b306 (patch)
treeb2358f8288bc5d950f372dc369fd48e0c66efd8e
parent86d6407eccd1ed9f44f4e1a0e495e504d393c1d8 (diff)
Support partial lengths
-rw-r--r--Data/OpenPGP.hs38
1 files changed, 23 insertions, 15 deletions
diff --git a/Data/OpenPGP.hs b/Data/OpenPGP.hs
index dca7838..c6c22e4 100644
--- a/Data/OpenPGP.hs
+++ b/Data/OpenPGP.hs
@@ -237,31 +237,39 @@ instance BINARY_CLASS Packet where
237 blen = fromIntegral $ B.length body 237 blen = fromIntegral $ B.length body
238 (body, tag) = put_packet p 238 (body, tag) = put_packet p
239 get = do 239 get = do
240 tag <- get :: Get Word8 240 (t, packet) <- get_packet_bytes
241 let (t, l) = 241 return $ unsafeRunGet (parse_packet t) (B.concat packet)
242 if (tag .&. 64) /= 0 then 242
243 (tag .&. 63, parse_new_length) 243get_packet_bytes :: Get (Word8, [B.ByteString])
244 else 244get_packet_bytes = do
245 ((tag `shiftR` 2) .&. 15, parse_old_length tag) 245 tag <- get
246 len <- l 246 let (t, l) =
247 -- This forces the whole packet to be consumed 247 if (tag .&. 64) /= 0 then
248 packet <- getSomeByteString (fromIntegral len) 248 (tag .&. 63, parse_new_length)
249 return $ unsafeRunGet (parse_packet t) packet 249 else
250 ((tag `shiftR` 2) .&. 15, (,) <$> parse_old_length tag <*> pure False)
251 (len, partial) <- l
252 -- This forces the whole packet to be consumed
253 packet <- getSomeByteString (fromIntegral len)
254 if not partial then return (t, [packet]) else
255 (,) t <$> ((packet:) . snd) <$> get_packet_bytes
250 256
251-- http://tools.ietf.org/html/rfc4880#section-4.2.2 257-- http://tools.ietf.org/html/rfc4880#section-4.2.2
252parse_new_length :: Get Word32 258parse_new_length :: Get (Word32, Bool)
253parse_new_length = do 259parse_new_length = do
254 len <- fmap fromIntegral (get :: Get Word8) 260 len <- fmap fromIntegral (get :: Get Word8)
255 case len of 261 case len of
256 -- One octet length 262 -- One octet length
257 _ | len < 192 -> return len 263 _ | len < 192 -> return (len, False)
258 -- Two octet length 264 -- Two octet length
259 _ | len > 191 && len < 224 -> do 265 _ | len > 191 && len < 224 -> do
260 second <- fmap fromIntegral (get :: Get Word8) 266 second <- fmap fromIntegral (get :: Get Word8)
261 return $ ((len - 192) `shiftL` 8) + second + 192 267 return (((len - 192) `shiftL` 8) + second + 192, False)
262 -- Five octet length 268 -- Five octet length
263 255 -> get :: Get Word32 269 255 -> (,) <$> (get :: Get Word32) <*> pure False
264 -- TODO: Partial body lengths. 1 << (len & 0x1F) 270 -- Partial length (streaming)
271 _ | len >= 224 && len < 255 ->
272 return (1 `shiftL` (fromIntegral len .&. 0x1F), True)
265 _ -> fail "Unsupported new packet length." 273 _ -> fail "Unsupported new packet length."
266 274
267-- http://tools.ietf.org/html/rfc4880#section-4.2.1 275-- http://tools.ietf.org/html/rfc4880#section-4.2.1