diff --git a/Data/X509.hs b/Data/X509.hs
--- a/Data/X509.hs
+++ b/Data/X509.hs
@@ -19,6 +19,7 @@
     , PubKeyEC(..)
     , SerializedPoint(..)
     , PrivKey(..)
+    , PrivKeyEC(..)
     , pubkeyToAlg
     , privkeyToAlg
     , module Data.X509.AlgorithmIdentifier
diff --git a/Data/X509/AlgorithmIdentifier.hs b/Data/X509/AlgorithmIdentifier.hs
--- a/Data/X509/AlgorithmIdentifier.hs
+++ b/Data/X509/AlgorithmIdentifier.hs
@@ -95,6 +95,8 @@
         Right (oidSig oid, xs)
     fromASN1 (Start Sequence:OID [1,2,840,113549,1,1,10]:Start Sequence:Start _:Start Sequence:OID hash1:End Sequence:End _:Start _:Start Sequence:OID [1,2,840,113549,1,1,8]:Start Sequence:OID _hash2:End Sequence:End Sequence:End _:Start _: IntVal _iv: End _: End Sequence : End Sequence:xs) =
         Right (oidSig hash1, xs)
+    fromASN1 (Start Sequence:OID [1,2,840,113549,1,1,10]:Start Sequence:Start _:Start Sequence:OID hash1:Null:End Sequence:End _:Start _:Start Sequence:OID [1,2,840,113549,1,1,8]:Start Sequence:OID _hash2:Null:End Sequence:End Sequence:End _:Start _: IntVal _iv: End _: End Sequence : End Sequence:xs) =
+        Right (oidSig hash1, xs)
     fromASN1 _ =
         Left "fromASN1: X509.SignatureALG: unknown format"
     toASN1 signatureAlg@(SignatureALG hashAlg PubKeyALG_RSAPSS) = \xs -> Start Sequence:OID [1,2,840,113549,1,1,10]:Start Sequence:Start (Container Context 0):Start Sequence:OID (sigOID signatureAlg):End Sequence:End (Container Context 0):Start (Container Context 1): Start Sequence:OID [1,2,840,113549,1,1,8]:Start Sequence:OID (sigOID signatureAlg):End Sequence:End Sequence:End (Container Context 1):Start (Container Context 2):IntVal (saltLen hashAlg):End (Container Context 2):End Sequence:End Sequence:xs
diff --git a/Data/X509/Cert.hs b/Data/X509/Cert.hs
--- a/Data/X509/Cert.hs
+++ b/Data/X509/Cert.hs
@@ -53,7 +53,7 @@
 
 parseCertHeaderVersion :: ParseASN1 Int
 parseCertHeaderVersion =
-    maybe 1 id <$> onNextContainerMaybe (Container Context 0) (getNext >>= getVer)
+    maybe 0 id <$> onNextContainerMaybe (Container Context 0) (getNext >>= getVer)
   where getVer (IntVal v) = return $ fromIntegral v
         getVer _          = throwParseError "unexpected type for version"
 
