diff --git a/Data/X509.hs b/Data/X509.hs
--- a/Data/X509.hs
+++ b/Data/X509.hs
@@ -16,6 +16,8 @@
     , SignedCRL
     , Certificate(..)
     , PubKey(..)
+    , PubKeyEC(..)
+    , SerializedPoint(..)
     , PrivKey(..)
     , pubkeyToAlg
     , privkeyToAlg
diff --git a/Data/X509/AlgorithmIdentifier.hs b/Data/X509/AlgorithmIdentifier.hs
--- a/Data/X509/AlgorithmIdentifier.hs
+++ b/Data/X509/AlgorithmIdentifier.hs
@@ -29,7 +29,7 @@
 data PubKeyALG =
       PubKeyALG_RSA         -- ^ RSA Public Key algorithm
     | PubKeyALG_DSA         -- ^ DSA Public Key algorithm
-    | PubKeyALG_ECDSA       -- ^ ECDSA Public Key algorithm
+    | PubKeyALG_EC          -- ^ ECDSA & ECDH Public Key algorithm
     | PubKeyALG_DH          -- ^ Diffie Hellman Public Key algorithm
     | PubKeyALG_Unknown OID -- ^ Unknown Public Key algorithm
     deriving (Show,Eq)
@@ -44,7 +44,7 @@
 instance OIDable PubKeyALG where
     getObjectID PubKeyALG_RSA   = [1,2,840,113549,1,1,1]
     getObjectID PubKeyALG_DSA   = [1,2,840,10040,4,1]
-    getObjectID PubKeyALG_ECDSA = [1,2,840,10045,2,1]
+    getObjectID PubKeyALG_EC    = [1,2,840,10045,2,1]
     getObjectID PubKeyALG_DH    = [1,2,840,10046,2,1]
     getObjectID (PubKeyALG_Unknown oid) = oid
 
@@ -58,10 +58,11 @@
         , ([1,2,840,113549,1,1,13], SignatureALG HashSHA512 PubKeyALG_RSA)
         , ([1,2,840,113549,1,1,14], SignatureALG HashSHA224 PubKeyALG_RSA)
         , ([1,2,840,10040,4,3],    SignatureALG HashSHA1 PubKeyALG_DSA)
-        , ([1,2,840,10045,4,3,1],  SignatureALG HashSHA224 PubKeyALG_ECDSA)
-        , ([1,2,840,10045,4,3,2],  SignatureALG HashSHA256 PubKeyALG_ECDSA)
-        , ([1,2,840,10045,4,3,3],  SignatureALG HashSHA384 PubKeyALG_ECDSA)
-        , ([1,2,840,10045,4,3,4],  SignatureALG HashSHA512 PubKeyALG_ECDSA)
+        , ([1,2,840,10045,4,1],    SignatureALG HashSHA1 PubKeyALG_EC)
+        , ([1,2,840,10045,4,3,1],  SignatureALG HashSHA224 PubKeyALG_EC)
+        , ([1,2,840,10045,4,3,2],  SignatureALG HashSHA256 PubKeyALG_EC)
+        , ([1,2,840,10045,4,3,3],  SignatureALG HashSHA384 PubKeyALG_EC)
+        , ([1,2,840,10045,4,3,4],  SignatureALG HashSHA512 PubKeyALG_EC)
         ]
 
 oidSig :: OID -> SignatureALG
diff --git a/Data/X509/CRL.hs b/Data/X509/CRL.hs
--- a/Data/X509/CRL.hs
+++ b/Data/X509/CRL.hs
@@ -66,10 +66,10 @@
         <*> getRevokedCertificates
         <*> getObject
   where getVersion (IntVal v) = return $ fromIntegral v
-        getVersion _          = throwError "unexpected type for version"
+        getVersion _          = throwParseError "unexpected type for version"
 
         getThisUpdate (ASN1Time _ t1 _) = return t1
-        getThisUpdate _                 = throwError "bad this update format, expecting time"
+        getThisUpdate _                 = throwParseError "bad this update format, expecting time"
 
         getNextUpdate = getNextMaybe timeOrNothing
 
