On Sat, Apr 01, 2017 at 07:10:35PM +1030, Jack Burton wrote:
> On Fri, 31 Mar 2017 13:03:44 -0700
> William Ahern <[email protected]> wrote:
<snip>
> > Basically, anything short of passing through the entire certificate
> > is going to be severely limiting and frustrating, to the point of
> > uselessness. And as a practical matter, parsing out and passing
> > through a subset of certificate data is likely going to require more
> > complex code than just passing the entire certificate to the
> > application.
>
> Thanks William. That's an interesting idea.
>
> Yes, I can see how having the raw client certificate available to
> fastcgi responders would be useful. That would solve a few more
> problems for my use case too and would provide the ultimate in
> flexibility. And it's not difficult to implement.
>
> My initial gut feeling was that adding a tls_peer_serial() function to
> libtls would be less intrusive (and more in keeping with the rest of
> the tls_peer_* functions) than adding a tls_peer_cert() along the lines
> you're suggesting.
Converting a cert to a PEM string should be as simple as:
BIO *bio = BIO_new(BIO_s_mem()); /* See NOTE 1 */
if (!bio)
goto sslerror;
if (!PEM_write_bio_X509(bio, crt))
goto sslerror;
char *pem;
long pemlen = BIO_get_mem_data(bio, &pem);
assert(pemlen >= 0); /* < 0 shouldn't be possible */
... /* copy pem string */
BIO_free(bio); /* See NOTE 1 */
compare that to getting the serial:
BIGNUM *bn = BN_new();
if (!bn)
goto sslerror;
ASN1_INTEGER *i;
if (!(i = X509_get_serialNumber(crt))) /* See NOTE 2 */
goto noserial;
if (!ASN1_INTEGER_to_BN(i, bn))
goto sslerror;
char *serial = BN_bn2dec(serial);
if (!serial)
goto sslerror;
... /* copy serial string */
BN_free(bn);
NOTE 1: I usually keep a BIO buffer around as a singleton, using BIO_reset
instead of BIO_free.
NOTE 2: I'd try X509_get0_serialNumber unless the const-ness is troublesome.
I'm cribbing from my own code, originally written for OpenSSL 0.9.8, which
lacks X509_get0_serialNumber.