CACert and MyOpenID both do this: they have a form that, when submitted, will cause the browser to generate a key and send the public part up to be signed, then deliver back down the signed certificate containing that public key which the browser binds up in its keystore and uses for authentication in the future. I know how to use SSLVerify and similar to verify the client cert once the user has it, and I know how to generate a CA and client certs normally using the openssl command line tools, but not how to do the browser interaction bit to generate the key etc.
I'm probably using Apache and Ruby/Rack or PHP if that helps :)
You are looking for the keygen tag. See Mozilla's page.
You might be better off letting EJBCA do this since it handles the different browser quirks by using it's external-ra component (I did :) ).
In essence, build two instances of ejbca. One to act as your ca behind your secure network. Another instance as the frontend ra which will be used to enrol your users. The ca polls the ra by querying the ra's MySQL database (externalra.properties config file), pick any outstanding CSRs, sign them and then post certificates back.
For you to enrol a user:
Here's a simple ejbca build script I used. It won't work right off the bat but it should work. Update: Also see this question and this link for client cert usage in Apache