-- |-- Module : System.Certificate.X509-- License : BSD-style-- Maintainer : Vincent Hanquez <vincent@snarc.org>-- Stability : experimental-- Portability : linux only---- this module is portable to unix system where there is usually-- a /etc/ssl/certs with system X509 certificates.---- the path can be dynamically override using the environment variable-- defined by envPathOverride in the module, which by-- default is SYSTEM_CERTIFICATE_PATH--moduleSystem.Certificate.X509(getSystemPath,readAll,findCertificate)whereimportSystem.Directory(getDirectoryContents)importSystem.Environment(getEnv)importData.List(isPrefixOf)importData.EitherimportData.Certificate.X509importData.Certificate.PEMimportqualifiedData.ByteStringasBimportqualifiedData.ByteString.LazyasLimportControl.Applicative((<$>))importControl.ExceptionimportControl.MonadimportPreludehiding(catch)defaultSystemPath::FilePathdefaultSystemPath="/etc/ssl/certs/"envPathOverride::StringenvPathOverride="SYSTEM_CERTIFICATE_PATH"getSystemPath::IOFilePathgetSystemPath=catch(getEnvenvPathOverride)inDefaultwhereinDefault::IOException->IOFilePathinDefault_=returndefaultSystemPathdataReadErr=ExceptionIOException|CertErrorStringderiving(Show,Eq)readCertificate::FilePath->IO(EitherReadErrX509)readCertificatefile=dorawdata<-try$B.readFilefile::IO(EitherIOExceptionB.ByteString)either(return.Left.Exception)parseCert$rawdatawhereparseCertpemdata=caseparsePEMCertpemdataofNothing->return$Left$CertError"certificate not in PEM format"Justcertdata->doreturn$either(Left.CertError)Right$decodeCertificate$L.fromChunks[certdata]readAll::IO[EitherReadErrX509]readAll=dopath<-getSystemPathcertfiles<-filter(not.isPrefixOf".")<$>getDirectoryContentspathforMcertfiles$\certfile->readCertificate(path++certfile)findCertificate::(X509->Bool)->IO(MaybeX509)findCertificatef=dopath<-getSystemPathcertfiles<-filter(not.isPrefixOf".")<$>getDirectoryContentspathloop$map(path++)certfileswhereloop[]=returnNothingloop(x:xs)=doox509<-readCertificatexcaseox509ofLeft_->loopxsRightx509->iffx509thenreturn$Justx509elseloopxs