diff --git a/Data/Certificate/KeyRSA.hs b/Data/Certificate/KeyRSA.hs
--- a/Data/Certificate/KeyRSA.hs
+++ b/Data/Certificate/KeyRSA.hs
@@ -9,15 +9,32 @@
 --
 
 module Data.Certificate.KeyRSA
-	( decodePrivate
+	( decodePublic
+	, decodePrivate
 	, encodePrivate
+	, parse_RSA
 	) where
 
 import Data.ASN1.DER (encodeASN1Stream, ASN1(..), ASN1ConstructionType(..))
 import Data.ASN1.BER (decodeASN1Stream)
+import Data.ASN1.BitArray
 import qualified Data.ByteString.Lazy as L
 import qualified Crypto.Types.PubKey.RSA as RSA
 
+parsePublic :: [ASN1] -> Either String RSA.PublicKey
+parsePublic
+	[ Start Sequence
+	, Start Sequence
+	, OID [1,2,840,113549,1,1,1] -- PubKeyALG_RSA
+	, Null
+	, End Sequence
+	, BitString (BitArray _ as1n)
+	, End Sequence ] = parse_RSA as1n
+parsePublic _ = Left "unexpected format"
+
+decodePublic :: L.ByteString -> Either String RSA.PublicKey
+decodePublic dat = either (Left . show) parsePublic $ decodeASN1Stream dat
+
 parsePrivate :: [ASN1] -> Either String (RSA.PublicKey, RSA.PrivateKey)
 parsePrivate
 	[ Start Sequence
@@ -70,3 +87,18 @@
 		, IntVal $ fromIntegral $ RSA.private_qinv privkey
 		, End Sequence
 		]
+
+{- | parse a RSA pubkeys from ASN1 encoded bits.
+ - return RSA.PublicKey (len-modulus, modulus, e) if successful -}
+parse_RSA :: L.ByteString -> Either String RSA.PublicKey
+parse_RSA bits =
+	case decodeASN1Stream $ bits of
+		Right [Start Sequence, IntVal modulus, IntVal pubexp, End Sequence] ->
+			Right $ RSA.PublicKey
+				{ RSA.public_size = calculate_modulus modulus 1
+				, RSA.public_n    = modulus
+				, RSA.public_e    = pubexp
+				}
+		_ -> Left "bad RSA format"
+	where
+		calculate_modulus n i = if (2 ^ (i * 8)) > n then i else calculate_modulus n (i+1)
diff --git a/Data/Certificate/X509/Cert.hs b/Data/Certificate/X509/Cert.hs
--- a/Data/Certificate/X509/Cert.hs
+++ b/Data/Certificate/X509/Cert.hs
@@ -44,6 +44,8 @@
 import qualified Crypto.Types.PubKey.RSA as RSA
 import qualified Crypto.Types.PubKey.DSA as DSA
 
+import Data.Certificate.KeyRSA (parse_RSA)
+
 data HashALG =
 	  HashMD2
 	| HashMD5
@@ -110,22 +112,6 @@
 oidOrganization     = [2,5,4,10]
 oidOrganizationUnit = [2,5,4,11]
 
-{- | parse a RSA pubkeys from ASN1 encoded bits.
- - return PubKeyRSA (len-modulus, modulus, e) if successful -}
-parse_RSA :: ByteString -> ParseASN1 PubKey
-parse_RSA bits =
-	case decodeASN1Stream $ bits of
-		Right [Start Sequence, IntVal modulus, IntVal pubexp, End Sequence] ->
-			return $ PubKeyRSA $ RSA.PublicKey
-				{ RSA.public_size = calculate_modulus modulus 1
-				, RSA.public_n    = modulus
-				, RSA.public_e    = pubexp
-				}
-		_ ->
-			throwError ("bad RSA format")
-	where
-		calculate_modulus n i = if (2 ^ (i * 8)) > n then i else calculate_modulus n (i+1)
-
 parse_ECDSA :: ByteString -> ParseASN1 PubKey
 parse_ECDSA bits =
 	case decodeASN1Stream bits of
@@ -249,7 +235,7 @@
 		[OID pkalg,Null] -> do
 			let sig = oidPubKey pkalg
 			case sig of
-				PubKeyALG_RSA -> parse_RSA bits
+				PubKeyALG_RSA -> either (throwError) (return . PubKeyRSA) (parse_RSA bits)
 				_             -> return $ PubKeyUnknown pkalg $ L.unpack bits
 		[OID pkalg,OID _] -> do
 			let sig = oidPubKey pkalg
diff --git a/certificate.cabal b/certificate.cabal
--- a/certificate.cabal
+++ b/certificate.cabal
@@ -1,5 +1,5 @@
 Name:                certificate
-Version:             1.2.2
+Version:             1.2.3
 Description:
     Certificates and Key reader/writer
     .
@@ -31,7 +31,7 @@
                    , mtl
                    , pem >= 0.1 && < 0.2
                    , asn1-data >= 0.6.1.3 && < 0.7
-                   , crypto-pubkey-types
+                   , crypto-pubkey-types >= 0.1 && < 0.2
                    , directory
                    , process
                    , time
