Crypto-3.0.3: RSAEncryptionExample.hs
module Main(main) where
import System.IO
import Data.Char
import Data.List
import System.Environment
import System.Console.GetOpt
import Data.Maybe
import Codec.ASN1
import Codec.Utils
import Data.Digest.SHA1
import Codec.Encryption.RSA.MGF
import qualified Codec.Encryption.RSA.EMEOAEP as E
import Codec.Encryption.RSA
import Codec.ASN1.TLV
import Codec.ASN1.X509
import Codec.ASN1.BER
import NewBinary.Binary
import Control.Monad.State
randomSeed :: [Octet]
randomSeed = hash [3]
ciphertext :: [Octet] -> [Octet] -> String -> [Octet]
ciphertext n d x =
encrypt (n,d) $
E.encode mgf hash [] randomSeed n $
map (fromIntegral . ord) x
encryptWith certFile plainTextFile cipherTextFile =
{-
certFile should contain an X.509 certificate.
-}
do hcert <- openFile certFile ReadMode
hplain <- openFile plainTextFile ReadMode
ptext <- hGetContents hplain
bin <- openBinIO_ hcert
(_,x) <- tlvIO bin
{-
Typecheck this is really a signed certificate.
-}
(q,sc) <- typeCheck signedCertificate x
{-
If it is then decode it and extract the bitstring containing the RSA
public key.
-}
let (_ ::= c) = q
d = (decode c (Just sc))::(Maybe SignedCertificate)
d1 = certificate1 (fromJust d)
d2 = subjectPublicKeyInfo2 d1
d3 = subjectPublicKeyInfo1 d2
(BitString e) = d3
(_,x') = tlv e
{-
Typecheck this really is an RSA public key.
-}
(q',rpk) <- typeCheck rsaPublicKey x'
{-
If it is then decode it and extract the modulus and the public
exponent.
-}
let (_ ::= r) = q'
s = (decode r (Just rpk))
ct = ciphertext (toOctets 256 $ modulus1 $ fromJust s)
(toOctets 256 $ publicExponent1 $ fromJust s)
ptext
{-
Write out the encrypted text.
-}
ofh <- openFile cipherTextFile WriteMode
hPutStr ofh (map (chr . fromIntegral) ct)
hClose ofh
main = do pn <- getProgName
args <- getArgs
(fs,ss) <- opts pn args
let sfs = sort fs
(Cert e) = sfs!!0
(Input i) = sfs!!1
(Output o) = sfs!!2
encryptWith e i o
data Flag = Cert String | Input String | Output String
deriving (Show,Eq,Ord)
options = [
Option ['e'] ["cert","certificate"] (ReqArg Cert "CERT")
"Certificate File",
Option ['p'] ["plain","plaintext"] (ReqArg Input "INPUT")
"Plaintext File",
Option ['c'] ["cipher","ciphertext"] (ReqArg Output "OUTPUT")
"Ciphertext Fileoutput"
]
opts :: String -> [String] -> IO ([Flag], [String])
opts progName argv =
case getOpt Permute options argv of
(o,n,[] ) ->
if length o == 3
then return (o,n)
else ioError (userError (usageInfo header options))
(_,_,errs) ->
ioError (userError (concat errs ++ usageInfo header options))
where header = "Usage: " ++ progName ++ " [OPTION...] files..."