module Main where

import Network.CGI
import Text.XHtml
import Text.Regex.Posix
import Data.Maybe

import Process
import DB
import CertInfo

main = runCGI $ handleErrors cgiMain

cgiMain = do
    subject <- getInput "subject"
    let subj = safe $ fromJust subject
    password <- getInput "password"
    let pass = fromJust password
    let keyfilename  = tmpfile subj "key"
    let reqfilename  = tmpfile subj "req"
    let certfilename = tmpfile subj "cert" 
    let req_command = "PASS=" ++ pass ++ " /usr/bin/openssl req -new -subj \"/CN=" ++ subj ++ "/O=da-op3n010/C=DE/\" -passout env:PASS -keyout " ++ keyfilename ++ " -out " ++ reqfilename
    let issue_command = "HOME=/tmp /usr/bin/openssl x509 -CAkey ../ca-key.pem -CA ../ca-cert.pem -req -in " ++ reqfilename ++ " -CAcreateserial -out " ++ certfilename
    let p12_command = "export HOME=/tmp; PASS=" ++ pass ++ " /usr/bin/openssl pkcs12 -export -inkey " ++ keyfilename ++ " -in " ++ certfilename ++ " -chain -CAfile ../ca-cert.pem -aes256 -passin env:PASS -passout env:PASS"
    req <- liftIO $ run req_command
    iss <- liftIO $ run issue_command
    p12 <- liftIO $ run p12_command
    certdata  <- liftIO $ run ("cat " ++ certfilename)
    notbefore <- liftIO $ notBefore   certfilename
    notafter  <- liftIO $ notAfter    certfilename
    fingerp   <- liftIO $ fingerPrint certfilename        
    serial    <- liftIO $ serial      certfilename
    let sep = "','"
    liftIO $ db_insert $ "INSERT INTO certificates VALUES ('" ++ subj ++ sep ++ notbefore ++ sep ++ notafter ++ sep ++ certdata ++ sep ++ fingerp ++ sep ++ serial ++ sep ++ "PKCS#12" ++ "')"
    setHeader "Content-Type" "application/octet-string"
    setHeader "Content-Disposition" ("attachment; filename=\"" ++ subj ++ ".p12\"")
    output $ p12

-- only accept alphanumeric values in variables from CGI input
safe var = if var =~ "^[a-zA-Z0-9\\ ]{1,64}$"
    then var
    else "dummy"

tmpfile subj typ = "/tmp/\"" ++ subj ++ "-" ++ typ ++ ".pem\""

