├── foafStore.php
├── README
├── rdfFragments.php
├── createCertificateAccount.php
├── simpleCreateClientCertificate.php
├── simple_KEYGEN_CreateClientCertificate.php
├── x509Functions.php
├── spkac_cert.php
└── cert.php
/foafStore.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | function store_rdf($nickname, $rdf)
4 | {
5 | // directory must be writeable
6 |
7 | file_put_contents($nickname, $rdf);
8 | }
9 |
10 | ?>
11 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | To use this code you have to edit your openssl.cnf file (look in
2 | /etc/pki/tls/openssl.cnf or /usr/share/ssl/openssl.cnf).
3 |
4 | the defaults section (the top bit, before and named sections) should have
5 | SAN = "" san = $ENV::SAN
6 | and the usr_cert section should have
7 | subjectAltName=$san
8 |
--------------------------------------------------------------------------------
/rdfFragments.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | function headerrdf()
4 | {
5 | $rdf = '
20 | ';
21 | $rdf .= ' '. $nicknameuri .'
22 | ';
23 | $rdf .= '
24 | ';
25 | $rdf .= '
26 | ';
27 | $rdf .= '
28 | ';
29 | $rdf .= '
30 | ';
31 | $rdf .= '
32 | ';
33 | $rdf .= '
34 | ';
35 | $rdf .= '
36 | ';
37 |
38 |
39 |
40 | return $rdf;
41 | }
42 |
43 | function certrdf($foafuri=NULL, $exp=NULL, $mod=NULL)
44 | {
45 | $rdf = '
46 | ';
47 | $foaffile = ($foafuri)?$foafuri:'TYPE YOUR WEBID HERE';
48 |
49 | $rdf .= '
50 | ';
51 | $rdf .= '
56 | ';
57 | $rdf .= '
62 | ';
63 | $rdf .= '
64 | ';
65 |
66 | return $rdf;
67 | }
68 |
69 | function footerrdf()
70 | {
71 | $rdf = '';
72 |
73 | return $rdf;
74 | }
75 |
76 | function generate_rdf($foafuri, $nicknameuri, $key)
77 | {
78 | $rdf = headerrdf();
79 | $rdf .= accountrdf($foafuri, $nicknameuri);
80 | $rdf .= certrdf($nicknameuri, $key[exponent], $key[modulus]);
81 | $rdf .= footerrdf();
82 |
83 | return $rdf;
84 | }
85 |
86 | ?>
87 |
--------------------------------------------------------------------------------
/createCertificateAccount.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | include_once("/home/foaf/public_html/rdfFragments.php");
4 | include_once("/home/foaf/public_html/x509Functions.php");
5 | include_once("/home/foaf/public_html/foafStore.php");
6 |
7 | $foafuri = $_GET[foafuri];
8 |
9 | if (!$foafuri)
10 | {
11 | if (array_key_exists('foafuri', $_GET))
12 | $query = $_SERVER[QUERY_STRING];
13 | else
14 | $query = ($_SERVER[QUERY_STRING]?$_SERVER[QUERY_STRING]."&":"") . "foafuri=";
15 |
16 | print "Please specify the location of a dereferencable foaf:Person. http://foaf.me/createCertificateAccount.php?foafuri=";
17 |
18 | exit();
19 | }
20 |
21 | $nickname = $_GET[nickname];
22 |
23 | if (!$nickname)
24 | {
25 | if (array_key_exists('nickname', $_GET))
26 | $query = $_SERVER[QUERY_STRING];
27 | else
28 | $query = ($_SERVER[QUERY_STRING]?$_SERVER[QUERY_STRING]."&":"") . "nickname=";
29 |
30 | print "Please specify the Common Name to be added to the Client Certificate. http://foaf.me/createCertificateAccount.php?nickname=";
31 |
32 | exit();
33 | }
34 |
35 | $pubkey = $_GET[pubkey];
36 |
37 | if (!$pubkey)
38 | {
39 | if (array_key_exists('pubkey', $_GET))
40 | $query = $_SERVER[QUERY_STRING];
41 | else
42 | $query = ($_SERVER[QUERY_STRING]?$_SERVER[QUERY_STRING]."&":"") . "pubkey=";
43 |
44 | print "Please specify the pubkey (KEYGEN) to be used in SPKAC generated certificate. http://foaf.me/createCertificateAccount.php?pubkey=";
45 |
46 | exit();
47 | }
48 |
49 | $nicknametmp = 'temp/'.urlencode($nickname);
50 | $nicknameuri = 'http://foaf.me/temp/'.urlencode($nickname);
51 |
52 | if($x509 = create_identity_x509(
53 | NULL, NULL, NULL, NULL, NULL, $nickname, NULL, $nicknameuri, $pubkey ))
54 | {
55 | $key = get_pkey($x509);
56 |
57 | $rdf = generate_rdf($foafuri, $nicknameuri, $key);
58 |
59 | store_rdf('temp/'.$nickname, $rdf);
60 |
61 | download_identity_x509($x509);
62 | }
63 |
64 | ?>
--------------------------------------------------------------------------------
/simpleCreateClientCertificate.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
14 | Simple Create Client Certificate Page
15 |
16 |
17 | Simple Create Client Certificate Page
18 |
55 |
56 |
57 |
58 | | Downloads |
59 |
60 |
61 |
65 |
66 |
67 | | See Also |
68 |
69 |
70 |
75 |
76 |
--------------------------------------------------------------------------------
/simple_KEYGEN_CreateClientCertificate.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 | Simple KEYGEN based Create Client Certificate Page
20 |
21 |
22 | Simple KEYGEN based Create Client Certificate Page
23 |
60 |
61 |
62 |
63 | | Downloads |
64 |
65 |
66 |
70 |
71 |
72 | | See Also |
73 |
74 |
75 |
80 |
81 |
82 | | External Links |
83 |
84 |
85 |
88 |
89 |
--------------------------------------------------------------------------------
/x509Functions.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | // Returns a X.509 SSL certificate
4 | function create_identity_x509(
5 | $countryName, $stateOrProvinceName, $localityName, $organizationName, $organizationalUnitName, $commonName, $emailAddress,
6 | $foafLocation, $pubkey)
7 | {
8 | // Remove any whitespace in teh supplied SPKAC
9 | $keyreq = "SPKAC=".str_replace(str_split(" \t\n\r\0\x0B"), '', $pubkey);
10 |
11 | // Create the DN for the openssl call
12 | if ($countryName)
13 | $keyreq .= "\ncountryName=".$countryName;
14 |
15 | if ($stateOrProvinceName)
16 | $keyreq .= "\nstateOrProvinceName=".$stateOrProvinceName;
17 |
18 | if ($localityName)
19 | $keyreq .= "\nlocalityName=".$localityName;
20 |
21 | if ($organizationName)
22 | $keyreq .= "\norganizationName=".$organizationName;
23 |
24 | if ($organizationalUnitName)
25 | $keyreq .= "\n0.OU=".$organizationalUnitName;
26 |
27 | if ($commonName)
28 | $keyreq .= "\nCN=".$commonName;
29 |
30 | if ($emailAddress)
31 | $keyreq .= "\nemailAddress=".$emailAddress;
32 |
33 | // Setup the contents of the subjectAltName
34 | if ($foafLocation)
35 | $SAN="URI:$foafLocation";
36 |
37 | if ($emailAddress)
38 | {
39 | if ($SAN)
40 | $SAN.=",email:$emailAddress";
41 | else
42 | $SAN="email:$emailAddress";
43 | }
44 |
45 | // Export the subjectAltName to be picked up by the openssl.cnf file
46 | if ($SAN)
47 | {
48 | putenv("SAN=$SAN");
49 | }
50 |
51 | // Create temporary files to hold the input and output to the openssl call.
52 | $tmpSPKACfname = tempnam("/tmp", "SPK");
53 | $tmpCERTfname = tempnam("/tmp", "CRT");
54 |
55 | // Write the SPKAC and DN into the temporary file
56 | $handle = fopen($tmpSPKACfname, "w");
57 | fwrite($handle, $keyreq);
58 | fclose($handle);
59 |
60 | // TODO - This should be more easily configured
61 | $command = "openssl ca -config /usr/share/ssl/openssl.cnf -verbose -batch -notext -spkac $tmpSPKACfname -out $tmpCERTfname -passin file:/home/foaf/ssl/password 2>&1";
62 |
63 | // Run the command;
64 | $output = `$command`;
65 |
66 | // TODO - Check for failures on the command
67 | if (preg_match("/Data Base Updated/", $output)==0)
68 | {
69 | print "Failed to create X.509 Certificate
";
70 | // print "";
71 | // print $output;
72 | // print "
";
73 |
74 | return;
75 | }
76 |
77 | // Delete the temporary SPKAC and DN file
78 | unlink($tmpSPKACfname);
79 |
80 | return $tmpCERTfname;
81 | }
82 |
83 | // Send the p12 encoded SSL certificate as a file transfer
84 | function download_identity_x509($certLocation)
85 | {
86 | $length = filesize($certLocation);
87 | header('Last-Modified: '.date('r+b'));
88 | header('Accept-Ranges: bytes');
89 | header('Content-Length: '.$length);
90 | header('Content-Type: application/x-x509-user-cert');
91 | readfile($certLocation);
92 |
93 | unlink($certLocation);
94 |
95 | exit;
96 | }
97 |
98 | function get_pkey($x509file)
99 | {
100 | $command = "openssl asn1parse -inform DER -i -in $x509file";
101 |
102 | $rsa_cert_struct = `$command`;
103 |
104 | $rsa_cert_fields = split("\n", $rsa_cert_struct);
105 | $rsakey_offset = split(":", $rsa_cert_fields[45]);
106 |
107 | $command = "openssl asn1parse -inform DER -i -in $x509file -strparse $rsakey_offset[0]";
108 |
109 | $rsa_key = `$command`;
110 |
111 | $rsa_keys = split("\n", $rsa_key);
112 | $modulus = split(":", $rsa_keys[1]);
113 | $exponent = split(":", $rsa_keys[2]);
114 |
115 | return(array( 'modulus'=>$modulus[3], 'exponent'=>$exponent[3] ) );
116 | }
117 | ?>
--------------------------------------------------------------------------------
/spkac_cert.php:
--------------------------------------------------------------------------------
1 | &1";
88 |
89 | // Run the command;
90 | $output = `$command`;
91 |
92 | // TODO - Check for failures on the command
93 | if (preg_match("/Data Base Updated/", $output)==0)
94 | {
95 | print "Failed to create X.509 Certificate
";
96 | print "";
97 | print $output;
98 | print "
";
99 |
100 | return;
101 | }
102 |
103 | // Delete the temporary SPKAC and DN file
104 | unlink($tmpSPKACfname);
105 |
106 | return $tmpCERTfname;
107 | }
108 |
109 | // Send the p12 encoded SSL certificate as a file transfer
110 | function download_identity_x509($certLocation)
111 | {
112 | $length = filesize($certLocation);
113 | header('Last-Modified: '.date('r+b'));
114 | header('Accept-Ranges: bytes');
115 | header('Content-Length: '.$length);
116 | header('Content-Type: application/x-x509-user-cert');
117 | readfile($certLocation);
118 |
119 | unlink($certLocation);
120 |
121 | exit;
122 | }
123 |
124 | //-----------------------------------------------------------------------------------------------------------------------------------
125 | //
126 | // Main
127 | //
128 | //-----------------------------------------------------------------------------------------------------------------------------------
129 |
130 | // Print out the permitted script parameters
131 | if ($_GET[help])
132 | {
133 | print "cert.php?
";
134 | print "foaf=http://foaf.me/jsmith&
";
135 | print "commonName=J Smith&
";
136 | print "emailAddress=jsmith@example.com&
";
137 | print "organizationName=My Company Ltd&
";
138 | print "organizationalUnitName=Technology Division&
";
139 | print "localityName=Newbury&
";
140 | print "stateOrProvinceName=Berkshire&
";
141 | print "countryName=GB&
";
142 | print "pubkey=***...***
";
143 | exit();
144 | }
145 |
146 | // Check if the foaf location is specified in the script call
147 | $foafLocation = $_GET[foaf];
148 | if (!$foafLocation)
149 | {
150 | if (array_key_exists('foaf', $_GET))
151 | $query = $_SERVER[QUERY_STRING];
152 | else
153 | $query = ($_SERVER[QUERY_STRING]?$_SERVER[QUERY_STRING]."&":"") . "foaf=";
154 |
155 | print "Please specify the location of your foaf file. https://foaf.me/spkac_cert.php?foaf=http://foaf.me/nickname
The FOAF location is added to the SubjectAltName within the SSL Client Certificate
";
156 |
157 | exit();
158 | }
159 |
160 | // Check if the commonName is specified in the script call
161 | $commonName = $_GET[commonName];
162 | if (!$commonName)
163 | {
164 | if (array_key_exists('commonName', $_GET))
165 | $query = $_SERVER[QUERY_STRING];
166 | else
167 | $query = ($_SERVER[QUERY_STRING]?$_SERVER[QUERY_STRING]."&":"") . "commonName=";
168 |
169 | print "Please specify the Common Name to be added to your certficate. https://foaf.me/spkac_cert.php?commonName=Common Name
";
170 |
171 | exit();
172 | }
173 |
174 | // Check that script is called using the HTTPS protocol
175 | if ($_SERVER[HTTPS] == NULL)
176 | {
177 | print "Please use the following secure uri to download the Identity P12. https://foaf.me/spkac_cert.php?" . $_SERVER[QUERY_STRING] . "
";
178 |
179 | exit();
180 | }
181 |
182 | // Get the rest of the script parameters
183 | $countryName = $_GET[countryName];
184 | $stateOrProvinceName = $_GET[stateOrProvinceName];
185 | $localityName = $_GET[localityName];
186 | $organizationName = $_GET[organizationName];
187 | $organizationalUnitName = $_GET[organizationalUnitName];
188 | $emailAddress = $_GET[emailAddress];
189 | $pubkey = $_GET[pubkey];
190 |
191 | // Create a x509 SSL certificate
192 | if ( $x509 = create_identity_x509(
193 | $countryName, $stateOrProvinceName, $localityName, $organizationName, $organizationalUnitName, $commonName, $emailAddress,
194 | $foafLocation, $pubkey ) )
195 | {
196 | // Send the X.509 SSL certificate to the script caller as a file transfer
197 | download_identity_x509($x509);
198 | }
199 |
200 | ?>
--------------------------------------------------------------------------------
/cert.php:
--------------------------------------------------------------------------------
1 | $countryName);
37 |
38 | if ($stateOrProvinceName)
39 | {
40 | if ($dn)
41 | $dn = array_merge($dn, array("stateOrProvinceName" => $stateOrProvinceName));
42 | else
43 | $dn = array("stateOrProvinceName" => $stateOrProvinceName);
44 | }
45 |
46 | if ($localityName)
47 | {
48 | if ($dn)
49 | $dn = array_merge($dn, array("localityName" => $localityName));
50 | else
51 | $dn = array("localityName" => $localityName);
52 | }
53 |
54 | if ($organizationName)
55 | {
56 | if ($dn)
57 | $dn = array_merge($dn, array("organizationName" => $organizationName));
58 | else
59 | $dn = array("organizationName" => $organizationName);
60 | }
61 |
62 | if ($organizationalUnitName)
63 | {
64 | if ($dn)
65 | $dn = array_merge($dn, array("organizationalUnitName" => $organizationalUnitName));
66 | else
67 | $dn = array("organizationalUnitName" => $organizationalUnitName);
68 | }
69 |
70 | if ($commonName)
71 | {
72 | if ($dn)
73 | $dn = array_merge($dn, array("commonName" => $commonName));
74 | else
75 | $dn = array("commonName" => $commonName);
76 | }
77 |
78 | if ($emailAddress)
79 | {
80 | if ($dn)
81 | $dn = array_merge($dn, array("emailAddress" => $emailAddress));
82 | else
83 | $dn = array("emailAddress" => $emailAddress);
84 | }
85 |
86 | // if the $dn array is NULL at this point set country name to the default of GB
87 | if (!$dn)
88 | $dn = array("countryName" => "GB");
89 |
90 | // Setup the contents of the subjectAltName
91 | if ($foafLocation)
92 | $SAN="URI:$foafLocation";
93 |
94 | if ($emailAddress)
95 | {
96 | if ($SAN)
97 | $SAN.=",email:$emailAddress";
98 | else
99 | $SAN="email:$emailAddress";
100 | }
101 |
102 | // Export the subjectAltName to be picked up by the openssl.cnf file
103 | if ($SAN)
104 | {
105 | putenv("SAN=$SAN");
106 | }
107 |
108 | // Create the array to hold the configuration options for the openssl function calls
109 | // TODO - This should be more easily configured
110 | $config = array('config'=>'/usr/share/ssl/openssl.cnf');
111 |
112 | if ($SAN)
113 | {
114 | // TODO - This should be more easily configured
115 | $config = array_merge($config, array('x509_extensions' => 'usr_cert'));
116 | }
117 |
118 | // Generate a new private (and public) key pair
119 | $privkey = openssl_pkey_new($config);
120 |
121 | if ($privkey==FALSE)
122 | {
123 | // Show any errors that occurred here
124 | while (($e = openssl_error_string()) !== false)
125 | {
126 | echo $e . "\n";
127 | print "
";
128 | }
129 | }
130 |
131 | // Generate a certificate signing request
132 | $csr = openssl_csr_new($dn, $privkey, $config);
133 |
134 | if (!$csr)
135 | {
136 | // Show any errors that occurred here
137 | while (($e = openssl_error_string()) !== false)
138 | {
139 | echo $e . "\n";
140 | print "
";
141 | }
142 | }
143 |
144 | // You will usually want to create a self-signed certificate at this
145 | // point until your CA fulfills your request.
146 | // This creates a self-signed cert that is valid for 365 days
147 | $sscert = openssl_csr_sign($csr, null, $privkey, 365, $config);
148 |
149 | if ($sscert==FALSE)
150 | {
151 | // Show any errors that occurred here
152 | while (($e = openssl_error_string()) !== false)
153 | {
154 | echo $e . "\n";
155 | print "
";
156 | }
157 | }
158 |
159 | if (openssl_pkcs12_export($sscert, $p12Out, $privkey, $p12Password)==FALSE)
160 | {
161 | // Show any errors that occurred here
162 | while (($e = openssl_error_string()) !== false)
163 | {
164 | echo $e . "\n";
165 | print "
";
166 | }
167 | }
168 |
169 | return $p12Out;
170 | }
171 |
172 | // Send the p12 encoded SSL certificate as a file transfer
173 | function download_identity_p12($p12, $foafLocation)
174 | {
175 | // set headers
176 | header("Pragma: private");
177 | header("Expires: 0");
178 | header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
179 | header("Cache-Control: private");
180 | header("Content-Description: File Transfer");
181 | header("Content-Type: application/x-pkcs12");
182 |
183 | $file = basename($foafLocation);
184 |
185 | header("Content-Disposition: attachment; filename=\"$file.p12\"");
186 | header("Content-Transfer-Encoding: binary");
187 | header("Content-Length: " . strlen($p12));
188 |
189 | print($p12);
190 |
191 | flush();
192 | if (connection_status()!=0)
193 | {
194 | @fclose($file);
195 | die();
196 | }
197 |
198 | }
199 |
200 | //-----------------------------------------------------------------------------------------------------------------------------------
201 | //
202 | // Main
203 | //
204 | //-----------------------------------------------------------------------------------------------------------------------------------
205 |
206 | // Print out the permitted script parameters
207 | if ($_GET[help])
208 | {
209 | print "cert.php?
";
210 | print "foaf=http://foaf.me/jsmith&
";
211 | print "commonName=J Smith&
";
212 | print "emailAddress=jsmith@example.com&
";
213 | print "organizationName=My Company Ltd&
";
214 | print "organizationalUnitName=Technology Division&
";
215 | print "localityName=Newbury&
";
216 | print "stateOrProvinceName=Berkshire&
";
217 | print "countryName=GB&
";
218 | print "password=secret
";
219 | exit();
220 | }
221 |
222 | // Check if the foaf loaction is specified in the script call
223 | $foafLocation = $_GET[foaf];
224 | if (!$foafLocation)
225 | {
226 | if (array_key_exists('foaf', $_GET))
227 | $query = $_SERVER[QUERY_STRING];
228 | else
229 | $query = ($_SERVER[QUERY_STRING]?$_SERVER[QUERY_STRING]."&":"") . "foaf=";
230 |
231 | print "Please specify the location of your foaf file. https://foaf.me/cert.php?foaf=http://foaf.me/nickname
The FOAF location is added to the SubjectAltName within the SSL Client Certificate
";
232 |
233 | exit();
234 | }
235 |
236 | // Check that script is called using the HTTPS protocol
237 | if ($_SERVER[HTTPS] == NULL)
238 | {
239 | print "Please use the following secure uri to download the Identity P12. https://foaf.me/cert.php?" . $_SERVER[QUERY_STRING] . "
";
240 |
241 | exit();
242 | }
243 |
244 | // Get the rest of the script parameters
245 | $countryName = $_GET[countryName];
246 | $stateOrProvinceName = $_GET[stateOrProvinceName];
247 | $localityName = $_GET[localityName];
248 | $organizationName = $_GET[organizationName];
249 | $organizationalUnitName = $_GET[organizationalUnitName];
250 | $commonName = $_GET[commonName];
251 | $emailAddress = $_GET[emailAddress];
252 | $p12Password = $_GET[password];
253 |
254 | // Create a PKCS12 encoded SSL certificate
255 | if ( $p12 = create_identity_p12(
256 | $countryName, $stateOrProvinceName, $localityName, $organizationName, $organizationalUnitName, $commonName, $emailAddress,
257 | $foafLocation, $p12Password ) )
258 | {
259 | // Send the PKCS12 encoded SSL certificate to the script caller as a file transfer
260 | download_identity_p12($p12, $foafLocation);
261 | }
262 |
263 | ?>
--------------------------------------------------------------------------------