diff options
-rw-r--r-- | includes/keygen.php | 23 | ||||
-rw-r--r-- | www/keygenIE.js | 236 |
2 files changed, 108 insertions, 151 deletions
diff --git a/includes/keygen.php b/includes/keygen.php index bf8bc5a..866c5f2 100644 --- a/includes/keygen.php +++ b/includes/keygen.php @@ -14,18 +14,18 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ +*/ if (array_key_exists('HTTP_USER_AGENT',$_SERVER) && strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) { ?> - + <noscript> <p><?=_('You have to enable JavaScript to generate certificates in '. 'the browser.')?></p> <p><?=_('If you don\'t want to do that for any reason, you can use '. 'manually created certificate requests instead.')?></p> </noscript> - + <div id="noActiveX" style="color:red"> <p><?=_('Could not initialize ActiveX object required for certificate '. 'generation.')?></p> @@ -44,7 +44,7 @@ if (array_key_exists('HTTP_USER_AGENT',$_SERVER) && 'https://'.$_SESSION['_config']['securehostname'])?> </p> </div> - + <form method="post" style="display:none" action="account.php" id="CertReqForm"> <input type="hidden" name="oldid" value="<?=$id?>" /> @@ -58,10 +58,10 @@ if (array_key_exists('HTTP_USER_AGENT',$_SERVER) && <option value="custom"><?=_('Custom')?>…</option> </select> </p> - + <fieldset id="customSettings" style="display:none"> <legend><?=_('Custom Parameters')?></legend> - + <p><?=_('Cryptography Provider')?>: <select id="CspProvider"></select> </p> @@ -82,14 +82,13 @@ if (array_key_exists('HTTP_USER_AGENT',$_SERVER) && 1024)?> </p> </fieldset> - + <p><input type="submit" id="GenReq" name="GenReq" value="<?=_('Create Certificate')?>" /></p> <p id="generatingKeyNotice" style="display:none"> <?=_('Generating your key. Please wait')?>…</p> </form> - - + <!-- Error messages used in the JavaScript. Defined here so they can be translated without passing the JavaScript code through PHP --> <p id="createRequestErrorChooseAlgorithm" style="display:none"> @@ -118,15 +117,15 @@ if (array_key_exists('HTTP_USER_AGENT',$_SERVER) && 'described in the red explanation text and accept loading of '. 'the module.')?> </p> - + <script type="text/javascript" src="keygenIE.js"></script> - + <? } else { ?> <p> <form method="post" action="account.php"> <input type="hidden" name="keytype" value="NS"> <?=_("Keysize:")?> <keygen name="SPKAC" challenge="<? $_SESSION['spkac_hash']=make_hash(); echo $_SESSION['spkac_hash']; ?>"> - + <input type="submit" name="submit" value="<?=_("Create Certificate Request")?>"> <input type="hidden" name="oldid" value="<?=$id?>"> </form> diff --git a/www/keygenIE.js b/www/keygenIE.js index dad84bb..2c2018e 100644 --- a/www/keygenIE.js +++ b/www/keygenIE.js @@ -1,4 +1,4 @@ -/* +/* LibreSSL - CAcert web application Copyright (C) 2004-2012 CAcert Inc. @@ -17,29 +17,26 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ var CAcert_keygen_IE = function () { - + /// Makes a new DOM text node var textnode = function (text) { return document.createTextNode(text); } - - + /// makes a new <p> element var paragraph = function (text) { var paragraph = document.createElement("p"); paragraph.appendChild(textnode(text)); return paragraph; } - - + /// makes a new <pre> elemtent var pre = function (text) { var pre = document.createElement("pre"); pre.appendChild(textnode(text)); return pre; } - - + /// makes a new <option> element var option = function (text, value) { var option = document.createElement("option"); @@ -49,14 +46,12 @@ var CAcert_keygen_IE = function () { option.appendChild(textnode(text)); return option; } - - + /// Removes all child nodes from the element var removeChildren = function (element) { element.innerHTML = ""; } - - + /// Show error message to user from exception var showError = function (message, exception) { window.alert(message + @@ -64,9 +59,7 @@ var CAcert_keygen_IE = function () { " (0x" + (0xFFFFFFFF + exception.number +1).toString(16) + " / " + exception.number + ")"); } - - - + // Get important elements from the DOM var form = document.getElementById("CertReqForm"); var securityLevel = document.getElementById("SecurityLevel"); @@ -88,15 +81,14 @@ var CAcert_keygen_IE = function () { var createRequestError = document.getElementById("createRequestError"); var invalidKeySizeError = document.getElementById("invalidKeySizeError"); var unsupportedPlatformError = document.getElementById("unsupportedPlatformError"); - - + /// Initialise the CertEnroll code (Vista and higher) /// returns false if initialisation fails var initCertEnroll = function () { var factory = null; var providerList = null; var cspStats = null; - + // Try to initialise the ActiveX element. Requires permissions by the user try { factory = new ActiveXObject( @@ -107,36 +99,33 @@ var CAcert_keygen_IE = function () { message: "Got null at object creation" }; } - + // also try to create a useless object here so the library gets // initialised and we don't need to check everytime later factory.CreateObject("X509Enrollment.CObjectId"); - + form.style.display = ""; noActiveX.style.display = "none"; } catch (e) { return false; } - - + /// Get the selected provider var getProvider = function () { var providerIndex = provider.options[provider.selectedIndex].value; return providerList.ItemByIndex(providerIndex); } - - + /// Get the selected algorithm var getAlgorithm = function () { var algorithmIndex = algorithm.options[algorithm.selectedIndex].value; return alg = cspStats.ItemByIndex(algorithmIndex).CspAlgorithm; } - - + /// Get the selected key size var getKeySize = function () { var alg = getAlgorithm(); - + var bits = parseInt(keySize.value, 10); if ( bits < alg.MinLength || bits > alg.MaxLength || (alg.IncrementLength && @@ -145,35 +134,33 @@ var CAcert_keygen_IE = function () { { return false; } - + return bits; } - - + /// Fill the key size list var getKeySizeList = function () { if (!cspStats) { return false; } - + var alg = getAlgorithm(); - + // HTML5 attributes keySize.setAttribute("min", alg.MinLength); keySize.setAttribute("max", alg.MaxLength); keySize.setAttribute("step", alg.IncrementLength); keySize.setAttribute("value", alg.DefaultLength); keySize.value = ""+alg.DefaultLength; - + // ugly, but buggy otherwise if done with text nodes keySizeMin.innerHTML = alg.MinLength; keySizeMax.innerHTML = alg.MaxLength; keySizeStep.innerHTML = alg.IncrementLength; - + return true; } - - + /// Fill the algorithm list var getAlgorithmList = function () { var i; @@ -181,9 +168,9 @@ var CAcert_keygen_IE = function () { if (!providerList) { return false; } - + var csp = getProvider(); - + cspStats = providerList.GetCspStatusesFromOperations( 0x1c, //XCN_NCRYPT_ANY_ASYMMETRIC_OPERATION //0x10, //XCN_NCRYPT_SIGNATURE_OPERATION @@ -191,43 +178,41 @@ var CAcert_keygen_IE = function () { //0x4, //XCN_NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION csp ); - + removeChildren(algorithm); for (i = 0; i < cspStats.Count; i++) { var alg = cspStats.ItemByIndex(i).CspAlgorithm; algorithm.appendChild(option(alg.Name, i)); } - + return getKeySizeList(); } - - + /// Fill the crypto provider list var getProviderList = function () { var i; var csps = factory.CreateObject("X509Enrollment.CCspInformations"); - + // Get provider information csps.AddAvailableCsps(); - + removeChildren(provider); - + for (i = 0; i < csps.Count; i++) { var csp = csps.ItemByIndex(i); provider.appendChild(option(csp.Name, i)); } - + providerList = csps; - + return getAlgorithmList(); } - - + /// Generate a key and create and submit the actual CSR var createCSR = function () { var providerName, algorithmOid, bits; - + var level = securityLevel.options[securityLevel.selectedIndex]; if (level.value === "custom") { providerName = getProvider().Name; @@ -238,30 +223,27 @@ var CAcert_keygen_IE = function () { window.alert(invalidKeySizeError.innerHTML); return false; } - } else { - providerName = "Microsoft Software Key Storage Provider"; - + algorithmOid = factory.CreateObject("X509Enrollment.CObjectId"); algorithmOid.InitializeFromValue("1.2.840.113549.1.1.1"); // RSA //"1.2.840.10040.4.1" == DSA //"1.2.840.10046.2.1" == DH - + if (level.value === "high") { bits = 4096; } else { // medium bits = 2048; } } - - + var privateKey = factory.CreateObject("X509Enrollment.CX509PrivateKey"); privateKey.ProviderName = providerName; privateKey.Algorithm = algorithmOid; privateKey.Length = bits; privateKey.KeyUsage = 0xffffff; // XCN_NCRYPT_ALLOW_ALL_USAGES - + var request = factory.CreateObject( "X509Enrollment.CX509CertificateRequestPkcs10"); request.InitializeFromPrivateKey( @@ -269,13 +251,12 @@ var CAcert_keygen_IE = function () { privateKey, "" // don't use a template ); - + var enroll = factory.CreateObject("X509Enrollment.CX509Enrollment"); enroll.InitializeFromRequest(request); - + generatingKeyNotice.style.display = ""; - - + // The request needs to be created after we return so the "please wait" // message gets rendered var createCSRHandler = function () { @@ -288,14 +269,13 @@ var CAcert_keygen_IE = function () { generatingKeyNotice.style.display = "none"; } - + window.setTimeout(createCSRHandler, 0); - + // Always return false, form is submitted by deferred method return false; } - - + /// Call if securityLevel has changed var refreshSecurityLevel = function () { var level = securityLevel.options[securityLevel.selectedIndex]; @@ -306,21 +286,20 @@ var CAcert_keygen_IE = function () { customSettings.style.display = "none"; } } - + securityLevel.onchange = refreshSecurityLevel; provider.onchange = getAlgorithmList; algorithm.onchange = getKeySizeList; genReq.onclick = createCSR; - + return true; } // end of initCertEnroll() - - + /// Initialise Xenroll code (XP and lower) /// returns false if initialisation fails var initXEnroll = function () { cenroll = null; - + providerTypes = Array( 1, //PROV_RSA_FULL 2, //PROV_RSA_SIG @@ -341,7 +320,7 @@ var CAcert_keygen_IE = function () { 23, //PROV_REPLACE_OWF 24 //PROV_RSA_AES ); - + algClasses = Array( 1 << 13, //ALG_CLASS_SIGNATURE //2 << 13, //ALG_CLASS_MSG_ENCRYPT @@ -349,125 +328,114 @@ var CAcert_keygen_IE = function () { //4 << 13, //ALG_CLASS_HASH 5 << 13 //ALG_CLASS_KEY_EXCHANGE ); - + // Try to initialise the ActiveX element. try { cenroll = new ActiveXObject("CEnroll.CEnroll"); - + if (!cenroll) { throw { name: "NoObjectError", message: "Got null at object creation" }; } - + form.style.display = ""; algorithm.disabled = true; noActiveX.style.display = "none"; } catch (e) { return false; } - - + /// Get the name of the selected provider var getProviderName = function () { return provider.options[provider.selectedIndex].text; } - - + /// Get the type of the selected provider var getProviderType = function () { return parseInt(provider.options[provider.selectedIndex].value, 10); } - - + var refreshProvider = function () { cenroll.ProviderName = getProviderName(); cenroll.ProviderType = getProviderType(); } - - + /// Get the ID of the selected algorithm var getAlgorithmId = function () { return parseInt( algorithm.options[algorithm.selectedIndex].value, 10); } - - + /// Minimum bit length for exchange keys var getMinExKeyLength = function () { refreshProvider(); - + try { return cenroll.GetKeyLen(true, true); } catch (e) { return false; } } - - + /// Maximum bit length for exchange keys var getMaxExKeyLength = function () { refreshProvider(); - + try { return cenroll.GetKeyLen(false, true); } catch (e) { return false; } } - - + /// Step size for exchange keys /// This might not be available on older platforms var getStepExKeyLength = function () { refreshProvider(); - + try { return cenroll.GetKeyLenEx(3, 1); } catch (e) { return false; } } - - + /// Minimum bit length for signature keys var getMinSigKeyLength = function () { refreshProvider(); - + try { return cenroll.GetKeyLen(true, false); } catch (e) { return false; } } - - + /// Maximum bit length for signature keys var getMaxSigKeyLength = function () { refreshProvider(); - + try { return cenroll.GetKeyLen(false, false); } catch (e) { return false; } } - - + /// Step size for signature keys /// This might not be available on older platforms var getStepSigKeyLength = function () { refreshProvider(); - + try { return cenroll.GetKeyLenEx(3, 2); } catch (e) { return false; } } - - + /// Get the selected key size var getKeySize = function () { var bits = parseInt(keySize.value, 10); @@ -479,11 +447,10 @@ var CAcert_keygen_IE = function () { { return false; } - + return bits; } - - + var getKeySizeLimits = function () { // HTML5 attributes keySize.setAttribute("min", getMinSigKeyLength()); @@ -491,28 +458,27 @@ var CAcert_keygen_IE = function () { if (getStepSigKeyLength()) { keySize.setAttribute("step", getStepSigKeyLength()); } - + // ugly, but buggy otherwise if done with text nodes keySizeMin.innerHTML = getMinSigKeyLength(); keySizeMax.innerHTML = getMaxSigKeyLength(); keySizeStep.innerHTML = getStepSigKeyLength(); - + if (getMinSigKeyLength() === getMaxSigKeyLength()) { keySize.value = getMaxSigKeyLength(); } - + return true; } - - + /// Fill the algorithm selection box var getAlgorithmList = function () { var i, j; refreshProvider(); - + removeChildren(algorithm); - + for (i = 0; i < algClasses.length; ++i) { for (j = 0; true; ++j) { try { @@ -524,20 +490,19 @@ var CAcert_keygen_IE = function () { } } } - + getKeySizeLimits(); } - - + /// Fill the provider selection box var getProviderList = function () { var i, j; removeChildren(provider); - + for (i = 0; i < providerTypes.length; ++i) { cenroll.providerType = providerTypes[i]; - + var providerName = "invalid"; for (j = 0; true; ++j) { try { @@ -549,43 +514,38 @@ var CAcert_keygen_IE = function () { } } } - + return getAlgorithmList(); } - - + var createCSR = function () { var providerName, bits; - + var level = securityLevel.options[securityLevel.selectedIndex]; if (level.value === "custom") { - refreshProvider(); - + bits = getKeySize(); if (bits === false) { window.alert(invalidKeySizeError.innerHTML); return false; } - } else { - cenroll.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0"; cenroll.ProviderType = 1; //PROV_RSA_FULL - + if (level.value === "high") { bits = 4096; } else { // medium bits = 2048; } } - + cenroll.GenKeyFlags = bits << 16; // keysize is encoded in the uper 16 bits //cenroll.GenKeyFlags = cenroll.GenKeyFlags | 0x1; //CRYPT_EXPORTABLE - + generatingKeyNotice.style.display = ""; - - + // The request needs to be created after we return so the "please wait" // message gets rendered var createCSRHandler = function () { @@ -603,18 +563,17 @@ var CAcert_keygen_IE = function () { showError(createRequestError.innerHTML, e); } } - + generatingKeyNotice.style.display = "none"; cenroll.Reset(); } - + window.setTimeout(createCSRHandler, 0); - + // Always return false, form is submitted by deferred method return false; } - - + /// Call if securityLevel has changed var refreshSecurityLevel = function () { var level = securityLevel.options[securityLevel.selectedIndex]; @@ -625,16 +584,15 @@ var CAcert_keygen_IE = function () { customSettings.style.display = "none"; } } - + securityLevel.onchange = refreshSecurityLevel; provider.onchange = getAlgorithmList; algorithm.onchange = getKeySizeLimits; genReq.onclick = createCSR; - + return true; }; - - + // Run the init functions until one is successful if (initCertEnroll()) { form.style.display = ""; |