-- | -- Module : Data.X509.ExtensionRaw -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- extension marshalling -- module Data.X509.ExtensionRaw ( ExtensionRaw(..) , tryExtRawASN1 , extRawASN1 , Extensions(..) ) where import Control.Applicative import Data.ASN1.Types import Data.ASN1.Encoding import Data.ASN1.BinaryEncoding import Data.X509.Internal import qualified Data.ByteString as B -- | An undecoded extension data ExtensionRaw = ExtensionRaw { extRawOID :: OID -- ^ OID of this extension , extRawCritical :: Bool -- ^ if this extension is critical , extRawContent :: B.ByteString -- ^ undecoded content } deriving (Show,Eq) tryExtRawASN1 :: ExtensionRaw -> Either String [ASN1] tryExtRawASN1 (ExtensionRaw oid _ content) = case decodeASN1' BER content of Left err -> Left $ "fromASN1: X509.ExtensionRaw: OID=" ++ show oid ++ ": cannot decode data: " ++ show err Right r -> Right r extRawASN1 :: ExtensionRaw -> [ASN1] extRawASN1 extRaw = either error id $ tryExtRawASN1 extRaw {-# DEPRECATED extRawASN1 "use tryExtRawASN1 instead" #-} -- | a Set of 'ExtensionRaw' newtype Extensions = Extensions (Maybe [ExtensionRaw]) deriving (Show,Eq) instance ASN1Object Extensions where toASN1 (Extensions Nothing) = \xs -> xs toASN1 (Extensions (Just exts)) = \xs -> asn1Container (Container Context 3) (asn1Container Sequence (concatMap encodeExt exts)) ++ xs fromASN1 s = runParseASN1State (Extensions <$> parseExtensions) s where parseExtensions = onNextContainerMaybe (Container Context 3) $ onNextContainer Sequence (getMany getObject) instance ASN1Object ExtensionRaw where toASN1 extraw = \xs -> encodeExt extraw ++ xs fromASN1 (Start Sequence:OID oid:xs) = case xs of Boolean b:OctetString obj:End Sequence:xs2 -> Right (ExtensionRaw oid b obj, xs2) OctetString obj:End Sequence:xs2 -> Right (ExtensionRaw oid False obj, xs2) _ -> Left ("fromASN1: X509.ExtensionRaw: unknown format:" ++ show xs) fromASN1 l = Left ("fromASN1: X509.ExtensionRaw: unknown format:" ++ show l) encodeExt :: ExtensionRaw -> [ASN1] encodeExt (ExtensionRaw oid critical content) = asn1Container Sequence ([OID oid] ++ (if critical then [Boolean True] else []) ++ [OctetString content])