[foaf-protocols] Generating X509 keys on Internet Explorer
Akbar Hossain
akkiehossain at googlemail.com
Tue Nov 24 21:38:14 CET 2009
re: 1. A KEYGEN equivalent for IE
Sorry to report. I have not been able to get this to work on my machines. I
believe xenroll.dll change to certenroll.dll post Vista.
No idea if IE versions come into play too. If someone has come across a
running version I will give it another go.
Have looked around a bit but not seen anything other than instructions to
create a CSR in keytool or certmgr.
The server side of SPKAC is already in place on the foaf.me server.
The script the foaf.me server uses is here:
http://foaf.me/download.php?uri=spkac_cert.php
If someone knows what they are doing feel free to submit a version of IE
equivalent of
http://foaf.me/download.php?uri=simple_KEYGEN_CreateClientCertificate.phpyou
should not need to change the SPKAC (server) script.
The running test version of KEYGEN is here
http://foaf.me/simple_KEYGEN_CreateClientCertificate.php
re: 2. Generating a p12 key server side
An example of a completely server side generator of a p12 which does work in
IE is here.
http://foaf.me/simpleCreateClientCertificate.php
It is insecure due to the following atleast. The p12 hits the filesystem of
the servers filesystem. You have to trust the script
deletes the file. Otherwise anyone with access could get a copy of your
certificate.
The minimum fields you need to fill in are webid and common name.
You then get asked to press the OK button a lot of times. Not sure if this
is the same experience for the KEYGEN equivalent as I havent seen it
running.
Thanks.
On Mon, Nov 23, 2009 at 8:18 PM, Dirk-WIllem van Gulik <
Dirk-Willem.van.Gulik at bbc.co.uk> wrote:
>
> On 23 Nov 2009, at 18:16, Story Henry wrote:
>
> > 1. A KEYGEN equivalent for IE
> > -----------------------------
> >
> > There is a way to get something very similar to the keygen tag on IE.
> Dirk Willem van Gulik pointed us to the EJBCA toolkit which has Java code
> implementing this. Their site is here:
> >
> > http://ejbca.sourceforge.net/
> >
> > Looking at that code 6 months ago, I found the following pieces of code:
> >
> >
> http://ejbca.svn.sourceforge.net/viewvc/ejbca/trunk/ejbca/src/publicweb/publicweb/enrol/apply/apply_exp.jspf
> >
> > and this javascript file
> >
> >
> http://ejbca.svn.sourceforge.net/viewvc/ejbca/trunk/ejbca/src/publicweb/publicweb/scripts/functions.js
> >
> > But not being an ActiveX person, and not having done VB inside of IE, I
> am not sure exactly what is going on here. It would be really useful if we
> could document this code at a higher level so that one can understand what
> it is doing.
>
> Actually a stupid cut-and-paste will work fine.
>
> Below are some snippets of code which drive things.
>
> Dw.
>
>
> First up - generate some UI bits along with whatever else you capture:
>
> IE:
> <script LANGUAGE="Javascript" SRC="msie/ieEnroll.js"></script>
>
> FireFox:
>
> <KEYGEN name=spkac type=hidden challenge=notSoBeIt><input
> type=submit value="Continue..">
>
> And the prefix this with the IE code if and where needed
>
> > <!--object
> > classid="clsid:43f8f289-7a20-11d0-8f06-00c04fc295e1"
> > codebase="xenroll.dll"
> > id="certHelperOld">
> > </object>
> > <object
> > classid= "clsid:127698e4-e730-4e5c-a2b1-21490a70c8a1"
> > codebase="/msie/xenroll.dll#Version=5,131,3659,0"
> > id="cec">
> > </object>
> >
> > <!-- script LANGUAGE="VBScript" SRC="msie/ieCSR.vbs" -->
> >
> > <script LANGUAGE="VBScript">
> > Function getProviderList()
> >
> > Dim CspList, cspIndex, ProviderName
> > On Error Resume Next
> >
> > count = 0
> > base = 0
> > enhanced = 0
> > CspList = ""
> > ProviderName = ""
> >
> > For ProvType = 0 to 13
> > cspIndex = 0
> > cec.ProviderType = ProvType
> > ProviderName = cec.enumProviders(cspIndex,0)
> >
> > while ProviderName <> ""
> > Set oOption = document.createElement("OPTION")
> > oOption.text = ProviderName
> > oOption.value = ProvType
> > document.OPENCA.csp.add(oOption)
> > if ProviderName = "Microsoft Base Cryptographic Provider v1.0"
> Then
> > base = count
> > end if
> > if ProviderName = "Microsoft Enhanced Cryptographic Provider
> v1.0" Then
> > enhanced = count
> > end if
> > cspIndex = cspIndex +1
> > ProviderName = ""
> > ProviderName = cec.enumProviders(cspIndex,0)
> > count = count + 1
> > wend
> > Next
> > document.OPENCA.csp.selectedIndex = base
> > if enhanced then
> > document.OPENCA.csp.selectedIndex = enhanced
> > end if
> > End Function
> >
> > Function CSR(keyflags)
> > CSR = ""
> > DIM szName
> > szName = "C=" & document.OPENCA.C.value & "/ST=" &
> document.OPENCA.ST.value & "/O=" & document.OPENCA.O.value & "/OU=" &
> document.OPENCA.OU.value & "/CN=" & document.OPENCA.CN.value
> > cec.HashAlgorithm = "MD5"
> > err.clear
> > On Error Resume Next
> > set options = document.all.csp.options
> > index = options.selectedIndex
> > cec.providerName = options(index).text
> > tmpProviderType = options(index).value
> > cec.providerType = tmpProviderType
> > cec.KeySpec = 2
> > if tmpProviderType < 2 Then
> > cec.KeySpec = 1
> > end if
> > cec.GenKeyFlags = &h04000001 OR keyflags
> > CSR = cec.createPKCS10(szName, "1.3.6.1.5.5.7.3.2")
> > if len(CSR)<>0 then Exit Function
> > cec.GenKeyFlags = &h04000000 OR keyflags
> > CSR = cec.createPKCS10(szName, "1.3.6.1.5.5.7.3.2")
> > if len(CSR)<>0 then Exit Function
> > if cec.providerName = "Microsoft Enhanced Cryptographic Provider
> v1.0" Then
> > if MsgBox("The 1024-bit key generation failed. Would you like
> to try 512 instead?", vbOkCancel)=vbOk Then
> > cec.providerName = "Microsoft Base Cryptographic Provider
> v1.0"
> > else
> > Exit Function
> > end if
> > end if
> > cec.GenKeyFlags = 1 OR keyflags
> > CSR = cec.createPKCS10(szName, "1.3.6.1.5.5.7.3.2")
> > if len(CSR)<>0 then Exit Function
> > cec.GenKeyFlags = keyflags
> > CSR = cec.createPKCS10(szName, "1.3.6.1.5.5.7.3.2")
> > if len(CSR)<>0 then Exit Function
> > cec.GenKeyFlags = 0
> > CSR = cec.createPKCS10(szName, "1.3.6.1.5.5.7.3.2")
> > End Function
> >
> > Sub GenReq_OnClick
> > err.clear
> > result = CSR(2)
> > if len(result)=0 Then
> > result = MsgBox("Unable to generate PKCS#10.", 0, "Alert")
> > Exit Sub
> > end if
> > document.OPENCA.request.Value = result
> > document.OPENCA.Submit
> > Exit Sub
> > End Sub
> > </script>
> >
> > <body onLoad="getProviderList()">
> >
>
>
> With something like:
>
> > sub keygenHTML {
> > my ($ui) = @_;
> >
> > return (keygen =>
> Asemantics::Templates::render('keygen-'.$ui.'.html'))
> > if ($ui eq 'spkac');
> >
> > return (
> > keygen =>
> Asemantics::Templates::render('keygen-'.$ui.'.html'),
> > jscript =>
> Asemantics::Templates::render('activeX.html'),
> > button => ' OnClick="GenReq()"'
> > ) if ($ui eq 'msie');
> >
> > return (keygen => "Browser not supported");
> > };
> >
>
>
> Ok - so then you get the form back. Recalling from
>
> IE:
> <script LANGUAGE="Javascript" SRC="msie/ieEnroll.js"></script>
> FireFox:
> <KEYGEN name=spkac type=hidden challenge=notSoBeIt><input
> type=submit value="Continue..">
>
> we can check for spkac presense/absence to drive openssl in the right way:
>
> > sub signCert {
> > my ($id) = @_;
> > my %dn = loadReq($id)
> > or return undef;
> >
> > my $subject = _dnencode(%dn),
> >
> > # Round the start date down - to ensue that
> > # Windows XP SP1 does not get confused by
> > # a certificate which is from 'the future' die
> > # to its date truncation.
> > #
> > my ($d,$m,$y) = (gmtime(time-1))[3,4,5];
> > my $from = sprintf("%02d%02d%02d000000Z", $y-100,$m+1, $d-1);
> >
> > my $out;
> > my @temps = ();
> > my @cmds = (
> > $CONF::OPENSSL, 'ca',
> > '-config', $CONF::OPENSSL_CONF,
> > '-cert', $CONF::CA_CRT,
> > '-keyfile', $CONF::CA_KEY,
> > '-days', $dn{days},
> > '-outdir', $CONF::ISSUEDDIR,
> > '-out', '/dev/null',
> > '-startdate', $from,
> > '-notext',
> > '-batch',
> > '-subj', $subject
> > );
> > if ($dn{ spkac }) {
> > my $file = $CONF::TMP.'/wadica_spkfile'.$id.$$;
> > unless (open FH, ">$file") {
> > warn "Cannot write to $file: $!";
> > goto erx;
> > };
> > $dn{ spkac } =~ s/\s+//sg;
> > print FH "commonName = $dn{ CN }\n".
> > "emailAddress = $dn{ emailAddress}\n".
> > "organizationName = $dn{ O}\n".
> > "organizationalUnitName = $dn{ OU }\n".
> > "localityName = $dn{ L }\n".
> > "stateOrProvinceName = $dn{ ST }\n".
> > "countryName = $dn{ C }\n".
> > "SPKAC = $dn{ spkac }\n";
> > close(FH);
> > push @cmds, '-spkac', $file;
> > push @temps, $file;
> > } else {
> > my $cert = $dn{ request };
> > my $file = $CONF::TMP.'/wadica_iecert'.$id.$$;
> > unless (open FH, ">$file") {
> > warn "Cannot write to $file: $!";
> > goto erx;
> > };
> > print FH $cert;
> > close FH;
> > push @cmds, '-in', $file;
> > push @temps, $file;
> > }
> >
> > my $rc = system @cmds;
> >
> > if ($rc) {
> > warn "OpenSSL issue CMD failed: $!$?\n";
> > goto erx;
> > };
> >
> > $dn{ status } = 'ACCEPT';
> > $dn{ date } = scalar(localtime(time));
> > $dn{history} .= 'Approved '.$dn{date}.'<br>';
> >
> > $dn{ from } = scalar(localtime(time));
> > $dn{ until } = scalar(localtime(time + $dn{days} * 365 * 24 *
> 3600 ));
> >
> > if (!(lockedopen FH, $CONF::SERIAL)) {
> > warn "Cannot read/lock serial $CONF::SERIAL: $!\n";
> > goto erx;
> > }
> > $dn{serial} = hex(<FH>) - 1;
> > close FH;
> >
> > if (!(open(FH,">"._toSerial($dn{serial})))) {
> > warn "Problem writing serial ($dn{serial}): $!\n";
> > goto erx;
> > }
> > print FH "$id\n";
> > close(FH);
> >
> > saveReq($id, %dn);
> > updateDB();
> >
> > $out = 1;
> > erx:
> > map { unlink $_; } @temps
> > unless $CONF::DEBUG;
> > return $out;
> > };
> >
>
> An finally we need to sent it to the user:
>
> > sub sendCert {
> > my ($id) = @_;
> > my %dn = loadReq($id);
> > my $serial = $dn{ serial };
> > my $hex_serial = sprintf("%02X", $serial);
> > my $cf = $CONF::ISSUEDDIR.'/'.$hex_serial.'.pem';
> >
> > warn "$cf does not exist"
> > unless -f $cf;
> >
> > my $ui = $ENV{ HTTP_USER_AGENT };
> > if ( $ui =~ /MSIE/i and $ui !~ /Opera/i ) {
> > my @cmds = (
> > $CONF::OPENSSL, 'crl2pkcs7',
> > '-in', $cf,
> > '-outform', 'PEM',
> > # '-nocrl'
> > );
> > my $cmd = "'".join("' '", at cmds)."'";
> > open FH, $cmd.' |';
> > my $out = '';
> > while(<FH>) {
> > s/\s+//g;
> > next if m/^---/;
> > $out .= $_;
> > };
> > print Asemantics::Templates::page('ieload.html',
> > jscript =>
> Asemantics::Templates::render('activeX.html').
> >
> Asemantics::Templates::render('ieEntroll.html'),
> > out=>$out,
> > );
> > return 1;
> > };
> >
> > print "Content-type: application/x-x509-user-cert\n";
> > print "Content-Disposition: attachment; filename=cert.pem\n\n";
> > open(FH,$cf);
> > while(<FH>) { print; };
> > close(FH);
> >
> > return 1;
> > };
> >
>
> And that should be it. Note that some of the OIDs for the spkac are set in
> openssl.conf - aside from the MS enroll.
>
> Dw.
>
>
> http://www.bbc.co.uk/
> This e-mail (and any attachments) is confidential and may contain personal
> views which are not the views of the BBC unless specifically stated.
> If you have received it in error, please delete it from your system.
> Do not use, copy or disclose the information in any way nor act in reliance
> on it and notify the sender immediately.
> Please note that the BBC monitors e-mails sent or received.
> Further communication will signify your consent to this.
>
> _______________________________________________
> foaf-protocols mailing list
> foaf-protocols at lists.foaf-project.org
> http://lists.foaf-project.org/mailman/listinfo/foaf-protocols
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.foaf-project.org/pipermail/foaf-protocols/attachments/20091124/ba32756b/attachment-0001.htm
More information about the foaf-protocols
mailing list