PageRenderTime 39ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/elgg/mod/foafssl/cert.php

https://bitbucket.org/rhizomatik/lorea_production/
PHP | 319 lines | 197 code | 41 blank | 81 comment | 39 complexity | c0a24df245550e5b7efc17904b5fdb02 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. //-----------------------------------------------------------------------------------------------------------------------------------
  3. //
  4. // Filename : cert.php
  5. // Version : 1.0
  6. // Date : 3rd Jan 2009
  7. //
  8. // Decription : This script creates an PKCS12 encoded SSL Certificate which is file transfered to the script caller.
  9. //
  10. // Usage : cert.php?foaf=http://foaf.me/jsmith&
  11. // commonName=J Smith&
  12. // emailAddress=jsmith@example.com&
  13. // organizationName=My Company Ltd&
  14. // organizationalUnitName=Technology Division&
  15. // localityName=Newbury&
  16. // stateOrProvinceName=Berkshire&
  17. // countryName=GB&
  18. // password=secret
  19. //
  20. // All parameters except 'foaf' are optional. Some parameters if missing will default as per openssl.cnf
  21. //
  22. // See Also : Using PHP to create self-signed X.509 Client Certificates
  23. // http://foaf.me/Using_PHP_to_create_X.509_Client_Certificates.php
  24. //
  25. //-----------------------------------------------------------------------------------------------------------------------------------
  26. require_once dirname(__FILE__).'/asn1.php';
  27. function toBASE64($encodeMe) {
  28. $data = base64_encode($encodeMe);
  29. $datalb = "";
  30. while (strlen($data) > 64) {
  31. $datalb .= substr($data, 0, 64) . "\n";
  32. $data = substr($data,64);
  33. }
  34. $datalb .= $data;
  35. return $datalb;
  36. }
  37. // Returns a PKCS12 encoded SSL certificate
  38. function create_identity_p12(
  39. $countryName, $stateOrProvinceName, $localityName, $organizationName, $organizationalUnitName, $commonName, $emailAddress,
  40. $foafLocation, $pubkey)
  41. {
  42. // Create the DN array for the openssl function calls
  43. if ($countryName)
  44. $dn = array("countryName" => $countryName);
  45. // decode base64
  46. // decode asn.1
  47. //
  48. $pubkey = str_replace(str_split(" \t\n\r\0\x0B"), '', $pubkey);
  49. $spkac_asn1 = base64_decode($pubkey);
  50. $spkac = ASN_BASE::parseASNString($spkac_asn1);
  51. //print_r($spkac);
  52. $asn1_key =$spkac[0]->asnData[0]->asnData[0]->asnData[1]->data;
  53. error_log("XX".$asn1_key);
  54. // $asn1_key = $spkac[0]->asnData[2]->value[0]->value;
  55. $pubkey = toBASE64($asn1_key);
  56. /* echo "<br/>bla<br/>".$spkac[0]->asnData[0]->asnData[0]->asnData[1]->value;
  57. $spki = ASN_BASE::parseASNString($spkac[0]->asnData[0]->asnData[0]->asnData[1]->asnData);*/
  58. //echo "<br/>bla<br/>".$asn1_key;
  59. /* print_r($spki);
  60. $spki = ASN_BASE::parseASNString($spkac[0]->asnData[2]->value[0]->value);
  61. print_r($spki);*/
  62. $pubkey = "-----BEGIN PUBLIC KEY-----\n".$pubkey;
  63. $pubkey = $pubkey."\n-----END PUBLIC KEY-----";
  64. error_log($pubkey);
  65. if ($dn) {
  66. // $dn = array_merge($dn, array("SPKAC" => $spkac));
  67. }
  68. else {
  69. // $dn = array("SPKAC" => $spkac);
  70. }
  71. if ($stateOrProvinceName)
  72. {
  73. if ($dn)
  74. $dn = array_merge($dn, array("stateOrProvinceName" => $stateOrProvinceName));
  75. else
  76. $dn = array("stateOrProvinceName" => $stateOrProvinceName);
  77. }
  78. if ($localityName)
  79. {
  80. if ($dn)
  81. $dn = array_merge($dn, array("localityName" => $localityName));
  82. else
  83. $dn = array("localityName" => $localityName);
  84. }
  85. if ($organizationName)
  86. {
  87. if ($dn)
  88. $dn = array_merge($dn, array("organizationName" => $organizationName));
  89. else
  90. $dn = array("organizationName" => $organizationName);
  91. }
  92. if ($organizationalUnitName)
  93. {
  94. if ($dn)
  95. $dn = array_merge($dn, array("organizationalUnitName" => $organizationalUnitName));
  96. else
  97. $dn = array("organizationalUnitName" => $organizationalUnitName);
  98. }
  99. if ($commonName)
  100. {
  101. if ($dn)
  102. $dn = array_merge($dn, array("commonName" => $commonName));
  103. else
  104. $dn = array("commonName" => $commonName);
  105. }
  106. if ($emailAddress)
  107. {
  108. if ($dn)
  109. $dn = array_merge($dn, array("emailAddress" => $emailAddress));
  110. else
  111. $dn = array("emailAddress" => $emailAddress);
  112. }
  113. // if the $dn array is NULL at this point set country name to the default of GB
  114. if (!$dn)
  115. $dn = array("countryName" => "GB");
  116. // Setup the contents of the subjectAltName
  117. if ($foafLocation)
  118. $SAN="URI:$foafLocation";
  119. if ($emailAddress)
  120. {
  121. if ($SAN)
  122. $SAN.=",email:$emailAddress";
  123. else
  124. $SAN="email:$emailAddress";
  125. }
  126. // Export the subjectAltName to be picked up by the openssl.cnf file
  127. if ($SAN)
  128. {
  129. putenv("SAN=$SAN");
  130. }
  131. // Create the array to hold the configuration options for the openssl function calls
  132. // TODO - This should be more easily configured
  133. $config = array('config'=>'/etc/ssl/openssl.cnf');
  134. if ($SAN)
  135. {
  136. // TODO - This should be more easily configured
  137. $config = array_merge($config, array('x509_extensions' => 'usr_cert'));
  138. }
  139. // Generate a new private (and public) key pair
  140. $privkey = openssl_pkey_new($config);
  141. if ($privkey==FALSE)
  142. {
  143. // Show any errors that occurred here
  144. while (($e = openssl_error_string()) !== false)
  145. {
  146. error_log( "privkey:".$e);
  147. //echo $e . "\n";
  148. //print "<br><br>";
  149. }
  150. }
  151. $userkey = openssl_pkey_get_public($pubkey);
  152. if ($userkey==FALSE)
  153. {
  154. // Show any errors that occurred here
  155. while (($e = openssl_error_string()) !== false)
  156. {
  157. error_log("userkey:". $e);
  158. //echo $e . "\n";
  159. //print "<br><br>";
  160. }
  161. }
  162. // Generate a certificate signing request
  163. $csr = openssl_csr_new($dn, $userkey, $config);
  164. if (!$csr)
  165. {
  166. // Show any errors that occurred here
  167. while (($e = openssl_error_string()) !== false)
  168. {
  169. error_log( "csr:".$e);
  170. //echo $e . "\n";
  171. //print "<br><br>";
  172. }
  173. }
  174. // You will usually want to create a self-signed certificate at this
  175. // point until your CA fulfills your request.
  176. // This creates a self-signed cert that is valid for 365 days
  177. $sscert = openssl_csr_sign($csr, null, $privkey, 365, $config);
  178. if ($sscert==FALSE)
  179. {
  180. // Show any errors that occurred here
  181. while (($e = openssl_error_string()) !== false)
  182. {
  183. error_log("cert". $e);
  184. //print "<br><br>";
  185. }
  186. }
  187. if (openssl_pkcs12_export($sscert, $p12Out, $userkey, "")==FALSE)
  188. {
  189. // Show any errors that occurred here
  190. while (($e = openssl_error_string()) !== false)
  191. {
  192. //echo $e . "\n";
  193. //print "<br><br>";
  194. }
  195. }
  196. return $p12Out;
  197. }
  198. // Send the p12 encoded SSL certificate as a file transfer
  199. function download_identity_p12($p12, $foafLocation)
  200. {
  201. // set headers
  202. header("Pragma: private");
  203. header("Expires: 0");
  204. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  205. header("Cache-Control: private");
  206. //header("Content-Description: File Transfer");
  207. header("Accept-Ranges: bytes");
  208. header('Content-Length: '.strlen($p12));
  209. header("Content-Type: application/x-x509-user-cert");
  210. $file = basename($foafLocation);
  211. //header("Content-Disposition: attachment; filename=\"$file.p12\"");
  212. //header("Content-Transfer-Encoding: binary");
  213. //header("Content-Length: " . strlen($p12));
  214. print($p12);
  215. flush();
  216. if (connection_status()!=0)
  217. {
  218. @fclose($file);
  219. die();
  220. }
  221. }
  222. //-----------------------------------------------------------------------------------------------------------------------------------
  223. //
  224. // Main
  225. //
  226. //-----------------------------------------------------------------------------------------------------------------------------------
  227. // Print out the permitted script parameters
  228. if ($_REQUEST[help])
  229. {
  230. print "cert.php?<br>";
  231. print "<ul>foaf=http://foaf.me/jsmith&<br><br>";
  232. print "commonName=J Smith&<br><br>";
  233. print "emailAddress=jsmith@example.com&<br><br>";
  234. print "organizationName=My Company Ltd&<br><br>";
  235. print "organizationalUnitName=Technology Division&<br><br>";
  236. print "localityName=Newbury&<br><br>";
  237. print "stateOrProvinceName=Berkshire&<br><br>";
  238. print "countryName=GB&<br><br>";
  239. print "password=secret<br></ul>";
  240. exit();
  241. }
  242. // Check if the foaf loaction is specified in the script call
  243. $foafLocation = $_REQUEST[foaf];
  244. if (!$foafLocation)
  245. {
  246. if (array_key_exists('foaf', $_REQUEST))
  247. $query = $_SERVER[QUERY_STRING];
  248. else
  249. $query = ($_SERVER[QUERY_STRING]?$_SERVER[QUERY_STRING]."&":"") . "foaf=";
  250. print "Please specify the location of your foaf file. <a href='https://foaf.me/cert.php?" . $query . "'>https://foaf.me/cert.php?foaf=</a><font color='red'><b>http://foaf.me/nickname</b></font><br><br>The FOAF location is added to the SubjectAltName within the SSL Client Certificate<br>";
  251. exit();
  252. }
  253. // Check that script is called using the HTTPS protocol
  254. if ($_SERVER[HTTPS] == NULL)
  255. {
  256. print "Please use the following secure uri to download the Identity P12. <a href='https://foaf.me/cert.php?" . $_SERVER[QUERY_STRING] . "'>https://foaf.me/cert.php?" . $_SERVER[QUERY_STRING] . "</a><br>";
  257. exit();
  258. }
  259. // Get the rest of the script parameters
  260. $countryName = $_REQUEST[countryName];
  261. $stateOrProvinceName = $_REQUEST[stateOrProvinceName];
  262. $localityName = $_REQUEST[localityName];
  263. $organizationName = $_REQUEST[organizationName];
  264. $organizationalUnitName = $_REQUEST[organizationalUnitName];
  265. $commonName = $_REQUEST[commonName];
  266. $emailAddress = $_REQUEST[emailAddress];
  267. $pubkey = $_REQUEST['pubkey'];
  268. error_log($emailAddress);
  269. error_log($pubkey);
  270. // Create a PKCS12 encoded SSL certificate
  271. if ( $p12 = create_identity_p12(
  272. $countryName, $stateOrProvinceName, $localityName, $organizationName, $organizationalUnitName, $commonName, $emailAddress,
  273. $foafLocation, $pubkey ) )
  274. {
  275. // Send the PKCS12 encoded SSL certificate to the script caller as a file transfer
  276. download_identity_p12($p12, $foafLocation);
  277. }
  278. ?>