summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Paul Weber <singpolyma@singpolyma.net>2013-01-03 13:53:55 -0500
committerStephen Paul Weber <singpolyma@singpolyma.net>2013-01-03 13:53:55 -0500
commitfc9dd0707c349e8e8e822d8e5a624dd46ac961f2 (patch)
tree413be0ad73ef8e1d033a6f32a8eb4afe48a8faed
parent77ee44a5ba50aacc8520b24614bbc044b6cf48f7 (diff)
Properly verify secret key checksums
-rw-r--r--Data/OpenPGP.hs25
1 files changed, 13 insertions, 12 deletions
diff --git a/Data/OpenPGP.hs b/Data/OpenPGP.hs
index 61d6dfd..209d876 100644
--- a/Data/OpenPGP.hs
+++ b/Data/OpenPGP.hs
@@ -170,6 +170,10 @@ pad l s = replicate (l - length s) '0' ++ s
170padBS :: Int -> B.ByteString -> B.ByteString 170padBS :: Int -> B.ByteString -> B.ByteString
171padBS l s = B.replicate (fromIntegral l - B.length s) 0 `B.append` s 171padBS l s = B.replicate (fromIntegral l - B.length s) 0 `B.append` s
172 172
173checksum :: B.ByteString -> Word16
174checksum = fromIntegral .
175 B.foldl (\c i -> (c + fromIntegral i) `mod` 65536) (0::Integer)
176
173data Packet = 177data Packet =
174 AsymmetricSessionKeyPacket { 178 AsymmetricSessionKeyPacket {
175 version::Word8, 179 version::Word8,
@@ -454,15 +458,11 @@ put_packet (SecretKeyPacket { version = version, timestamp = timestamp,
454 [encode symmetric_algorithm] 458 [encode symmetric_algorithm]
455 ) ++ 459 ) ++
456 (if symmetric_algorithm /= Unencrypted then 460 (if symmetric_algorithm /= Unencrypted then
461 -- For V3 keys, the "encrypted data" has an unencrypted checksum
462 -- of the unencrypted MPIs on the end
457 [encrypted_data] 463 [encrypted_data]
458 else s ++ 464 else s ++
459 -- TODO: Checksum is part of encrypted_data for V4 ONLY 465 [encode $ checksum $ B.concat s]),
460 if s2k_useage == 254 then
461 [B.replicate 20 0] -- TODO SHA1 Checksum
462 else
463 [encode (fromIntegral $
464 B.foldl (\c i -> (c + fromIntegral i) `mod` 65536)
465 (0::Integer) (B.concat s) :: Word16)]),
466 if is_subkey then 7 else 5) 466 if is_subkey then 7 else 5)
467 where 467 where
468 p = fst (put_packet $ 468 p = fst (put_packet $
@@ -610,12 +610,13 @@ parse_packet 5 = do
610 encrypted <- getRemainingByteString; 610 encrypted <- getRemainingByteString;
611 return (k s2k symmetric_algorithm encrypted False) 611 return (k s2k symmetric_algorithm encrypted False)
612 } else do 612 } else do
613 key <- foldM (\m f -> do 613 skey <- foldM (\m f -> do
614 mpi <- get :: Get MPI 614 mpi <- get :: Get MPI
615 return $ (f,mpi):m) key (secret_key_fields algorithm) 615 return $ (f,mpi):m) [] (secret_key_fields algorithm)
616 checksum <- getRemainingByteString 616 chk <- get
617 -- TODO: verify checksum 617 when (checksum (B.concat $ map (encode . snd) skey) /= chk) $
618 return ((k s2k symmetric_algorithm B.empty False) {key = key}) 618 fail "Checksum verification failed for unencrypted secret key"
619 return ((k s2k symmetric_algorithm B.empty False) {key = key ++ skey})
619-- PublicKeyPacket, http://tools.ietf.org/html/rfc4880#section-5.5.2 620-- PublicKeyPacket, http://tools.ietf.org/html/rfc4880#section-5.5.2
620parse_packet 6 = do 621parse_packet 6 = do
621 version <- get :: Get Word8 622 version <- get :: Get Word8