Hi Willy,

On Fri, May 09, Willy Tarreau wrote:
> > This patch should be compatible with apache/mod_ssl
> > (RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s") 
> > (newlines in the pem cert are replaced with space chars).
> 
> I'm wondering whether there is a risk that this same cert could be used
> encoded differently. Eg, currently we have it in PEM and replace new lines
> with spaces, but would it make sense sometimes for example to hash it and
> just pass a hash or whatever ?

I don't know about hashes, but googling shows that there seems to
be quite few slightly different "formats" (some examples below).
 
> My question comes from the fact that we have sample converters and that
> in my opinion, the conversion to the PEM format is very simple (eg:
> add "-----BEGIN CERTIFICATE-----\n", encode in base64 then END).
> 
> Similarly we could have the PEM converter chose the delimiting character
> to be used. And BTW we already have the base64 converter, but I don't
> think it would provide any value here.
> 
> So basically the output format could be built using this string :
> 
>     ssl_c_cert,pem(CERTIFICATE)
> 
> With :
>    - ssl_c_cert outputting raw binary
>    - pem(type) being the PEM encoder (prepend the BEGIN and append
>      the END line, encode in base64 each block of 48 bytes, and emit
>      a spacexs)

This sounds reasonable. With this approach it should be fairly
easy to support other SSL_CLIENT_CERT header "formats":
- just plain base64: ssl_c_cert,base64
- base64(pem): ssl_c_cert,pem(CERTIFICATE,"\n"),base64
(https://devcentral.f5.com/questions/irule-to-pass-client-ssl-cert-to-the-application-server-pool-member)
- pem encoded with newlines removed (pound compiled w/--enable-cert1l):
  ssl_c_cert,pem(CERTIFICATE) ?
- nginx seems to be changing how they output the cert 
(http://forum.nginx.org/read.php?29,249804,249848): 
ssl_c_cert,pem(CERTIFICATE,"\r\n\t")
 
> An optional "t" argument to the pem encoder would emit tabs instead
> of spaces to be compatible with pound/nginx.

Apache adds space(' ') after -----END CERTIFICATE----- line, but
I think nginx/pound compat. output should not add anything after
-----END CERTIFICATE----- ?

So should the pem converter take third argument: end marker?
- so apache compat: ssl_c_cert,pem(CERTIFICATE, " ", " ")
- nginx/pound: ssl_c_cert,pem(CERTIFICATE, "\r\n\t")

I might have some time next week or so to try to do this.
Can you give some pointers (for example which functions I could use
to look for examples) ?

I assume that ssl_c_cert would fetch function (similar to my earlier
patch, but returning the cert in raw binary) and pem would be converter
(like sample_conv_bin2base64) ?

-Jarno
 
> > (pound / nginx use different formatting for the cert:
> > X-SSL-certificate: -----BEGIN CERTIFICATE-----
> > \t...
> > \t-----END CERTIFICATE-----).
> > 
> > The code to replace newlines with spaces is not optimized. If there's a
> > guarantee that openssl PEM_write_bio_X509 will always format the pem
> > cert in same way(
> > -----BEGIN CERTIFICATE-----
> > MIIEoTCCA4mgAwIBAgIQIHCGEzfaVEFkF5d4JxstDTANBgkqhkiG9w0BAQUFADA2
> > ....
> > r8q5R89n4IPaS0DaE4I+/W15CPs/AUlkUh6vy2v+PY+WRlie6g==
> > -----END CERTIFICATE-----) --> are the base64 encoded lines always 64chars
> > (except the last line) ?
> 
> We really cannot rely on this I think, it sounds quite dangerous. Also,
> the cost of translating new lines into spaces is low compared to computing
> the cert output!
> 
> > --> the loop could be optimized to start from pos 27 (end of BEGIN line)
> > and jump 65 chars until end of last line.
> 
> Well, at least the with pem converter described above you would get this
> for free :-)
> 
> > Is this something that could be included in haproxy ?
> 
> Sure, I'm just trying to figure what would be the best way to do it so
> that we don't have to modify it in 6 months :-)

Reply via email to