summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2014-05-12 20:51:50 -0400
committerjoe <joe@jerkface.net>2014-05-12 20:51:50 -0400
commit83c9390271cfcb9cd64d0ffab0a2713f204c2ccc (patch)
tree0b5c4a8aa69a109050d6aaedc12c452b469c6049
parent91dd66f6478ec87aaf184daab7c44b17f9796fce (diff)
parse email-style Date: headers when importing PEM files.
-rw-r--r--KeyRing.hs17
-rw-r--r--TimeUtil.hs23
2 files changed, 35 insertions, 5 deletions
diff --git a/KeyRing.hs b/KeyRing.hs
index e0c3b77..94039f6 100644
--- a/KeyRing.hs
+++ b/KeyRing.hs
@@ -113,7 +113,7 @@ import Data.ASN1.Types ( toASN1, ASN1Object, fromASN1
113import Data.ASN1.BitArray ( BitArray(..), toBitArray ) 113import Data.ASN1.BitArray ( BitArray(..), toBitArray )
114import Data.ASN1.Encoding ( encodeASN1, encodeASN1', decodeASN1, decodeASN1' ) 114import Data.ASN1.Encoding ( encodeASN1, encodeASN1', decodeASN1, decodeASN1' )
115import Data.ASN1.BinaryEncoding ( DER(..) ) 115import Data.ASN1.BinaryEncoding ( DER(..) )
116import Data.Time.Clock.POSIX ( POSIXTime, utcTimeToPOSIXSeconds ) 116import Data.Time.Clock.POSIX ( POSIXTime, utcTimeToPOSIXSeconds, posixSecondsToUTCTime )
117import Data.Time.Clock ( UTCTime ) 117import Data.Time.Clock ( UTCTime )
118import Data.Bits ( Bits ) 118import Data.Bits ( Bits )
119import Data.Text.Encoding ( encodeUtf8 ) 119import Data.Text.Encoding ( encodeUtf8 )
@@ -1500,9 +1500,9 @@ readSecretPEMFile fname = do
1500 let ctx = InputFileContext "" "" 1500 let ctx = InputFileContext "" ""
1501 -- Note: The key's timestamp is included in it's fingerprint. 1501 -- Note: The key's timestamp is included in it's fingerprint.
1502 -- Therefore, we should attempt to preserve it. 1502 -- Therefore, we should attempt to preserve it.
1503 timestamp <- getInputFileTime ctx fname 1503 stamp <- getInputFileTime ctx fname
1504 input <- readInputFileL ctx fname 1504 input <- readInputFileL ctx fname
1505 let dta = catMaybes $ scanAndParse (pkcs1 <> cert) $ Char8.lines input 1505 let edta = scanAndParse (fmap Left dateParser <> fmap Right (pkcs1 <> cert)) $ Char8.lines input
1506 pkcs1 = fmap (parseRSAPrivateKey . pemBlob) 1506 pkcs1 = fmap (parseRSAPrivateKey . pemBlob)
1507 $ pemParser $ Just "RSA PRIVATE KEY" 1507 $ pemParser $ Just "RSA PRIVATE KEY"
1508 cert = fmap (fmap PEMCertificate . parseCertBlob False . pemBlob) 1508 cert = fmap (fmap PEMCertificate . parseCertBlob False . pemBlob)
@@ -1514,7 +1514,7 @@ readSecretPEMFile fname = do
1514 let _ = rsa :: RSAPrivateKey 1514 let _ = rsa :: RSAPrivateKey
1515 return $ PEMPacket $ SecretKeyPacket 1515 return $ PEMPacket $ SecretKeyPacket
1516 { version = 4 1516 { version = 4
1517 , timestamp = toEnum (fromEnum timestamp) 1517 , timestamp = fromTime stamp -- toEnum (fromEnum stamp)
1518 , key_algorithm = RSA 1518 , key_algorithm = RSA
1519 , key = [ -- public fields... 1519 , key = [ -- public fields...
1520 ('n',rsaN rsa) 1520 ('n',rsaN rsa)
@@ -1532,7 +1532,14 @@ readSecretPEMFile fname = do
1532 , encrypted_data = "" 1532 , encrypted_data = ""
1533 , is_subkey = True 1533 , is_subkey = True
1534 } 1534 }
1535 return dta 1535 dta = catMaybes $ map snd $ scanl mergeDate (stamp,Nothing) edta
1536 mergeDate (_,obj) (Left tm) = (fromTime tm,obj)
1537 mergeDate (tm,_) (Right (Just (PEMPacket key))) = (tm,Just $ PEMPacket key')
1538 where key' = if tm < fromTime (timestamp key)
1539 then key { timestamp = fromTime tm }
1540 else key
1541 mergeDate (tm,_) (Right mb) = (tm,mb)
1542 return $ dta
1536 1543
1537doImport 1544doImport
1538 :: Ord k => 1545 :: Ord k =>
diff --git a/TimeUtil.hs b/TimeUtil.hs
index 1c241a4..9c0a2b5 100644
--- a/TimeUtil.hs
+++ b/TimeUtil.hs
@@ -3,8 +3,10 @@
3module TimeUtil 3module TimeUtil
4 ( now 4 ( now
5 , IsTime(..) 5 , IsTime(..)
6 , fromTime
6 , parseRFC2822 7 , parseRFC2822
7 , printRFC2822 8 , printRFC2822
9 , dateParser
8 ) where 10 ) where
9 11
10import Data.Time.LocalTime 12import Data.Time.LocalTime
@@ -18,6 +20,8 @@ import Data.Maybe
18import Data.Char 20import Data.Char
19import qualified Data.ByteString.Char8 as S 21import qualified Data.ByteString.Char8 as S
20import qualified Data.ByteString.Lazy.Char8 as L 22import qualified Data.ByteString.Lazy.Char8 as L
23import Foreign.C.Types ( CTime(..) )
24import Data.Word ( Word32 )
21 25
22import ScanningParser 26import ScanningParser
23 27
@@ -89,6 +93,25 @@ dateParser = ScanningParser ffst pbdy
89 else Nothing 93 else Nothing
90 pbdy date xs = (date,xs) 94 pbdy date xs = (date,xs)
91 95
96class IsUTC a where
97 fromUTC :: UTCTime -> a
98 toUTC :: a -> UTCTime
99
100fromTime :: ( IsUTC a, IsUTC b ) => a -> b
101fromTime = fromUTC . toUTC
102
103instance IsUTC UTCTime where
104 fromUTC = id
105 toUTC = id
106
107instance IsUTC CTime where
108 fromUTC utc = CTime (round $ utcTimeToPOSIXSeconds utc)
109 toUTC (CTime t) = posixSecondsToUTCTime (realToFrac t)
110
111instance IsUTC Word32 where
112 fromUTC utc = round $ utcTimeToPOSIXSeconds utc
113 toUTC t = posixSecondsToUTCTime (realToFrac t)
114
92{- 115{-
93main = do 116main = do
94 nowtime <- now 117 nowtime <- now