Skip to content

Instantly share code, notes, and snippets.

@frasertweedale
Last active August 29, 2015 14:16
Show Gist options
  • Save frasertweedale/9267cb46dbe600821d58 to your computer and use it in GitHub Desktop.
Save frasertweedale/9267cb46dbe600821d58 to your computer and use it in GitHub Desktop.
Example TLS API
module TLS where
-- |
--
-- This is something like what I want from a TLS API. The TLS
-- library should provide a single call: "give me a secure
-- connection to $HOST". All possibilities for authenticating the
-- peer, including CRL, OCSP, DANE, etc, should be accounted for in
-- a configuration type, and the library should take care of all the
-- details.
--
-- The library should provide some sensible default configurations,
-- and it should be prepared to remove/reject unsafe configurations
-- in future versions of the library.
--
-- The following is an example of what I expect. It is not complete
-- (for example, there is no CRL policy or configuration of
-- acceptable key strengths, cipher suites or key exchange
-- protocols).
import Data.Set
data Hostname
data Port
data TrustStore
data Socket
data TLSError
data HostVerifyPolicy
= HostMismatchReject
-- ^ If hostname is not present in CN or subjectAltName extension
-- reject the certificate.
| HostMismatchIgnore
-- ^ Continue connecting even if hostname is not present in CN or
-- subjectAltName extension. Certificate may still be rejected
-- for other reasons.
data OcspResponderFailurePolicy
= OcspResponderFailureReject
-- ^ Failure to get a response from the appointed OCSP responder
-- results in validation failure.
| OcspResponderFailureIgnore
-- ^ Failure to get a response from the appointed OCSP responder
-- is treated like the cert had no OCSP authorityInfoAccess.
data OcspLookupPolicy
= OcspStapledOrResponder
-- ^ Prefer stapled response otherwise attempt to contact OCSP responder.
| OcspStapledOnly
-- ^ Only use stapled responses.
| OcspResponderOnly
-- ^ Ignore stapled response; always attempt to use responses
-- directly from OCSP responder.
data OcspPolicy
= OcspRequire
-- ^ OCSP validity is required
| OcspIfAvailable
-- ^ OCSP is checked if a response is available according to the
-- active 'OcspLookupPolicy'
| OcspNone
-- ^ No OCSP validity checking is performed at all
data DaneCertificateUsage
= CaConstraint
| ServiceCertificateConstraint
| TrustAnchorAssertion
| DomainIssuedCertificate
deriving (Eq, Ord)
type DanePolicy = Set DaneCertificateUsage
data TrustPolicy
= TrustAndDaneIfPresent
| TrustAndDane
| TrustSufficient
| DaneSufficient
data TLSParams = TLSParams
{ trustPolicy :: TrustPolicy
, hostVerifyPolicy :: HostVerifyPolicy
, ocspPolicy :: OcspPolicy
, ocspLookupPolicy :: OcspLookupPolicy
, ocspResponderFailurePolicy :: OcspResponderFailurePolicy
, danePolicy :: DanePolicy
}
defaultTLSParams :: TLSParams
defaultTLSParams = TLSParams
TrustAndDaneIfPresent
HostMismatchReject
OcspIfAvailable
OcspStapledOrResponder
OcspResponderFailureIgnore
(fromList
[ CaConstraint, ServiceCertificateConstraint
, TrustAnchorAssertion, DomainIssuedCertificate ])
connect
:: TLSParams
-> TrustStore
-> Hostname
-> Port
-> IO (Either TLSError Socket)
connect = undefined
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment