summaryrefslogtreecommitdiff
path: root/Data
diff options
context:
space:
mode:
authorStephen Paul Weber <singpolyma@singpolyma.net>2012-04-30 13:03:43 -0500
committerStephen Paul Weber <singpolyma@singpolyma.net>2012-04-30 13:03:43 -0500
commiteca03631b66b623c42677d4ca1af393c4322cb84 (patch)
treeb513f043a3fb2b98b75fb555026c5fb1141a8f1b /Data
parentbe7580e37a1233be35131dcb957fe502cd47aa2f (diff)
support subkeys
Diffstat (limited to 'Data')
-rw-r--r--Data/OpenPGP.hs38
1 files changed, 27 insertions, 11 deletions
diff --git a/Data/OpenPGP.hs b/Data/OpenPGP.hs
index 4904e54..d6da9de 100644
--- a/Data/OpenPGP.hs
+++ b/Data/OpenPGP.hs
@@ -171,7 +171,8 @@ data Packet =
171 version::Word8, 171 version::Word8,
172 timestamp::Word32, 172 timestamp::Word32,
173 key_algorithm::KeyAlgorithm, 173 key_algorithm::KeyAlgorithm,
174 key::[(Char,MPI)] 174 key::[(Char,MPI)],
175 is_subkey::Bool
175 } | 176 } |
176 SecretKeyPacket { 177 SecretKeyPacket {
177 version::Word8, 178 version::Word8,
@@ -185,7 +186,8 @@ data Packet =
185 s2k_salt::Maybe Word64, 186 s2k_salt::Maybe Word64,
186 s2k_count::Maybe Word32, 187 s2k_count::Maybe Word32,
187 encrypted_data::B.ByteString, 188 encrypted_data::B.ByteString,
188 private_hash::Maybe B.ByteString -- the hash may be in the encrypted data 189 private_hash::Maybe B.ByteString, -- the hash may be in the encrypted data
190 is_subkey::Bool
189 } | 191 } |
190 CompressedDataPacket { 192 CompressedDataPacket {
191 compression_algorithm::CompressionAlgorithm, 193 compression_algorithm::CompressionAlgorithm,
@@ -346,7 +348,8 @@ put_packet (SecretKeyPacket { version = version, timestamp = timestamp,
346 s2k_hash_algorithm = s2k_hash_algo, 348 s2k_hash_algorithm = s2k_hash_algo,
347 s2k_salt = s2k_salt, 349 s2k_salt = s2k_salt,
348 s2k_count = s2k_count, 350 s2k_count = s2k_count,
349 encrypted_data = encrypted_data }) = 351 encrypted_data = encrypted_data,
352 is_subkey = is_subkey }) =
350 (B.concat $ [p, encode s2k_useage] ++ 353 (B.concat $ [p, encode s2k_useage] ++
351 (if s2k_useage `elem` [255, 254] then 354 (if s2k_useage `elem` [255, 254] then
352 [encode $ fromJust symmetric_type, encode s2k_t, 355 [encode $ fromJust symmetric_type, encode s2k_t,
@@ -364,16 +367,20 @@ put_packet (SecretKeyPacket { version = version, timestamp = timestamp,
364 else 367 else
365 [encode (fromIntegral $ 368 [encode (fromIntegral $
366 B.foldl (\c i -> (c + fromIntegral i) `mod` 65536) 369 B.foldl (\c i -> (c + fromIntegral i) `mod` 65536)
367 (0::Integer) (B.concat s) :: Word16)]), 5) 370 (0::Integer) (B.concat s) :: Word16)]),
371 if is_subkey then 7 else 5)
368 where 372 where
369 (Just s2k_t) = s2k_type 373 (Just s2k_t) = s2k_type
370 p = fst (put_packet $ PublicKeyPacket version timestamp algorithm key 374 p = fst (put_packet $
375 PublicKeyPacket version timestamp algorithm key False
371 :: (B.ByteString, Integer)) -- Supress warning 376 :: (B.ByteString, Integer)) -- Supress warning
372 s = map (encode . (key !)) (secret_key_fields algorithm) 377 s = map (encode . (key !)) (secret_key_fields algorithm)
373put_packet (PublicKeyPacket { version = 4, timestamp = timestamp, 378put_packet (PublicKeyPacket { version = 4, timestamp = timestamp,
374 key_algorithm = algorithm, key = key }) = 379 key_algorithm = algorithm, key = key,
380 is_subkey = is_subkey }) =
375 (B.concat $ [B.singleton 4, encode timestamp, encode algorithm] ++ 381 (B.concat $ [B.singleton 4, encode timestamp, encode algorithm] ++
376 map (encode . (key !)) (public_key_fields algorithm), 6) 382 map (encode . (key !)) (public_key_fields algorithm),
383 if is_subkey then 14 else 6)
377put_packet (CompressedDataPacket { compression_algorithm = algorithm, 384put_packet (CompressedDataPacket { compression_algorithm = algorithm,
378 message = message }) = 385 message = message }) =
379 (B.append (encode algorithm) $ compress algorithm $ encode message, 8) 386 (B.append (encode algorithm) $ compress algorithm $ encode message, 8)
@@ -468,13 +475,13 @@ parse_packet 5 = do
468 return (k Nothing Nothing Nothing Nothing Nothing) 475 return (k Nothing Nothing Nothing Nothing Nothing)
469 if s2k_useage > 0 then do { 476 if s2k_useage > 0 then do {
470 encrypted <- getRemainingByteString; 477 encrypted <- getRemainingByteString;
471 return (k' encrypted Nothing) 478 return (k' encrypted Nothing False)
472 } else do 479 } else do
473 key <- foldM (\m f -> do 480 key <- foldM (\m f -> do
474 mpi <- get :: Get MPI 481 mpi <- get :: Get MPI
475 return $ (f,mpi):m) key (secret_key_fields algorithm) 482 return $ (f,mpi):m) key (secret_key_fields algorithm)
476 private_hash <- getRemainingByteString 483 private_hash <- getRemainingByteString
477 return ((k' B.empty (Just private_hash)) {key = key}) 484 return ((k' B.empty (Just private_hash) False) {key = key})
478-- PublicKeyPacket, http://tools.ietf.org/html/rfc4880#section-5.5.2 485-- PublicKeyPacket, http://tools.ietf.org/html/rfc4880#section-5.5.2
479parse_packet 6 = do 486parse_packet 6 = do
480 version <- get :: Get Word8 487 version <- get :: Get Word8
@@ -489,9 +496,14 @@ parse_packet 6 = do
489 version = 4, 496 version = 4,
490 timestamp = timestamp, 497 timestamp = timestamp,
491 key_algorithm = algorithm, 498 key_algorithm = algorithm,
492 key = key 499 key = key,
500 is_subkey = False
493 } 501 }
494 x -> fail $ "Unsupported PublicKeyPacket version " ++ show x ++ "." 502 x -> fail $ "Unsupported PublicKeyPacket version " ++ show x ++ "."
503-- Secret-SubKey Packet, http://tools.ietf.org/html/rfc4880#section-5.5.1.4
504parse_packet 7 = do
505 p <- parse_packet 5
506 return p {is_subkey = True}
495-- CompressedDataPacket, http://tools.ietf.org/html/rfc4880#section-5.6 507-- CompressedDataPacket, http://tools.ietf.org/html/rfc4880#section-5.6
496parse_packet 8 = do 508parse_packet 8 = do
497 algorithm <- get 509 algorithm <- get
@@ -518,6 +530,10 @@ parse_packet 11 = do
518-- UserIDPacket, http://tools.ietf.org/html/rfc4880#section-5.11 530-- UserIDPacket, http://tools.ietf.org/html/rfc4880#section-5.11
519parse_packet 13 = 531parse_packet 13 =
520 fmap (UserIDPacket . B.toString) getRemainingByteString 532 fmap (UserIDPacket . B.toString) getRemainingByteString
533-- Public-Subkey Packet, http://tools.ietf.org/html/rfc4880#section-5.5.1.2
534parse_packet 14 = do
535 p <- parse_packet 6
536 return p {is_subkey = True}
521-- ModificationDetectionCodePacket, http://tools.ietf.org/html/rfc4880#section-5.14 537-- ModificationDetectionCodePacket, http://tools.ietf.org/html/rfc4880#section-5.14
522parse_packet 19 = 538parse_packet 19 =
523 fmap ModificationDetectionCodePacket getRemainingByteString 539 fmap ModificationDetectionCodePacket getRemainingByteString
@@ -547,7 +563,7 @@ fingerprint_material (SecretKeyPacket {version = 4,
547 fingerprint_material PublicKeyPacket {version = 4, 563 fingerprint_material PublicKeyPacket {version = 4,
548 timestamp = timestamp, 564 timestamp = timestamp,
549 key_algorithm = algorithm, 565 key_algorithm = algorithm,
550 key = key} 566 key = key, is_subkey = False}
551fingerprint_material p | version p `elem` [2, 3] = [n, e] 567fingerprint_material p | version p `elem` [2, 3] = [n, e]
552 where 568 where
553 n = B.drop 2 (encode (key p ! 'n')) 569 n = B.drop 2 (encode (key p ! 'n'))