Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] [help-wanted] What format of public keys can be decoded? #100

Open
ecthiender opened this issue Aug 2, 2018 · 4 comments
Open

Comments

@ecthiender
Copy link

I'm a little confused with what format of public keys can be decoded by the x509 package? (Also I'm not really super familiar with crypto formats etc.)

I have a public key in two formats generated via openssh (converted using openssl):

  • PKCS1:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA7Iuqbid12peSqm8btHL2ddLcqEzHH50ImHyr0+CE6fZedR4Fmfj/
DnLkp3LWCcf5/qgtgPP/XvLQprTk5Y5xipPf99qmcqnQ/iCzHqoN8FWds2M4ssXS
Ggst6iUGj/71kTKBIWwna5ID4lg+/k9e57hmHFEbVEpnJK9ApM9gSBnqiqQE8P4/
Cdy4mYJ2bfIg3jf8RrTgdtfpNMDooZJfDMPyx1vOm9T9YuhyQ2eqsUlQB5+5Q9Mp
KQxTNBr6Qzq00nI9dEUkCg48KYqQekN9bjAGgobzAMRv0tN50GjpcCFD7KofzlSG
zj0NzABB5niWopb520p8Sz6S9emm9PxUgQIDAQAB
-----END RSA PUBLIC KEY-----

and

  • PKCS8:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Iuqbid12peSqm8btHL2
ddLcqEzHH50ImHyr0+CE6fZedR4Fmfj/DnLkp3LWCcf5/qgtgPP/XvLQprTk5Y5x
ipPf99qmcqnQ/iCzHqoN8FWds2M4ssXSGgst6iUGj/71kTKBIWwna5ID4lg+/k9e
57hmHFEbVEpnJK9ApM9gSBnqiqQE8P4/Cdy4mYJ2bfIg3jf8RrTgdtfpNMDooZJf
DMPyx1vOm9T9YuhyQ2eqsUlQB5+5Q9MpKQxTNBr6Qzq00nI9dEUkCg48KYqQekN9
bjAGgobzAMRv0tN50GjpcCFD7KofzlSGzj0NzABB5niWopb520p8Sz6S9emm9PxU
gQIDAQAB
-----END PUBLIC KEY-----

Now I'm using pem to read the file first, and then trying to decodeSignedObject it. Is that correct?

import qualified Data.PEM as PEM
import qualified Data.X509 as X509
import qualified Data.ByteString as B

main :: IO ()
main = do
  rc <- B.readFile "test_rsa.pub.pkcs1"  -- "test_rsa.pub.pkcs8"
  let Right [pem] = PEM.parseBS rc
  let res = X509.decodeSignedObject (PEM.pemContent pem) :: Either String (X509.SignedExact X509.PubKey)
  print res

I get the following output, with:

  • PKCS1:
    Left "signed object error: \"fromASN1: X509.PubKey: unknown format:[]\""
  • PKCS8:
    Left "signed object error: \"fromASN1: X509.PubKey: unknown format:[OID [1,2,840,113549,1,1,1],Null]\""

How can I decode a public key from any of these popular formats of public key?

@ecthiender ecthiender changed the title What format of public keys can be decoded? [question] [help-wanted] What format of public keys can be decoded? Aug 2, 2018
@ecthiender
Copy link
Author

Ok, after searching around, I kind of understand. I cannot use decodeSignedObject because I'm not using a signed certificate. I'm just using the public key. So x509 is not going to help me here?

I actually discovered https://hackage.haskell.org/package/certificate-1.3.9 first and found out that is deprecated. Ideally, I would need the decodePublic function from Data.Certificate.KeyRSA in certificate package. But as this is deprecated, I can't seem to find any package/function which will help.

Any help in the right direction would be much appreciated!

@ocheron
Copy link
Contributor

ocheron commented Aug 2, 2018

You can use the ASN1Object instance like this:

import qualified Data.PEM as PEM
import qualified Data.X509 as X509
import qualified Data.ByteString as B

import Data.ASN1.BinaryEncoding
import Data.ASN1.Types
import Data.ASN1.Encoding

main :: IO ()
main = do
  rc <- B.readFile "test_rsa.pub.pkcs8"
  let Right [pem] = PEM.pemParseBS rc
      Right asn1 = decodeASN1' BER (PEM.pemContent pem)
      Right (pub, []) = fromASN1 asn1
  print (pub :: X509.PubKey)

(with help from packages asn1-types and asn1-encoding)

@ecthiender
Copy link
Author

ecthiender commented Aug 3, 2018

Thanks! So this works for PKCS8 formats. Is PKCS1 format also an instance of ASN1Object ? Do I have to decodeASN1 in a different way (for PKCS1) ?

@ocheron
Copy link
Contributor

ocheron commented Aug 5, 2018

The ASN1Object instance implements format SubjectPublicKeyInfo, i.e. the one used in X.509 certificates.

The PKCS#1 format you referenced maps to the BitString inside this structure and is only possible for RSA because the algorithm has no parameter. I don't think there is API for this currently.

Btw PKCS#8 is a format for private keys, not public keys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants