From cdaf9a2e3e3318699c70c3a0358fbefe6c370948 Mon Sep 17 00:00:00 2001 From: Nathan Kinder Date: Tue, 13 Aug 2013 15:47:47 -0700 Subject: [PATCH] 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. --- admserv/cgi-src40/security.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/admserv/cgi-src40/security.c b/admserv/cgi-src40/security.c index 31da45d..def202b 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; } -- 1.7.11.7