diff --git a/Data/X509/EC.hs b/Data/X509/EC.hs
new file mode 100644
--- /dev/null
+++ b/Data/X509/EC.hs
@@ -0,0 +1,126 @@
+-- |
+-- Module      : Data.X509.EC
+-- License     : BSD-style
+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
+-- Stability   : experimental
+-- Portability : unknown
+--
+-- Utilities related to Elliptic Curve certificates and keys.
+--
+module Data.X509.EC
+    (
+      unserializePoint
+    , ecPubKeyCurve
+    , ecPubKeyCurveName
+    , ecPrivKeyCurve
+    , ecPrivKeyCurveName
+    , lookupCurveNameByOID
+    ) where
+
+import Data.ASN1.OID
+import Data.List (find)
+
+import Data.X509.OID
+import Data.X509.PublicKey
+import Data.X509.PrivateKey
+
+import qualified Crypto.PubKey.ECC.Prim  as ECC
+import qualified Crypto.PubKey.ECC.Types as ECC
+import           Crypto.Number.Serialize (os2ip)
+
+import qualified Data.ByteString as B
+
+-- | Read an EC point from a serialized format and make sure the point is
+-- valid for the specified curve.
+unserializePoint :: ECC.Curve -> SerializedPoint -> Maybe ECC.Point
+unserializePoint curve (SerializedPoint bs) =
+    case B.uncons bs of
+        Nothing                -> Nothing
+        Just (ptFormat, input) ->
+            case ptFormat of
+                4 -> if B.length input /= 2 * bytes
+                        then Nothing
+                        else
+                            let (x, y) = B.splitAt bytes input
+                                p      = ECC.Point (os2ip x) (os2ip y)
+                             in if ECC.isPointValid curve p
+                                    then Just p
+                                    else Nothing
+                -- 2 and 3 for compressed format.
+                _ -> Nothing
+  where bits  = ECC.curveSizeBits curve
+        bytes = (bits + 7) `div` 8
+
+-- | Return the curve associated to an EC Public Key.  This does not check
+-- if a curve in explicit format is valid: if the input is not trusted one
+-- should consider 'ecPubKeyCurveName' instead.
+ecPubKeyCurve :: PubKeyEC -> Maybe ECC.Curve
+ecPubKeyCurve (PubKeyEC_Named name _) = Just $ ECC.getCurveByName name
+ecPubKeyCurve pub@PubKeyEC_Prime{}    =
+    fmap buildCurve $
+        unserializePoint (buildCurve undefined) (pubkeyEC_generator pub)
+  where
+    prime = pubkeyEC_prime pub
+    buildCurve g =
+        let cc = ECC.CurveCommon
+                     { ECC.ecc_a = pubkeyEC_a        pub
+                     , ECC.ecc_b = pubkeyEC_b        pub
+                     , ECC.ecc_g = g
+                     , ECC.ecc_n = pubkeyEC_order    pub
+                     , ECC.ecc_h = pubkeyEC_cofactor pub
+                     }
+         in ECC.CurveFP (ECC.CurvePrime prime cc)
+
+-- | Return the name of a standard curve associated to an EC Public Key
+ecPubKeyCurveName :: PubKeyEC -> Maybe ECC.CurveName
+ecPubKeyCurveName (PubKeyEC_Named name _) = Just name
+ecPubKeyCurveName pub@PubKeyEC_Prime{}    =
+    find matchPrimeCurve $ enumFrom $ toEnum 0
+  where
+    matchPrimeCurve c =
+        case ECC.getCurveByName c of
+            ECC.CurveFP (ECC.CurvePrime p cc) ->
+                ECC.ecc_a cc == pubkeyEC_a pub     &&
+                ECC.ecc_b cc == pubkeyEC_b pub     &&
+                ECC.ecc_n cc == pubkeyEC_order pub &&
+                p            == pubkeyEC_prime pub
+            _                                 -> False
+
+-- | Return the EC curve associated to an EC Private Key.  This does not check
+-- if a curve in explicit format is valid: if the input is not trusted one
+-- should consider 'ecPrivKeyCurveName' instead.
+ecPrivKeyCurve :: PrivKeyEC -> Maybe ECC.Curve
+ecPrivKeyCurve (PrivKeyEC_Named name _) = Just $ ECC.getCurveByName name
+ecPrivKeyCurve priv@PrivKeyEC_Prime{}   =
+    fmap buildCurve $
+        unserializePoint (buildCurve undefined) (privkeyEC_generator priv)
+  where
+    prime = privkeyEC_prime priv
+    buildCurve g =
+        let cc = ECC.CurveCommon
+                     { ECC.ecc_a = privkeyEC_a        priv
+                     , ECC.ecc_b = privkeyEC_b        priv
+                     , ECC.ecc_g = g
+                     , ECC.ecc_n = privkeyEC_order    priv
+                     , ECC.ecc_h = privkeyEC_cofactor priv
+                     }
+         in ECC.CurveFP (ECC.CurvePrime prime cc)
+
+-- | Return the name of a standard curve associated to an EC Private Key
+ecPrivKeyCurveName :: PrivKeyEC -> Maybe ECC.CurveName
+ecPrivKeyCurveName (PrivKeyEC_Named name _) = Just name
+ecPrivKeyCurveName priv@PrivKeyEC_Prime{}   =
+    find matchPrimeCurve $ enumFrom $ toEnum 0
+  where
+    matchPrimeCurve c =
+        case ECC.getCurveByName c of
+            ECC.CurveFP (ECC.CurvePrime p cc) ->
+                ECC.ecc_a cc == privkeyEC_a priv     &&
+                ECC.ecc_b cc == privkeyEC_b priv     &&
+                ECC.ecc_n cc == privkeyEC_order priv &&
+                p            == privkeyEC_prime priv
+            _                                 -> False
+
+-- | Return the curve name associated to an OID
+lookupCurveNameByOID :: OID -> Maybe ECC.CurveName
+lookupCurveNameByOID = lookupByOID curvesOIDTable
diff --git a/Data/X509/PrivateKey.hs b/Data/X509/PrivateKey.hs
--- a/Data/X509/PrivateKey.hs
+++ b/Data/X509/PrivateKey.hs
@@ -5,25 +5,50 @@
 -- Stability   : experimental
 -- Portability : unknown
 --
