summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kiki.hs102
1 files changed, 47 insertions, 55 deletions
diff --git a/kiki.hs b/kiki.hs
index 3628307..c8adb51 100644
--- a/kiki.hs
+++ b/kiki.hs
@@ -26,6 +26,7 @@ import System.Environment
26import System.Exit 26import System.Exit
27import System.IO (hPutStrLn,stderr) 27import System.IO (hPutStrLn,stderr)
28import qualified Codec.Binary.Base64 as Base64 28import qualified Codec.Binary.Base64 as Base64
29import qualified Codec.Binary.Base16 as Base16
29import qualified Crypto.Hash.RIPEMD160 as RIPEMD160 30import qualified Crypto.Hash.RIPEMD160 as RIPEMD160
30import qualified Crypto.Hash.SHA256 as SHA256 31import qualified Crypto.Hash.SHA256 as SHA256
31import qualified Data.ByteString as S 32import qualified Data.ByteString as S
@@ -40,6 +41,7 @@ import Crypto.PubKey.RSA as RSA
40import qualified Codec.Compression.GZip as GZip 41import qualified Codec.Compression.GZip as GZip
41import Data.Time.Clock.POSIX ( utcTimeToPOSIXSeconds ) 42import Data.Time.Clock.POSIX ( utcTimeToPOSIXSeconds )
42import Data.Time.Clock ( UTCTime ) 43import Data.Time.Clock ( UTCTime )
44import Data.Monoid ( (<>) )
43 45
44 46
45import DotLock 47import DotLock
@@ -353,25 +355,42 @@ parseCertBlob comp bs = do
353 (notBefore,notAfter) = certValidity cert 355 (notBefore,notAfter) = certValidity cert
354 case certPubKey cert of 356 case certPubKey cert of
355 PubKeyRSA key -> do 357 PubKeyRSA key -> do
356 let ex = let ekey = Char8.toStrict $ encodeASN1 DER (toASN1 key []) 358 let withoutkey =
357 (pre,post) = S.breakSubstring ekey $ Char8.toStrict bs 359 let ekey = Char8.toStrict $ encodeASN1 DER (toASN1 key [])
358 post' = S.drop (S.length ekey) post 360 (pre,post) = S.breakSubstring ekey $ Char8.toStrict bs
359 len :: Word16 361 post' = S.drop (S.length ekey) post
360 len = if S.null post then maxBound 362 len :: Word16
361 else fromIntegral $ S.length pre 363 len = if S.null post then maxBound
362 in encode len `L.append` GZip.compress (Char8.fromChunks [pre,post']) 364 else fromIntegral $ S.length pre
365 in if len < 4096
366 then encode len `L.append` GZip.compress (Char8.fromChunks [pre,post'])
367 else bs
363 return 368 return
364 ParsedCert { pcertKey = packetFromPublicRSAKey notBefore 369 ParsedCert { pcertKey = packetFromPublicRSAKey notBefore
365 (MPI $ public_n key) 370 (MPI $ public_n key)
366 (MPI $ public_e key) 371 (MPI $ public_e key)
367 , pcertTimestamp = notBefore 372 , pcertTimestamp = notBefore
368 , pcertBlob = case comp of 373 , pcertBlob = if comp then withoutkey
369 0 -> ex 374 else bs
370 1 -> bs
371 2 -> GZip.compress bs
372 } 375 }
373 _ -> Nothing 376 _ -> Nothing
374 377
378decodeBlob cert =
379 if 0 /= (bs `L.index` 0) .&. 0x10
380 then bs
381 else let (keypos0,bs') = L.splitAt 2 bs
382 keypos :: Word16
383 keypos = decode keypos0
384 ds = GZip.decompress bs'
385 (prekey,postkey) = L.splitAt (fromIntegral keypos) ds
386 in prekey <> key <> postkey
387 where
388 bs = pcertBlob cert
389 key = maybe L.empty (encodeASN1 DER . flip toASN1 []) $ rsaKeyFromPacket $ pcertKey cert
390
391parsePEM :: L.ByteString -> L.ByteString -> (Message,L.ByteString)
392parsePEM hdr bs = error "todo"
393
375show_torhash pubkey _ = do 394show_torhash pubkey _ = do
376 bs <- Char8.readFile pubkey 395 bs <- Char8.readFile pubkey
377 let parsekey f dta = do 396 let parsekey f dta = do
@@ -391,50 +410,13 @@ show_cert certfile _ = do
391 bs <- Char8.readFile certfile 410 bs <- Char8.readFile certfile
392 let dta = extractPEM "CERTIFICATE" bs 411 let dta = extractPEM "CERTIFICATE" bs
393 mdta = L.pack <$> Base64.decode (Char8.unpack dta) 412 mdta = L.pack <$> Base64.decode (Char8.unpack dta)
394 {- 413 let c = mdta >>= parseCertBlob True
395 pubkey = RSA.PublicKey 414 d = mdta >>= parseCertBlob False
396 { public_size = 128 415 -- e = mdta >>= parseCertBlob 2
397 , public_n = 154361684503603802222425703762858923586891027963572326870083767113931020265732747123162809298697685461466566794668728252513238617267841367255306789892103614749619835666015844098056127878039846958283514957904585088494988419964303541700240003254472965884445634980070222782747273430139103311807958905274574715853
398 , public_e = 65537}
399 pubkey2 = RSAKey8
400 (MPI 154361684503603802222425703762858923586891027963572326870083767113931020265732747123162809298697685461466566794668728252513238617267841367255306789892103614749619835666015844098056127878039846958283514957904585088494988419964303541700240003254472965884445634980070222782747273430139103311807958905274574715853)
401 (MPI 65537)
402 mdta = Base64.decode (Char8.unpack dta)
403 cert = do
404 e <- decodeASN1 DER . L.pack <$> mdta
405 let scert = searchit bs -- decodeSignedCertificate $ Char8.toStrict (Char8.drop 4 bs)
406 scert :: Either String SignedCertificate
407 searchit bs | Char8.null bs = Left "thoroughly exhausted"
408 searchit bs = either (const $ searchit $ Char8.drop 1 bs) Right $ go bs
409 go bs | Char8.null bs = Left "exhausted"
410 go bs = either (const $ go $ Char8.init bs) Right $ (decodeSignedCertificate $ Char8.toStrict bs)
411 asn1 <- either (const Nothing) (Just) e
412 let asn1' = drop 2 asn1 -- getSequence 0 (drop 1 asn1) -- reverse $ dropWhile (/=End Sequence) $ drop 1 $ reverse asn1
413 -- k <- either (Just . Left) (Just . Right . fst) (fromASN1 asn1')
414 k <- either (const Nothing) (Just . fst) (fromASN1 asn1')
415 let _ = k :: Certificate -- Either String Certificate
416 return (k,scert) -- (asn1', k) -- asn1
417 ekey = encodeASN1 DER (toASN1 pubkey [])
418 ekey2 = encodeASN1 DER (toASN1 pubkey2 [])
419 ekey2_64 = Base64.encode $ L.unpack ekey2
420 ex = do
421 dta <- mdta
422 let ekey_ = Char8.toStrict ekey
423 (pre,post) = S.breakSubstring ekey_ (S.pack dta)
424 post' = S.drop (S.length ekey_) post
425 return $ ( b64L $ GZip.compress (Char8.fromChunks [pre,post']), (b64 pre, b64 post'))
426 putStrLn $ show dta
427 putStrLn $ show (fmap fst cert)
428 -- putStrLn $ show (fmap snd cert)
429 putStrLn $ show (Base64.encode $ L.unpack ekey)
430 putStrLn $ show (Base64.encode $ L.unpack ekey2)
431 putStrLn $ show ex
432 -}
433 let c = mdta >>= parseCertBlob 0
434 d = mdta >>= parseCertBlob 1
435 e = mdta >>= parseCertBlob 2
436 b64 = Base64.encode . S.unpack 416 b64 = Base64.encode . S.unpack
437 b64L = Base64.encode . L.unpack 417 b64L = Base64.encode . L.unpack
418 hex = Base16.encode . S.unpack
419 hexL = Base16.encode . L.unpack
438 putStrLn $ maybe "" (fingerprint . pcertKey) c 420 putStrLn $ maybe "" (fingerprint . pcertKey) c
439 putStrLn $ maybe "" (torhash . pcertKey) c 421 putStrLn $ maybe "" (torhash . pcertKey) c
440 putStrLn "" 422 putStrLn ""
@@ -442,16 +424,26 @@ show_cert certfile _ = do
442 putStrLn $ maybe "" (("key = " ++) . show . pcertKey) c 424 putStrLn $ maybe "" (("key = " ++) . show . pcertKey) c
443 putStrLn "" 425 putStrLn ""
444 putStrLn $ maybe "" (("small blob length = " ++) . show . L.length . pcertBlob) c 426 putStrLn $ maybe "" (("small blob length = " ++) . show . L.length . pcertBlob) c
445 putStrLn ""
446 putStrLn $ maybe "" (("small blob = " ++) . b64L . pcertBlob) c 427 putStrLn $ maybe "" (("small blob = " ++) . b64L . pcertBlob) c
428 putStrLn $ maybe "" ((" decoded = " ++) . b64L . decodeBlob) c
447 putStrLn "" 429 putStrLn ""
448 putStrLn $ maybe "" ((" big blob length = " ++) . show . L.length . pcertBlob) d 430 putStrLn $ maybe "" ((" big blob length = " ++) . show . L.length . pcertBlob) d
449 putStrLn ""
450 putStrLn $ maybe "" ((" big blob = " ++) . b64L . pcertBlob) d 431 putStrLn $ maybe "" ((" big blob = " ++) . b64L . pcertBlob) d
432 putStrLn $ maybe "" ((" decoded = " ++) . b64L . decodeBlob) d
433 {-
451 putStrLn "" 434 putStrLn ""
452 putStrLn $ maybe "" ((" gzip blob length = " ++) . show . L.length . pcertBlob) e 435 putStrLn $ maybe "" ((" gzip blob length = " ++) . show . L.length . pcertBlob) e
453 putStrLn "" 436 putStrLn ""
454 putStrLn $ maybe "" ((" gzip blob = " ++) . b64L . pcertBlob) e 437 putStrLn $ maybe "" ((" gzip blob = " ++) . b64L . pcertBlob) e
438 -}
439 -- ASN1 starts:
440 -- 1 2 3 4 5 6 7 8
441 -- cl....pc.tag..........
442 -- Start Sequence tag = 0x10
443 -- Start Sequence cl = 0
444 let v = encodeASN1 DER [Start Sequence]
445 putStrLn ""
446 putStrLn $ "prefix = " ++ hexL v
455 return () 447 return ()
456 448
457cannonical_eckey x y = 0x4:pad32(numToBytes x) ++ pad32(numToBytes y) :: [Word8] 449cannonical_eckey x y = 0x4:pad32(numToBytes x) ++ pad32(numToBytes y) :: [Word8]