summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Paul Weber <singpolyma@singpolyma.net>2011-08-02 19:07:18 -0500
committerStephen Paul Weber <singpolyma@singpolyma.net>2011-08-02 19:07:18 -0500
commita7049687ad5a392cc16769a63ddfb221c13dfbf9 (patch)
tree00425740298874f4c038a936b8d838bccdd4ecd1
parentbde6687c6016bc81a95dbc033e475fce8a0e2594 (diff)
SecretKeyPacket with parser
-rw-r--r--lib/OpenPGP.hs63
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/OpenPGP.hs b/lib/OpenPGP.hs
index 373bd17..330c6a1 100644
--- a/lib/OpenPGP.hs
+++ b/lib/OpenPGP.hs
@@ -1,5 +1,6 @@
1module OpenPGP (Message(..), Packet(..), HashAlgorithm, KeyAlgorithm, CompressionAlgorithm, fingerprint) where 1module OpenPGP (Message(..), Packet(..), HashAlgorithm, KeyAlgorithm, CompressionAlgorithm, fingerprint) where
2 2
3import Control.Monad
3import Data.Binary 4import Data.Binary
4import Data.Binary.Get 5import Data.Binary.Get
5import Data.Bits 6import Data.Bits
@@ -32,6 +33,20 @@ data Packet =
32 public_key_algorithm::KeyAlgorithm, 33 public_key_algorithm::KeyAlgorithm,
33 key::Map Char MPI 34 key::Map Char MPI
34 } | 35 } |
36 SecretKeyPacket {
37 version::Word8,
38 timestamp::Word32,
39 public_key_algorithm::KeyAlgorithm,
40 key::Map Char MPI,
41 s2k_useage::Word8,
42 symmetric_type::Word8,
43 s2k_type::Word8,
44 s2k_hash_algorithm::HashAlgorithm,
45 s2k_salt::Word64,
46 s2k_count::Word8,
47 encrypted_data::LZ.ByteString,
48 private_hash::LZ.ByteString
49 } |
35 CompressedDataPacket { 50 CompressedDataPacket {
36 compressed_data_algorithm::CompressionAlgorithm, 51 compressed_data_algorithm::CompressionAlgorithm,
37 message::Message 52 message::Message
@@ -174,6 +189,14 @@ public_key_fields RSA_S = public_key_fields RSA
174public_key_fields ELGAMAL = ['p', 'g', 'y'] 189public_key_fields ELGAMAL = ['p', 'g', 'y']
175public_key_fields DSA = ['p', 'q', 'g', 'y'] 190public_key_fields DSA = ['p', 'q', 'g', 'y']
176 191
192-- http://tools.ietf.org/html/rfc4880#section-5.5.3
193secret_key_fields :: KeyAlgorithm -> [Char]
194secret_key_fields RSA = ['d', 'p', 'q', 'u']
195secret_key_fields RSA_E = public_key_fields RSA
196secret_key_fields RSA_S = public_key_fields RSA
197secret_key_fields ELGAMAL = ['x']
198secret_key_fields DSA = ['x']
199
177-- Helper method for fingerprints and such 200-- Helper method for fingerprints and such
178fingerprint_material :: Packet -> [LZ.ByteString] 201fingerprint_material :: Packet -> [LZ.ByteString]
179fingerprint_material (PublicKeyPacket {version = 4, 202fingerprint_material (PublicKeyPacket {version = 4,
@@ -218,6 +241,46 @@ parse_packet 4 = do
218 key_id = (BaseConvert.toString 16 key_id), 241 key_id = (BaseConvert.toString 16 key_id),
219 nested = nested 242 nested = nested
220 }) 243 })
244-- SecretKeyPacket, http://tools.ietf.org/html/rfc4880#section-5.5.3
245parse_packet 5 = do
246 -- Parse PublicKey part
247 (PublicKeyPacket {
248 version = version,
249 timestamp = timestamp,
250 public_key_algorithm = algorithm,
251 key = key
252 }) <- parse_packet 6
253 s2k_useage <- get :: Get Word8
254 let k = SecretKeyPacket version timestamp algorithm key s2k_useage
255 in do
256 k' <- case s2k_useage of
257 _ | s2k_useage == 255 || s2k_useage == 254 -> do
258 symmetric_type <- get
259 s2k_type <- get
260 s2k_hash_algorithm <- get
261 s2k_salt <- if s2k_type == 1 || s2k_type == 3 then get
262 else return undefined
263 s2k_count <- if s2k_type == 3 then do
264 c <- fmap fromIntegral (get :: Get Word8)
265 return $ fromIntegral $
266 (16 + (c .&. 15)) `shiftL` ((c `shiftR` 4) + 6)
267 else return undefined
268 return (k symmetric_type s2k_type s2k_hash_algorithm
269 s2k_salt s2k_count)
270 _ | s2k_useage > 0 ->
271 -- s2k_useage is symmetric_type in this case
272 return (k s2k_useage undefined undefined undefined undefined)
273 _ ->
274 return (k undefined undefined undefined undefined undefined)
275 if s2k_useage > 0 then do
276 encrypted <- getRemainingLazyByteString
277 return (k' encrypted undefined)
278 else do
279 key <- foldM (\m f -> do
280 mpi <- get :: Get MPI
281 return $ Map.insert f mpi m) key (secret_key_fields algorithm)
282 private_hash <- getRemainingLazyByteString
283 return ((k' undefined private_hash) {key = key})
221-- PublicKeyPacket, http://tools.ietf.org/html/rfc4880#section-5.5.2 284-- PublicKeyPacket, http://tools.ietf.org/html/rfc4880#section-5.5.2
222parse_packet 6 = do 285parse_packet 6 = do
223 version <- get :: Get Word8 286 version <- get :: Get Word8