--- Public key handling in X.509 infrastructure
+-- Private key handling in X.509 infrastructure
 --
 module Data.X509.PrivateKey
     ( PrivKey(..)
+    , PrivKeyEC(..)
     , privkeyToAlg
     ) where
 
 import Data.X509.AlgorithmIdentifier
+import Data.X509.PublicKey (SerializedPoint(..))
 import qualified Crypto.PubKey.RSA as RSA
 import qualified Crypto.PubKey.DSA as DSA
+import qualified Crypto.PubKey.ECC.Types as ECC
 
+-- | Elliptic Curve Private Key
+--
+-- TODO: missing support for binary curve.
+data PrivKeyEC =
+      PrivKeyEC_Prime
+        { privkeyEC_priv      :: Integer
+        , privkeyEC_a         :: Integer
+        , privkeyEC_b         :: Integer
+        , privkeyEC_prime     :: Integer
+        , privkeyEC_generator :: SerializedPoint
+        , privkeyEC_order     :: Integer
+        , privkeyEC_cofactor  :: Integer
+        , privkeyEC_seed      :: Integer
+        }
+    | PrivKeyEC_Named
+        { privkeyEC_name      :: ECC.CurveName
+        , privkeyEC_priv      :: Integer
+        }
+    deriving (Show,Eq)
+
 -- | Private key types known and used in X.509
 data PrivKey =
       PrivKeyRSA RSA.PrivateKey -- ^ RSA private key
     | PrivKeyDSA DSA.PrivateKey -- ^ DSA private key
+    | PrivKeyEC  PrivKeyEC      -- ^ EC private key
     deriving (Show,Eq)
 
--- | Convert a Public key to the Public Key Algorithm type
+-- | Convert a Private key to the Public Key Algorithm type
 privkeyToAlg :: PrivKey -> PubKeyALG
 privkeyToAlg (PrivKeyRSA _)         = PubKeyALG_RSA
 privkeyToAlg (PrivKeyDSA _)         = PubKeyALG_DSA
+privkeyToAlg (PrivKeyEC _)          = PubKeyALG_EC
 
diff --git a/x509.cabal b/x509.cabal
--- a/x509.cabal
+++ b/x509.cabal
@@ -1,5 +1,5 @@
 Name:                x509
-version:             1.7.1
+version:             1.7.2
 Description:         X509 reader and writer
 License:             BSD3
 License-file:        LICENSE
@@ -25,8 +25,9 @@
                    , asn1-types >= 0.3.1 && < 0.4
                    , asn1-encoding >= 0.9 && < 0.10
                    , asn1-parse >= 0.9.3 && < 0.10
-                   , cryptonite
+                   , cryptonite >= 0.8
   Exposed-modules:   Data.X509
+                     Data.X509.EC
   Other-modules:     Data.X509.Internal
                      Data.X509.CertificateChain
                      Data.X509.AlgorithmIdentifier