diff --git a/Data/X509/Cert.hs b/Data/X509/Cert.hs
--- a/Data/X509/Cert.hs
+++ b/Data/X509/Cert.hs
@@ -55,19 +55,19 @@
 parseCertHeaderVersion =
     maybe 1 id <$> onNextContainerMaybe (Container Context 0) (getNext >>= getVer)
   where getVer (IntVal v) = return $ fromIntegral v
-        getVer _          = throwError "unexpected type for version"
+        getVer _          = throwParseError "unexpected type for version"
 
 parseCertHeaderSerial :: ParseASN1 Integer
 parseCertHeaderSerial = do
     n <- getNext
     case n of
         IntVal v -> return v
-        _        -> throwError ("missing serial" ++ show n)
+        _        -> throwParseError ("missing serial" ++ show n)
 
 parseCertHeaderValidity :: ParseASN1 (DateTime, DateTime)
 parseCertHeaderValidity = getNextContainer Sequence >>= toTimeBound
   where toTimeBound [ ASN1Time _ t1 _, ASN1Time _ t2 _ ] = return (t1,t2)
-        toTimeBound _                                    = throwError "bad validity format"
+        toTimeBound _                                    = throwParseError "bad validity format"
 
 {- | parse header structure of a x509 certificate. the structure is the following:
         Version
diff --git a/Data/X509/DistinguishedName.hs b/Data/X509/DistinguishedName.hs
--- a/Data/X509/DistinguishedName.hs
+++ b/Data/X509/DistinguishedName.hs
@@ -74,7 +74,7 @@
     s <- getNextContainer Sequence
     case s of
         [OID oid, ASN1String cs] -> return (oid, cs)
-        _                        -> throwError ("expecting [OID,String] got " ++ show s)
+        _                        -> throwParseError ("expecting [OID,String] got " ++ show s)
 
 encodeDNinner :: DistinguishedName -> [ASN1]
 encodeDNinner (DistinguishedName dn) = concatMap dnSet dn
diff --git a/Data/X509/Ext.hs b/Data/X509/Ext.hs
--- a/Data/X509/Ext.hs
+++ b/Data/X509/Ext.hs
@@ -265,19 +265,19 @@
                     case c of
                         Just [ASN1String cs] ->
                             case asn1CharacterToString cs of
-                                Nothing -> throwError ("GeneralNames: invalid string for XMPP Addr")
+                                Nothing -> throwParseError ("GeneralNames: invalid string for XMPP Addr")
                                 Just s  -> return $ AltNameXMPP s
-                        _ -> throwError ("GeneralNames: expecting string for XMPP Addr got: " ++ show c)
+                        _ -> throwParseError ("GeneralNames: expecting string for XMPP Addr got: " ++ show c)
                 OID [1,3,6,1,5,5,7,8,7] -> do -- DNSSRV addr
                     c <- getNextContainerMaybe (Container Context 0)
                     case c of
                         Just [ASN1String cs] ->
                             case asn1CharacterToString cs of
-                                Nothing -> throwError ("GeneralNames: invalid string for DNSSrv Addr")
+                                Nothing -> throwParseError ("GeneralNames: invalid string for DNSSrv Addr")
                                 Just s  -> return $ AltNameDNSSRV s
-                        _ -> throwError ("GeneralNames: expecting string for DNSSRV Addr got: " ++ show c)
-                OID unknown -> throwError ("GeneralNames: unknown OID " ++ show unknown)
-                _           -> throwError ("GeneralNames: expecting OID but got " ++ show n)
+                        _ -> throwParseError ("GeneralNames: expecting string for DNSSRV Addr got: " ++ show c)
+                OID unknown -> throwParseError ("GeneralNames: unknown OID " ++ show unknown)
+                _           -> throwParseError ("GeneralNames: expecting OID but got " ++ show n)
 
         getSimpleAddr = do
             n <- getNext
@@ -286,7 +286,7 @@
                 (Other Context 2 b) -> return $ AltNameDNS $ BC.unpack b
                 (Other Context 6 b) -> return $ AltNameURI $ BC.unpack b
                 (Other Context 7 b) -> return $ AltNameIP  b
-                _                   -> throwError ("GeneralNames: not coping with unknown stream " ++ show n)
+                _                   -> throwParseError ("GeneralNames: not coping with unknown stream " ++ show n)
 
 encodeGeneralNames :: [AltName] -> [ASN1]
 encodeGeneralNames names =
diff --git a/Data/X509/Internal.hs b/Data/X509/Internal.hs
--- a/Data/X509/Internal.hs
+++ b/Data/X509/Internal.hs
@@ -13,7 +13,6 @@
     -- * error handling
     , ErrT
     , runErrT
-    , throwError
     ) where
 
 import Data.ASN1.Types
diff --git a/Data/X509/PublicKey.hs b/Data/X509/PublicKey.hs
--- a/Data/X509/PublicKey.hs
+++ b/Data/X509/PublicKey.hs
@@ -9,6 +9,8 @@
 --
 module Data.X509.PublicKey
     ( PubKey(..)
+    , PubKeyEC(..)
+    , SerializedPoint(..)
     , pubkeyToAlg
     ) where
 
@@ -18,6 +20,7 @@
 import Data.ASN1.BitArray
 
 import Data.Bits
+import Data.ByteString (ByteString)
 
 import Data.X509.Internal
 import Data.X509.OID
@@ -26,17 +29,42 @@
 import qualified Crypto.PubKey.RSA.Types as RSA
 import qualified Crypto.PubKey.DSA       as DSA
 import qualified Crypto.PubKey.ECC.Types as ECC
+import           Crypto.Number.Serialize (os2ip)
 import Data.Word
 
 import qualified Data.ByteString as B
 
+-- | Serialized Elliptic Curve Point
+newtype SerializedPoint = SerializedPoint ByteString
+    deriving (Show,Eq)
+
+-- | Elliptic Curve Public Key
+--
+-- TODO: missing support for binary curve.
+data PubKeyEC =
+      PubKeyEC_Prime
+        { pubkeyEC_pub       :: SerializedPoint
+        , pubkeyEC_a         :: Integer
+        , pubkeyEC_b         :: Integer
+        , pubkeyEC_prime     :: Integer
+        , pubkeyEC_generator :: SerializedPoint
+        , pubkeyEC_order     :: Integer
+        , pubkeyEC_cofactor  :: Integer
+        , pubkeyEC_seed      :: Integer
+        }
+    | PubKeyEC_Named
+        { pubkeyEC_name      :: ECC.CurveName
+        , pubkeyEC_pub       :: SerializedPoint
+        }
+    deriving (Show,Eq)
+
 -- | Public key types known and used in X.509
 data PubKey =
       PubKeyRSA RSA.PublicKey -- ^ RSA public key
     | PubKeyDSA DSA.PublicKey -- ^ DSA public key
     | PubKeyDH (Integer,Integer,Integer,Maybe Integer,([Word8], Integer))
                                 -- ^ DH format with (p,g,q,j,(seed,pgenCounter))
-    | PubKeyECDSA ECC.CurveName B.ByteString
+    | PubKeyEC PubKeyEC       -- ^ EC public key
     | PubKeyUnknown OID B.ByteString -- ^ unrecognized format
     deriving (Show,Eq)
 
@@ -67,13 +95,43 @@
                         _ -> Left "fromASN1: X509.PubKey: unknown DSA format"
                         )
                 _ -> Left "fromASN1: X509.PubKey: unknown DSA format"
-        | pkalg == getObjectID PubKeyALG_ECDSA =
+        | pkalg == getObjectID PubKeyALG_EC =
             case xs of
                 OID curveOid:End Sequence:BitString bits:End Sequence:xs2 ->
                     case lookupByOID curvesOIDTable curveOid of
