From 4555aff338e70d646d4867460f37cfdd49b7f456 Mon Sep 17 00:00:00 2001 From: Nathan Kinder Date: Aug 14 2013 22:01:39 +0000 Subject: Ticket 362 - Directory Console generates insufficient key strength The security CGI that is called by the Console is limited terms of key generation and the signing algorithm used for the request. The RSA key size is limited to 1024 bit or less, and the signing algorithm is hardcoded to MD5. This patch increases the maximum RSA key size to 4096 and uses a default of 2048 if the caller doesn't specify a key size. The default signing algorithm is changed to SHA-1, and a new CGI parameter has been added to allow the caller to alternatively choose SHA-256, SHA-384, or SHA-512. --- diff --git a/admserv/cgi-src40/security.c b/admserv/cgi-src40/security.c index 1cee29d..3664d70 100644 --- a/admserv/cgi-src40/security.c +++ b/admserv/cgi-src40/security.c @@ -73,11 +73,8 @@ extern "C" { } #endif -#ifdef NS_DOMESTIC -#define MAX_KEY_BITS 1024/*2048*/ -#else -#define MAX_KEY_BITS 512/*1024*/ -#endif +#define DEFAULT_KEY_BITS 2048 +#define MAX_KEY_BITS 4096 #define SUBJECT_NEW "Certificate request" #define SUBJECT_OLD "Certificate renewal" @@ -1064,6 +1061,8 @@ generateCertificateRequest(SECKEYPrivateKey* privateKey, SECKEYPublicKey* pubKey PRArenaPool *arena = NULL; PRBool error = PR_FALSE; char *line; + char *sSignAlgo = NULL; + int signAlgo = 0; /*DebugBreak();*/ /* convert subject name(DN) */ certName = CERT_AsciiToName(subjectName); @@ -1101,8 +1100,25 @@ generateCertificateRequest(SECKEYPrivateKey* privateKey, SECKEYPublicKey* pubKey /* Encode the result will get a "request blob" */ der = (SECItem *)SEC_ASN1EncodeItem(arena, result, request, SEC_ASN1_GET(CERT_CertificateRequestTemplate)); + /* Determine the signing algorithm to use. We default + * to SHA-1 and support SHA-256, SHA-384, and SHA-512. */ + sSignAlgo = get_cgi_var("signingalgo", NULL, NULL); + + if (!sSignAlgo || !PORT_Strcmp(sSignAlgo, "SHA-1")) { + signAlgo = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; + } else if (!PORT_Strcmp(sSignAlgo, "SHA-256")) { + signAlgo = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; + } else if (!PORT_Strcmp(sSignAlgo, "SHA-384")) { + signAlgo = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; + } else if (!PORT_Strcmp(sSignAlgo, "SHA-512")) { + signAlgo = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; + } else { + /* Unknown algorithm, so just use the default. */ + signAlgo = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; + } + /* Sign certificate request(the blob) with private key */ - if (SEC_DerSignData(arena, result, der->data, der->len, privateKey, SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION) != SECSuccess) { + if (SEC_DerSignData(arena, result, der->data, der->len, privateKey, signAlgo) != SECSuccess) { rpt_err(GENERAL_FAILURE, getResourceString(DBT_INTERNAL_ERROR), getResourceString(DBT_CSR_GEN_FAIL), @@ -1172,16 +1188,16 @@ generateKey(SECKEYPublicKey** publicKey, char* tokenName) /* generate key pair */ { - char *sKeySize = get_cgi_var("keysize", NULL, NULL); int keySize = 0; if (sKeySize) { keySize = atoi(sKeySize); } - - if ((keySize > MAX_KEY_BITS) || (keySize <=0)) { + if (keySize > MAX_KEY_BITS) { params.keySizeInBits = MAX_KEY_BITS; + } else if (keySize <= 0) { + params.keySizeInBits = DEFAULT_KEY_BITS; } else { params.keySizeInBits = keySize; }