Pass X509Certificate as String?

Discussion in 'Java' started by Ian Pilcher, Feb 8, 2013.

  1. Ian Pilcher

    Ian Pilcher Guest

    This is a bit weird. I am writing an SSLSocketFactory for use with the
    PostgreSQL JDBC driver. Unfortunately, the driver imposes some very
    inconvenient criteria on the factory class.

    http://jdbc.postgresql.org/documentation/91/ssl-factory.html

    In particular, the class must have a zero-argument constructor or a
    constructor that takes a single String argument. My challenge is to
    somehow pass a java.security.cert.X509Certificate to this constructor.

    The only idea I've been able to come up with thus far is to serialize
    the certificate to a ByteArrayOutputStream, convert that to a String,
    and reverse the process in the constructor.

    Does anyone have a better idea?

    If not, is there a character set that can handle all values 0-255?

    Thanks!

    --
    ========================================================================
    Ian Pilcher
    Sometimes there's nothing left to do but crash and burn...or die trying.
    ========================================================================
     
    Ian Pilcher, Feb 8, 2013
    #1
    1. Advertising

  2. Ian Pilcher

    Arne Vajhøj Guest

    On 2/8/2013 6:48 PM, Ian Pilcher wrote:
    > This is a bit weird. I am writing an SSLSocketFactory for use with the
    > PostgreSQL JDBC driver. Unfortunately, the driver imposes some very
    > inconvenient criteria on the factory class.
    >
    > http://jdbc.postgresql.org/documentation/91/ssl-factory.html
    >
    > In particular, the class must have a zero-argument constructor or a
    > constructor that takes a single String argument. My challenge is to
    > somehow pass a java.security.cert.X509Certificate to this constructor.
    >
    > The only idea I've been able to come up with thus far is to serialize
    > the certificate to a ByteArrayOutputStream, convert that to a String,
    > and reverse the process in the constructor.
    >
    > Does anyone have a better idea?


    I believe it is common to use Bas64 encoding of DER encoding
    of the certificate.

    Maybe you can use that!?

    Arne
     
    Arne Vajhøj, Feb 9, 2013
    #2
    1. Advertising

  3. Ian Pilcher

    Arne Vajhøj Guest

    On 2/8/2013 7:12 PM, Arne Vajhøj wrote:
    > On 2/8/2013 6:48 PM, Ian Pilcher wrote:
    >> This is a bit weird. I am writing an SSLSocketFactory for use with the
    >> PostgreSQL JDBC driver. Unfortunately, the driver imposes some very
    >> inconvenient criteria on the factory class.
    >>
    >> http://jdbc.postgresql.org/documentation/91/ssl-factory.html
    >>
    >> In particular, the class must have a zero-argument constructor or a
    >> constructor that takes a single String argument. My challenge is to
    >> somehow pass a java.security.cert.X509Certificate to this constructor.
    >>
    >> The only idea I've been able to come up with thus far is to serialize
    >> the certificate to a ByteArrayOutputStream, convert that to a String,
    >> and reverse the process in the constructor.
    >>
    >> Does anyone have a better idea?

    >
    > I believe it is common to use Bas64 encoding of DER encoding
    > of the certificate.
    >
    > Maybe you can use that!?


    The methods must be getInstance and getEncoded.

    Arne
     
    Arne Vajhøj, Feb 9, 2013
    #3
  4. Ian Pilcher

    Arne Vajhøj Guest

    On 2/8/2013 7:21 PM, Arne Vajhøj wrote:
    > On 2/8/2013 7:12 PM, Arne Vajhøj wrote:
    >> On 2/8/2013 6:48 PM, Ian Pilcher wrote:
    >>> This is a bit weird. I am writing an SSLSocketFactory for use with the
    >>> PostgreSQL JDBC driver. Unfortunately, the driver imposes some very
    >>> inconvenient criteria on the factory class.
    >>>
    >>> http://jdbc.postgresql.org/documentation/91/ssl-factory.html
    >>>
    >>> In particular, the class must have a zero-argument constructor or a
    >>> constructor that takes a single String argument. My challenge is to
    >>> somehow pass a java.security.cert.X509Certificate to this constructor.
    >>>
    >>> The only idea I've been able to come up with thus far is to serialize
    >>> the certificate to a ByteArrayOutputStream, convert that to a String,
    >>> and reverse the process in the constructor.
    >>>
    >>> Does anyone have a better idea?

    >>
    >> I believe it is common to use Bas64 encoding of DER encoding
    >> of the certificate.
    >>
    >> Maybe you can use that!?

    >
    > The methods must be getInstance and getEncoded.


    Code snippet:

    public static String b64encode(byte[] b) throws MessagingException,
    IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    OutputStream b64os = MimeUtility.encode(baos, "base64");
    b64os.write(b);
    b64os.close();
    return new String(baos.toByteArray());
    }
    public static byte[] b64decode(String s) throws
    MessagingException, IOException {
    ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes());
    InputStream b64is = MimeUtility.decode(bais, "Base64");
    byte[] tmp = new byte[s.length()];
    int n = b64is.read(tmp);
    byte[] res = new byte[n];
    System.arraycopy(tmp, 0, res, 0, n);
    return res;
    }
    public static String encode(X509Certificate cert) throws
    CertificateEncodingException, MessagingException, IOException {
    return b64encode(cert.getEncoded());
    }
    public static X509Certificate decode(String s) throws
    CertificateException, MessagingException, IOException {
    return X509Certificate.getInstance(b64decode(s));
    }

    Arne
     
    Arne Vajhøj, Feb 9, 2013
    #4
  5. Ian Pilcher

    Ian Pilcher Guest

    On 02/08/2013 06:35 PM, � wrote:
    >>
    >> The methods must be getInstance and getEncoded.

    >
    > Code snippet:
    >


    You're as literal-minded as I am. :) (BTW, I also found base64
    encode/decode methods in javax.xml.bind.DatatypeConverter.)

    The cluebat fairy visited me, and I realized that it will be far more
    efficient to simply "register" my CA certificate by name before
    connecting to the database.

    final class JdbcSSLSocketFactory extends SSLSocketFactory
    {
    private final static Map<String,X509Certificate> caCerts = new
    HashMap<>();

    public static void registerCA(String caName, X509Certificate caCert)
    {
    if (caName == null || caCert == null) {
    throw new IllegalArgumentException(String.format(
    "null value not allowed for %s",
    caName == null ? "caName" : "caCert"));
    caCerts.put(caName, caCert);
    }

    public JdbcSSLSocketFactory(String caName)
    {
    try {
    X509Certificate caCert = caCerts.get(caName);
    if (caCert == null) {
    throw new IllegalStateException(String.format(
    "No certificate authority named '%s' has been registered",
    caName));
    }

    ...

    Thanks!

    --
    ========================================================================
    Ian Pilcher
    Sometimes there's nothing left to do but crash and burn...or die trying.
    ========================================================================
     
    Ian Pilcher, Feb 9, 2013
    #5
  6. On 2/8/2013 7:50 PM, Ian Pilcher wrote:
    > On 02/08/2013 06:35 PM, � wrote:
    >>>
    >>> The methods must be getInstance and getEncoded.

    >>
    >> Code snippet:
    >>

    >
    > You're as literal-minded as I am. :) (BTW, I also found base64
    > encode/decode methods in javax.xml.bind.DatatypeConverter.)


    Ah. That will get rid of the two b64 methods. Thanks.

    > The cluebat fairy visited me, and I realized that it will be far more
    > efficient to simply "register" my CA certificate by name before
    > connecting to the database.


    :)

    Arne
     
    Arne Vajhøj, Feb 9, 2013
    #6
  7. On 2/8/2013 7:57 PM, Arne Vajhøj wrote:
    > On 2/8/2013 7:50 PM, Ian Pilcher wrote:
    >> On 02/08/2013 06:35 PM, � wrote:
    >>>>
    >>>> The methods must be getInstance and getEncoded.
    >>>
    >>> Code snippet:
    >>>

    >>
    >> You're as literal-minded as I am. :) (BTW, I also found base64
    >> encode/decode methods in javax.xml.bind.DatatypeConverter.)

    >
    > Ah. That will get rid of the two b64 methods. Thanks.


    public static String encode(X509Certificate cert) throws
    CertificateEncodingException, MessagingException, IOException {
    return DatatypeConverter.printBase64Binary(cert.getEncoded());
    }
    public static X509Certificate decode(String s) throws
    CertificateException, MessagingException, IOException {
    return
    X509Certificate.getInstance(DatatypeConverter.parseBase64Binary(s));
    }

    Arne
     
    Arne Vajhøj, Feb 9, 2013
    #7
  8. Ian Pilcher

    Roedy Green Guest

    On Fri, 08 Feb 2013 17:48:16 -0600, Ian Pilcher <>
    wrote, quoted or indirectly quoted someone who said :

    >In particular, the class must have a zero-argument constructor or a
    >constructor that takes a single String argument


    Surely it has a very particular format for this string in mind. You
    would have to convert the cert to this format, not just to some
    arbitrary encoding.
    --
    Roedy Green Canadian Mind Products http://mindprod.com
    The first 90% of the code accounts for the first 90% of the development time.
    The remaining 10% of the code accounts for the other 90% of the development
    time.
    ~ Tom Cargill Ninety-ninety Law
     
    Roedy Green, Feb 9, 2013
    #8
  9. Ian Pilcher

    Ian Pilcher Guest

    On 02/09/2013 12:10 PM, Roedy Green wrote:
    > Surely it has a very particular format for this string in mind. You
    > would have to convert the cert to this format, not just to some
    > arbitrary encoding.


    Well, since I was thinking of writing the class, I would have been
    writing both the serialization and deserialization code. Terribly
    inefficient, though.

    --
    ========================================================================
    Ian Pilcher
    Sometimes there's nothing left to do but crash and burn...or die trying.
    ========================================================================
     
    Ian Pilcher, Feb 16, 2013
    #9
  10. Ian Pilcher

    Roedy Green Guest

    On Sat, 16 Feb 2013 11:03:48 -0600, Ian Pilcher <>
    wrote, quoted or indirectly quoted someone who said :

    >Well, since I was thinking of writing the class, I would have been
    >writing both the serialization and deserialization code. Terribly
    >inefficient, though.


    It you have something in binary and want to transport it as a string
    that may meddle with chars such asLf Cr space, accented letters your
    best bet is Base64 armouring. That is how certs are typically
    armoured.

    See http://mindprod/jgloss/base64.html
    --
    Roedy Green Canadian Mind Products http://mindprod.com
    The first 90% of the code accounts for the first 90% of the development time.
    The remaining 10% of the code accounts for the other 90% of the development
    time.
    ~ Tom Cargill Ninety-ninety Law
     
    Roedy Green, Feb 16, 2013
    #10
  11. Ian Pilcher

    Arne Vajhoej Guest

    On 2/16/2013 3:40 PM, Roedy Green wrote:
    > On Sat, 16 Feb 2013 11:03:48 -0600, Ian Pilcher <>
    > wrote, quoted or indirectly quoted someone who said :
    >
    >> Well, since I was thinking of writing the class, I would have been
    >> writing both the serialization and deserialization code. Terribly
    >> inefficient, though.

    >
    > It you have something in binary and want to transport it as a string
    > that may meddle with chars such asLf Cr space, accented letters your
    > best bet is Base64 armouring. That is how certs are typically
    > armoured.


    Well base64 code was already posted a week ago.

    Arne
     
    Arne Vajhoej, Feb 17, 2013
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. iksrazal
    Replies:
    0
    Views:
    692
    iksrazal
    Feb 29, 2004
  2. Replies:
    2
    Views:
    14,568
    =?iso-8859-1?B?QmVub+50?=
    Jun 23, 2005
  3. JN
    Replies:
    0
    Views:
    146
  4. Peter Ritchie [C# MVP]

    Verifying X509Certificate signature

    Peter Ritchie [C# MVP], Jul 31, 2008, in forum: ASP .Net Security
    Replies:
    8
    Views:
    1,704
    Peter Ritchie [C# MVP]
    Aug 5, 2008
  5. Matthew

    X509Certificate not passed to webservice.

    Matthew, Oct 28, 2004, in forum: ASP .Net Web Services
    Replies:
    3
    Views:
    279
    Matthew
    Nov 5, 2004
Loading...

Share This Page