-                        Just curveName -> Right (PubKeyECDSA curveName (bitArrayGetData bits), xs2)
-                        Nothing        -> Left ("fromASN1: X509.Pubkey: ECDSA unknown curve " ++ show curveOid)
-                _ -> Left "fromASN1: X509.PubKey: unknown ECDSA format"
+                        Just curveName -> Right (PubKeyEC $ PubKeyEC_Named curveName (bitArrayToPoint bits), xs2)
+                        Nothing        -> Left ("fromASN1: X509.Pubkey: EC unknown curve " ++ show curveOid)
+                Start Sequence
+                    :IntVal 1
+                    :Start Sequence
+                    :OID [1,2,840,10045,1,1]
+                    :IntVal prime
+                    :End Sequence
+                    :Start Sequence
+                    :OctetString a
+                    :OctetString b
+                    :BitString seed
+                    :End Sequence
+                    :OctetString generator
+                    :IntVal order
+                    :IntVal cofactor
+                    :End Sequence
+                    :End Sequence
+                    :BitString pub
+                    :End Sequence
+                    :xs2 ->
+                    Right (PubKeyEC $ PubKeyEC_Prime
+                        { pubkeyEC_pub       = bitArrayToPoint pub
+                        , pubkeyEC_a         = os2ip a
+                        , pubkeyEC_b         = os2ip b
+                        , pubkeyEC_prime     = prime
+                        , pubkeyEC_generator = SerializedPoint generator
+                        , pubkeyEC_order     = order
+                        , pubkeyEC_cofactor  = cofactor
+                        , pubkeyEC_seed      = os2ip $ bitArrayGetData seed
+                        }, xs2)
+                _ ->
+                    Left $ "fromASN1: X509.PubKey: unknown EC format: " ++ show xs
         | otherwise = error ("unknown public key OID: " ++ show pkalg)
       where decodeASN1Err format bits xs2 f =
                 case decodeASN1' BER (bitArrayGetData bits) of
@@ -83,6 +141,8 @@
                                     Right (r, xsinner) -> Right (r, xsinner ++ xs2)
             toPubKeyRSA = either Left (\(rsaKey, r) -> Right (PubKeyRSA rsaKey, r))
 
+            bitArrayToPoint = SerializedPoint . bitArrayGetData
+
             removeNull (Null:r) = r
             removeNull l        = l
 
@@ -94,7 +154,7 @@
 pubkeyToAlg (PubKeyRSA _)         = PubKeyALG_RSA
 pubkeyToAlg (PubKeyDSA _)         = PubKeyALG_DSA
 pubkeyToAlg (PubKeyDH _)          = PubKeyALG_DH
-pubkeyToAlg (PubKeyECDSA _ _)     = PubKeyALG_ECDSA
+pubkeyToAlg (PubKeyEC _)          = PubKeyALG_EC
 pubkeyToAlg (PubKeyUnknown oid _) = PubKeyALG_Unknown oid
 
 encodePK :: PubKey -> [ASN1]
@@ -112,12 +172,14 @@
                                         ,IntVal (DSA.params_g params)]
         params = DSA.public_params pubkey
         bits   = encodeASN1' DER [IntVal $ DSA.public_y pubkey]
-    encodeInner (PubKeyECDSA curveName bits) =
+    encodeInner (PubKeyEC (PubKeyEC_Named curveName (SerializedPoint bits))) =
         asn1Container Sequence [pkalg,OID eOid] ++ [BitString $ toBitArray bits 0]
       where
         eOid = case curveName of
                     ECC.SEC_p384r1 -> [1,3,132,0,34]
                     _              -> error ("undefined curve OID: " ++ show curveName)
+    encodeInner (PubKeyEC (PubKeyEC_Prime {})) =
+        error "encodeInner: unimplemented public key EC_Prime"
     encodeInner (PubKeyDH _) = error "encodeInner: unimplemented public key DH"
     encodeInner (PubKeyUnknown _ l) =
         asn1Container Sequence [pkalg,Null] ++ [BitString $ toBitArray l 0]
diff --git a/x509.cabal b/x509.cabal
--- a/x509.cabal
+++ b/x509.cabal
@@ -1,5 +1,5 @@
 Name:                x509
-Version:             1.6.1
+Version:             1.6.2
 Description:         X509 reader and writer
 License:             BSD3
 License-file:        LICENSE
@@ -21,9 +21,9 @@
                    , containers
                    , hourglass
                    , pem >= 0.1 && < 0.3
-                   , asn1-types >= 0.3.0 && < 0.4
+                   , asn1-types >= 0.3.1 && < 0.4
                    , asn1-encoding >= 0.9 && < 0.10
-                   , asn1-parse >= 0.9 && < 0.10
+                   , asn1-parse >= 0.9.3 && < 0.10
                    , cryptonite
   Exposed-modules:   Data.X509
   Other-modules:     Data.X509.Internal
