diff options
Diffstat (limited to 'security/nss/cmd')
-rw-r--r-- | security/nss/cmd/bltest/blapitest.c | 84 | ||||
-rw-r--r-- | security/nss/cmd/fipstest/fipstest.c | 525 | ||||
-rw-r--r-- | security/nss/cmd/lib/basicutil.c | 9 | ||||
-rw-r--r-- | security/nss/cmd/lib/pk11table.c | 28 | ||||
-rw-r--r-- | security/nss/cmd/lib/secutil.c | 76 | ||||
-rw-r--r-- | security/nss/cmd/lib/secutil.h | 2 | ||||
-rw-r--r-- | security/nss/cmd/lowhashtest/lowhashtest.c | 4 | ||||
-rw-r--r-- | security/nss/cmd/modutil/install-ds.c | 2 | ||||
-rw-r--r-- | security/nss/cmd/pk11gcmtest/pk11gcmtest.c | 4 | ||||
-rw-r--r-- | security/nss/cmd/pk11mode/pk11mode.c | 2 | ||||
-rw-r--r-- | security/nss/cmd/selfserv/selfserv.c | 109 | ||||
-rw-r--r-- | security/nss/cmd/shlibsign/shlibsign.c | 4 | ||||
-rw-r--r-- | security/nss/cmd/signtool/manifest.mn | 4 | ||||
-rw-r--r-- | security/nss/cmd/tstclnt/tstclnt.c | 60 |
14 files changed, 836 insertions, 77 deletions
diff --git a/security/nss/cmd/bltest/blapitest.c b/security/nss/cmd/bltest/blapitest.c index ef8fdd802..06654ef65 100644 --- a/security/nss/cmd/bltest/blapitest.c +++ b/security/nss/cmd/bltest/blapitest.c @@ -608,9 +608,11 @@ typedef enum { bltestDES_CBC, /* . */ bltestDES_EDE_ECB, /* . */ bltestDES_EDE_CBC, /* . */ - bltestRC2_ECB, /* . */ - bltestRC2_CBC, /* . */ - bltestRC4, /* . */ +#ifndef NSS_DISABLE_DEPRECATED_RC2 + bltestRC2_ECB, /* . */ + bltestRC2_CBC, /* . */ +#endif + bltestRC4, /* . */ #ifdef NSS_SOFTOKEN_DOES_RC5 bltestRC5_ECB, /* . */ bltestRC5_CBC, /* . */ @@ -622,21 +624,23 @@ typedef enum { bltestAES_GCM, /* . */ bltestCAMELLIA_ECB, /* . */ bltestCAMELLIA_CBC, /* . */ - bltestSEED_ECB, /* SEED algorithm */ - bltestSEED_CBC, /* SEED algorithm */ - bltestCHACHA20, /* ChaCha20 + Poly1305 */ - bltestRSA, /* Public Key Ciphers */ - bltestRSA_OAEP, /* . (Public Key Enc.) */ - bltestRSA_PSS, /* . (Public Key Sig.) */ - bltestECDSA, /* . (Public Key Sig.) */ - bltestDSA, /* . (Public Key Sig.) */ - bltestMD2, /* Hash algorithms */ - bltestMD5, /* . */ - bltestSHA1, /* . */ - bltestSHA224, /* . */ - bltestSHA256, /* . */ - bltestSHA384, /* . */ - bltestSHA512, /* . */ +#ifndef NSS_DISABLE_DEPRECATED_SEED + bltestSEED_ECB, /* SEED algorithm */ + bltestSEED_CBC, /* SEED algorithm */ +#endif + bltestCHACHA20, /* ChaCha20 + Poly1305 */ + bltestRSA, /* Public Key Ciphers */ + bltestRSA_OAEP, /* . (Public Key Enc.) */ + bltestRSA_PSS, /* . (Public Key Sig.) */ + bltestECDSA, /* . (Public Key Sig.) */ + bltestDSA, /* . (Public Key Sig.) */ + bltestMD2, /* Hash algorithms */ + bltestMD5, /* . */ + bltestSHA1, /* . */ + bltestSHA224, /* . */ + bltestSHA256, /* . */ + bltestSHA384, /* . */ + bltestSHA512, /* . */ NUMMODES } bltestCipherMode; @@ -646,8 +650,10 @@ static char *mode_strings[] = "des_cbc", "des3_ecb", "des3_cbc", +#ifndef NSS_DISABLE_DEPRECATED_RC2 "rc2_ecb", "rc2_cbc", +#endif "rc4", #ifdef NSS_SOFTOKEN_DOES_RC5 "rc5_ecb", @@ -660,8 +666,10 @@ static char *mode_strings[] = "aes_gcm", "camellia_ecb", "camellia_cbc", +#ifndef NSS_DISABLE_DEPRECATED_SEED "seed_ecb", "seed_cbc", +#endif "chacha20_poly1305", "rsa", "rsa_oaep", @@ -792,8 +800,12 @@ struct bltestCipherInfoStr { PRBool is_symmkeyCipher(bltestCipherMode mode) { - /* change as needed! */ +/* change as needed! */ +#ifndef NSS_DISABLE_DEPRECATED_SEED if (mode >= bltestDES_ECB && mode <= bltestSEED_CBC) +#else + if (mode >= bltestDES_ECB && mode <= bltestCAMELLIA_CBC) +#endif return PR_TRUE; return PR_FALSE; } @@ -871,7 +883,9 @@ cipher_requires_IV(bltestCipherMode mode) switch (mode) { case bltestDES_CBC: case bltestDES_EDE_CBC: +#ifndef NSS_DISABLE_DEPRECATED_RC2 case bltestRC2_CBC: +#endif #ifdef NSS_SOFTOKEN_DOES_RC5 case bltestRC5_CBC: #endif @@ -880,7 +894,9 @@ cipher_requires_IV(bltestCipherMode mode) case bltestAES_CTR: case bltestAES_GCM: case bltestCAMELLIA_CBC: +#ifndef NSS_DISABLE_DEPRECATED_SEED case bltestSEED_CBC: +#endif case bltestCHACHA20: return PR_TRUE; default: @@ -1078,6 +1094,7 @@ des_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen, input, inputLen); } +#ifndef NSS_DISABLE_DEPRECATED_RC2 SECStatus rc2_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, const unsigned char *input, @@ -1095,6 +1112,7 @@ rc2_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen, return RC2_Decrypt((RC2Context *)cx, output, outputLen, maxOutputLen, input, inputLen); } +#endif /* NSS_DISABLE_DEPRECATED_RC2 */ SECStatus rc4_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen, @@ -1176,6 +1194,7 @@ camellia_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen, input, inputLen); } +#ifndef NSS_DISABLE_DEPRECATED_SEED SECStatus seed_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, const unsigned char *input, @@ -1193,6 +1212,7 @@ seed_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen, return SEED_Decrypt((SEEDContext *)cx, output, outputLen, maxOutputLen, input, inputLen); } +#endif /* NSS_DISABLE_DEPRECATED_SEED */ SECStatus rsa_PublicKeyOp(void *cx, SECItem *output, const SECItem *input) @@ -1361,6 +1381,7 @@ bltest_des_init(bltestCipherInfo *cipherInfo, PRBool encrypt) return SECSuccess; } +#ifndef NSS_DISABLE_DEPRECATED_RC2 SECStatus bltest_rc2_init(bltestCipherInfo *cipherInfo, PRBool encrypt) { @@ -1406,6 +1427,7 @@ bltest_rc2_init(bltestCipherInfo *cipherInfo, PRBool encrypt) cipherInfo->cipher.symmkeyCipher = rc2_Decrypt; return SECSuccess; } +#endif /* NSS_DISABLE_DEPRECATED_RC2 */ SECStatus bltest_rc4_init(bltestCipherInfo *cipherInfo, PRBool encrypt) @@ -1481,7 +1503,7 @@ bltest_aes_init(bltestCipherInfo *cipherInfo, PRBool encrypt) unsigned char *params; int len; CK_AES_CTR_PARAMS ctrParams; - CK_GCM_PARAMS gcmParams; + CK_NSS_GCM_PARAMS gcmParams; params = aesp->iv.buf.data; switch (cipherInfo->mode) { @@ -1587,6 +1609,7 @@ bltest_camellia_init(bltestCipherInfo *cipherInfo, PRBool encrypt) return SECSuccess; } +#ifndef NSS_DISABLE_DEPRECATED_SEED SECStatus bltest_seed_init(bltestCipherInfo *cipherInfo, PRBool encrypt) { @@ -1630,6 +1653,7 @@ bltest_seed_init(bltestCipherInfo *cipherInfo, PRBool encrypt) return SECSuccess; } +#endif /* NSS_DISABLE_DEPRECATED_SEED */ SECStatus bltest_chacha20_init(bltestCipherInfo *cipherInfo, PRBool encrypt) @@ -2245,12 +2269,14 @@ cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt) cipherInfo->input.pBuf.len); return bltest_des_init(cipherInfo, encrypt); break; +#ifndef NSS_DISABLE_DEPRECATED_RC2 case bltestRC2_ECB: case bltestRC2_CBC: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, cipherInfo->input.pBuf.len); return bltest_rc2_init(cipherInfo, encrypt); break; +#endif /* NSS_DISABLE_DEPRECATED_RC2 */ case bltestRC4: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, cipherInfo->input.pBuf.len); @@ -2282,12 +2308,14 @@ cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt) cipherInfo->input.pBuf.len); return bltest_camellia_init(cipherInfo, encrypt); break; +#ifndef NSS_DISABLE_DEPRECATED_SEED case bltestSEED_ECB: case bltestSEED_CBC: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, cipherInfo->input.pBuf.len); return bltest_seed_init(cipherInfo, encrypt); break; +#endif /* NSS_DISABLE_DEPRECATED_SEED */ case bltestCHACHA20: outlen = cipherInfo->input.pBuf.len + (encrypt ? 16 : 0); SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen); @@ -2586,19 +2614,23 @@ cipherFinish(bltestCipherInfo *cipherInfo) case bltestCAMELLIA_CBC: Camellia_DestroyContext((CamelliaContext *)cipherInfo->cx, PR_TRUE); break; +#ifndef NSS_DISABLE_DEPRECATED_SEED case bltestSEED_ECB: case bltestSEED_CBC: SEED_DestroyContext((SEEDContext *)cipherInfo->cx, PR_TRUE); break; +#endif /* NSS_DISABLE_DEPRECATED_SEED */ case bltestCHACHA20: ChaCha20Poly1305_DestroyContext((ChaCha20Poly1305Context *) cipherInfo->cx, PR_TRUE); break; +#ifndef NSS_DISABLE_DEPRECATED_RC2 case bltestRC2_ECB: case bltestRC2_CBC: RC2_DestroyContext((RC2Context *)cipherInfo->cx, PR_TRUE); break; +#endif /* NSS_DISABLE_DEPRECATED_RC2 */ case bltestRC4: RC4_DestroyContext((RC4Context *)cipherInfo->cx, PR_TRUE); break; @@ -2747,10 +2779,14 @@ print_td: case bltestAES_GCM: case bltestCAMELLIA_ECB: case bltestCAMELLIA_CBC: +#ifndef NSS_DISABLE_DEPRECATED_SEED case bltestSEED_ECB: case bltestSEED_CBC: +#endif +#ifndef NSS_DISABLE_DEPRECATED_RC2 case bltestRC2_ECB: case bltestRC2_CBC: +#endif case bltestRC4: if (td) fprintf(stdout, "%8s", "symmkey"); @@ -2934,21 +2970,29 @@ get_params(PLArenaPool *arena, bltestParams *params, load_file_data(arena, ¶ms->ask.aad, filename, bltestBinary); case bltestDES_CBC: case bltestDES_EDE_CBC: +#ifndef NSS_DISABLE_DEPRECATED_RC2 case bltestRC2_CBC: +#endif case bltestAES_CBC: case bltestAES_CTS: case bltestAES_CTR: case bltestCAMELLIA_CBC: +#ifndef NSS_DISABLE_DEPRECATED_SEED case bltestSEED_CBC: +#endif sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j); load_file_data(arena, ¶ms->sk.iv, filename, bltestBinary); case bltestDES_ECB: case bltestDES_EDE_ECB: +#ifndef NSS_DISABLE_DEPRECATED_RC2 case bltestRC2_ECB: +#endif case bltestRC4: case bltestAES_ECB: case bltestCAMELLIA_ECB: +#ifndef NSS_DISABLE_DEPRECATED_SEED case bltestSEED_ECB: +#endif sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j); load_file_data(arena, ¶ms->sk.key, filename, bltestBinary); break; diff --git a/security/nss/cmd/fipstest/fipstest.c b/security/nss/cmd/fipstest/fipstest.c index 1a8008d59..abf7ec168 100644 --- a/security/nss/cmd/fipstest/fipstest.c +++ b/security/nss/cmd/fipstest/fipstest.c @@ -1027,7 +1027,7 @@ aes_gcm(char *reqfn, int encrypt) unsigned int tagbits; unsigned int taglen = 0; unsigned int ivlen; - CK_GCM_PARAMS params; + CK_NSS_GCM_PARAMS params; SECStatus rv; aesreq = fopen(reqfn, "r"); @@ -8231,6 +8231,527 @@ loser: fclose(ikereq); } +void +kbkdf(char *path) +{ + /* == Parser data == */ + char buf[610]; /* holds one line from the input REQUEST file. Needs to + * be large enough to hold the longest line: + * "KO = <600 hex digits>\n". */ + CK_ULONG L; + unsigned char KI[64]; + unsigned int KI_len = 64; + unsigned char KO[300]; + unsigned int KO_len = 300; + /* This is used only with feedback mode. */ + unsigned char IV[64]; + unsigned int IV_len = 64; + /* These are only used in counter mode with counter location as + * MIDDLE_FIXED. */ + unsigned char BeforeFixedInputData[50]; + unsigned int BeforeFixedInputData_len = 50; + unsigned char AfterFixedInputData[10]; + unsigned int AfterFixedInputData_len = 10; + /* These are used with every KDF type. */ + unsigned char FixedInputData[60]; + unsigned int FixedInputData_len = 60; + + /* Counter locations: + * + * 0: not used + * 1: beginning + * 2: middle + * 3: end */ + int ctr_location = 0; + CK_ULONG counter_bitlen = 0; + + size_t buf_offset; + size_t offset; + + FILE *kbkdf_req = NULL; + FILE *kbkdf_resp = NULL; + + /* == PKCS#11 data == */ + CK_RV crv; + + CK_SLOT_ID slotList[10]; + CK_SLOT_ID slotID; + CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]); + CK_ULONG slotCount = 0; + + CK_MECHANISM kdf = { 0 }; + + CK_MECHANISM_TYPE prf_mech = 0; + CK_BBOOL ck_true = CK_TRUE; + + /* We never need more than 3 data parameters. */ + CK_PRF_DATA_PARAM dataParams[3]; + CK_ULONG dataParams_len = 3; + + CK_SP800_108_COUNTER_FORMAT iterator = { CK_FALSE, 0 }; + + CK_SP800_108_KDF_PARAMS kdfParams = { 0 }; + CK_SP800_108_FEEDBACK_KDF_PARAMS feedbackParams = { 0 }; + + CK_OBJECT_CLASS ck_secret_key = CKO_SECRET_KEY; + CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET; + + CK_ATTRIBUTE prf_template[] = { + { CKA_VALUE, &KI, sizeof(KI) }, + { CKA_CLASS, &ck_secret_key, sizeof(ck_secret_key) }, + { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, + { CKA_DERIVE, &ck_true, sizeof(ck_true) } + }; + CK_ULONG prf_template_count = sizeof(prf_template) / sizeof(prf_template[0]); + + CK_ATTRIBUTE derive_template[] = { + { CKA_CLASS, &ck_secret_key, sizeof(ck_secret_key) }, + { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + { CKA_VALUE_LEN, &L, sizeof(L) } + }; + CK_ULONG derive_template_count = sizeof(derive_template) / sizeof(derive_template[0]); + + CK_ATTRIBUTE output_key = { CKA_VALUE, KO, KO_len }; + + const CK_C_INITIALIZE_ARGS pk11args = { + NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS, + (void *)"flags=readOnly,noCertDB,noModDB", NULL + }; + + /* == Start up PKCS#11 == */ + crv = NSC_Initialize((CK_VOID_PTR)&pk11args); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv); + goto done; + } + + slotCount = slotListCount; + crv = NSC_GetSlotList(PR_TRUE, slotList, &slotCount); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv); + goto done; + } + if ((slotCount > slotListCount) || slotCount < 1) { + fprintf(stderr, + "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n", + (int)slotCount, (int)slotListCount); + goto done; + } + slotID = slotList[0]; + + /* == Start parsing the file == */ + kbkdf_req = fopen(path, "r"); + kbkdf_resp = stdout; + + while (fgets(buf, sizeof buf, kbkdf_req) != NULL) { + /* If we have a comment, check if it tells us the type of KDF to use. + * This differs per-file, so we have to parse it. */ + if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') { + if (strncmp(buf, "# KDF Mode Supported: Counter Mode", 34) == 0) { + kdf.mechanism = CKM_SP800_108_COUNTER_KDF; + } + if (strncmp(buf, "# KDF Mode Supported: Feedback Mode", 35) == 0) { + kdf.mechanism = CKM_SP800_108_FEEDBACK_KDF; + } + if (strncmp(buf, "# KDF Mode Supported: DblPipeline Mode", 38) == 0) { + kdf.mechanism = CKM_SP800_108_DOUBLE_PIPELINE_KDF; + } + + fputs(buf, kbkdf_resp); + continue; + } + + /* [....] - context directive */ + if (buf[0] == '[') { + /* PRF begins each new section. */ + if (strncmp(buf, "[PRF=CMAC_AES128]", 17) == 0) { + prf_mech = CKM_AES_CMAC; + KI_len = 16; + } else if (strncmp(buf, "[PRF=CMAC_AES192]", 17) == 0) { + prf_mech = CKM_AES_CMAC; + KI_len = 24; + } else if (strncmp(buf, "[PRF=CMAC_AES256]", 17) == 0) { + prf_mech = CKM_AES_CMAC; + KI_len = 32; + } else if (strncmp(buf, "[PRF=HMAC_SHA1]", 15) == 0) { + prf_mech = CKM_SHA_1_HMAC; + KI_len = 20; + } else if (strncmp(buf, "[PRF=HMAC_SHA224]", 17) == 0) { + prf_mech = CKM_SHA224_HMAC; + KI_len = 28; + } else if (strncmp(buf, "[PRF=HMAC_SHA256]", 17) == 0) { + prf_mech = CKM_SHA256_HMAC; + KI_len = 32; + } else if (strncmp(buf, "[PRF=HMAC_SHA384]", 17) == 0) { + prf_mech = CKM_SHA384_HMAC; + KI_len = 48; + } else if (strncmp(buf, "[PRF=HMAC_SHA512]", 17) == 0) { + prf_mech = CKM_SHA512_HMAC; + KI_len = 64; + } else if (strncmp(buf, "[PRF=", 5) == 0) { + fprintf(stderr, "Invalid or unsupported PRF mechanism: %s\n", buf); + goto done; + } + + /* Then comes counter, if present. */ + if (strncmp(buf, "[CTRLOCATION=BEFORE_FIXED]", 26) == 0 || + strncmp(buf, "[CTRLOCATION=BEFORE_ITER]", 24) == 0) { + ctr_location = 1; + } + if (strncmp(buf, "[CTRLOCATION=MIDDLE_FIXED]", 26) == 0 || + strncmp(buf, "[CTRLOCATION=AFTER_ITER]", 24) == 0) { + ctr_location = 2; + } + if (strncmp(buf, "[CTRLOCATION=AFTER_FIXED]", 25) == 0) { + ctr_location = 3; + } + + /* If counter is present, then we need to know its size. */ + if (strncmp(buf, "[RLEN=", 6) == 0) { + if (sscanf(buf, "[RLEN=%lu_BITS]", &counter_bitlen) != 1) { + goto done; + } + } + + fputs(buf, kbkdf_resp); + continue; + } + + /* Each test contains a counter, an output length L, an input key KI, + * maybe an initialization vector IV, one of a couple of fixed data + * buffers, and finally the output key KO. */ + + /* First comes COUNT. */ + if (strncmp(buf, "COUNT=", 6) == 0) { + /* Clear all out data fields on each test. */ + memset(KI, 0, sizeof KI); + memset(KO, 0, sizeof KO); + memset(IV, 0, sizeof IV); + memset(BeforeFixedInputData, 0, sizeof BeforeFixedInputData); + memset(AfterFixedInputData, 0, sizeof AfterFixedInputData); + memset(FixedInputData, 0, sizeof FixedInputData); + + /* Then reset lengths except KI: it was determined by PRF + * selection above. */ + KO_len = 0; + IV_len = 0; + BeforeFixedInputData_len = 0; + AfterFixedInputData_len = 0; + FixedInputData_len = 0; + + fputs(buf, kbkdf_resp); + continue; + } + + /* Then comes L. */ + if (strncmp(buf, "L = ", 4) == 0) { + if (sscanf(buf, "L = %lu", &L) != 1) { + goto done; + } + + if ((L % 8) != 0) { + fprintf(stderr, "Assumption that L was length in bits incorrect: %lu - %s", L, buf); + fprintf(stderr, "Note that NSS only supports byte-aligned outputs and not bit-aligned outputs.\n"); + goto done; + } + + L = L / 8; + + fputs(buf, kbkdf_resp); + continue; + } + + /* Then comes KI. */ + if (strncmp(buf, "KI = ", 5) == 0) { + buf_offset = 5; + + for (offset = 0; offset < KI_len; offset++, buf_offset += 2) { + hex_to_byteval(buf + buf_offset, KI + offset); + } + + fputs(buf, kbkdf_resp); + continue; + } + + /* Then comes IVlen and IV, if present. */ + if (strncmp(buf, "IVlen = ", 8) == 0) { + if (sscanf(buf, "IVlen = %u", &IV_len) != 1) { + goto done; + } + + if ((IV_len % 8) != 0) { + fprintf(stderr, "Assumption that IV_len was length in bits incorrect: %u - %s. ", IV_len, buf); + fprintf(stderr, "Note that NSS only supports byte-aligned inputs and not bit-aligned inputs.\n"); + goto done; + } + + /* Need the IV length in bytes, not bits. */ + IV_len = IV_len / 8; + + fputs(buf, kbkdf_resp); + continue; + } + if (strncmp(buf, "IV = ", 5) == 0) { + buf_offset = 5; + + for (offset = 0; offset < IV_len; offset++, buf_offset += 2) { + hex_to_byteval(buf + buf_offset, IV + offset); + } + + fputs(buf, kbkdf_resp); + continue; + } + + /* We might have DataBeforeCtr and DataAfterCtr if present. */ + if (strncmp(buf, "DataBeforeCtrLen = ", 19) == 0) { + if (sscanf(buf, "DataBeforeCtrLen = %u", &BeforeFixedInputData_len) != 1) { + goto done; + } + + fputs(buf, kbkdf_resp); + continue; + } + if (strncmp(buf, "DataBeforeCtrData = ", 20) == 0) { + buf_offset = 20; + + for (offset = 0; offset < BeforeFixedInputData_len; offset++, buf_offset += 2) { + hex_to_byteval(buf + buf_offset, BeforeFixedInputData + offset); + } + + fputs(buf, kbkdf_resp); + continue; + } + if (strncmp(buf, "DataAfterCtrLen = ", 18) == 0) { + if (sscanf(buf, "DataAfterCtrLen = %u", &AfterFixedInputData_len) != 1) { + goto done; + } + + fputs(buf, kbkdf_resp); + continue; + } + if (strncmp(buf, "DataAfterCtrData = ", 19) == 0) { + buf_offset = 19; + + for (offset = 0; offset < AfterFixedInputData_len; offset++, buf_offset += 2) { + hex_to_byteval(buf + buf_offset, AfterFixedInputData + offset); + } + + fputs(buf, kbkdf_resp); + continue; + } + + /* Otherwise, we might have FixedInputData, if present. */ + if (strncmp(buf, "FixedInputDataByteLen = ", 24) == 0) { + if (sscanf(buf, "FixedInputDataByteLen = %u", &FixedInputData_len) != 1) { + goto done; + } + + fputs(buf, kbkdf_resp); + continue; + } + if (strncmp(buf, "FixedInputData = ", 17) == 0) { + buf_offset = 17; + + for (offset = 0; offset < FixedInputData_len; offset++, buf_offset += 2) { + hex_to_byteval(buf + buf_offset, FixedInputData + offset); + } + + fputs(buf, kbkdf_resp); + continue; + } + + /* Finally, run the KBKDF calculation when KO is passed. */ + if (strncmp(buf, "KO = ", 5) == 0) { + CK_SESSION_HANDLE session; + CK_OBJECT_HANDLE prf_key; + CK_OBJECT_HANDLE derived_key; + + /* Open the session. */ + crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_OpenSession failed crv=0x%x\n", (unsigned int)crv); + goto done; + } + + /* Create the PRF key object. */ + prf_template[0].ulValueLen = KI_len; + crv = NSC_CreateObject(session, prf_template, prf_template_count, &prf_key); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_CreateObject (prf_key) failed crv=0x%x\n", (unsigned int)crv); + goto done; + } + + /* Set up the KDF parameters. */ + if (kdf.mechanism == CKM_SP800_108_COUNTER_KDF) { + /* Counter operates in one of three ways: counter before fixed + * input data, counter between fixed input data, and counter + * after fixed input data. In all cases, we have an iterator. + */ + iterator.ulWidthInBits = counter_bitlen; + + if (ctr_location == 0 || ctr_location > 3) { + fprintf(stderr, "Expected ctr_location != 0 for Counter Mode KDF but got 0.\n"); + goto done; + } else if (ctr_location == 1) { + /* Counter before */ + dataParams[0].type = CK_SP800_108_ITERATION_VARIABLE; + dataParams[0].pValue = &iterator; + dataParams[0].ulValueLen = sizeof(iterator); + + dataParams[1].type = CK_SP800_108_BYTE_ARRAY; + dataParams[1].pValue = FixedInputData; + dataParams[1].ulValueLen = FixedInputData_len; + + dataParams_len = 2; + } else if (ctr_location == 2) { + /* Counter between */ + dataParams[0].type = CK_SP800_108_BYTE_ARRAY; + dataParams[0].pValue = BeforeFixedInputData; + dataParams[0].ulValueLen = BeforeFixedInputData_len; + + dataParams[1].type = CK_SP800_108_ITERATION_VARIABLE; + dataParams[1].pValue = &iterator; + dataParams[1].ulValueLen = sizeof(iterator); + + dataParams[2].type = CK_SP800_108_BYTE_ARRAY; + dataParams[2].pValue = AfterFixedInputData; + dataParams[2].ulValueLen = AfterFixedInputData_len; + + dataParams_len = 3; + } else { + /* Counter after */ + dataParams[0].type = CK_SP800_108_BYTE_ARRAY; + dataParams[0].pValue = FixedInputData; + dataParams[0].ulValueLen = FixedInputData_len; + + dataParams[1].type = CK_SP800_108_ITERATION_VARIABLE; + dataParams[1].pValue = &iterator; + dataParams[1].ulValueLen = sizeof(iterator); + + dataParams_len = 2; + } + } else if (kdf.mechanism == CKM_SP800_108_FEEDBACK_KDF || kdf.mechanism == CKM_SP800_108_DOUBLE_PIPELINE_KDF) { + /* When counter_bitlen != 0, we have an optional counter. */ + if (counter_bitlen != 0) { + iterator.ulWidthInBits = counter_bitlen; + + if (ctr_location == 0 || ctr_location > 3) { + fprintf(stderr, "Expected ctr_location != 0 for Counter Mode KDF but got 0.\n"); + goto done; + } else if (ctr_location == 1) { + /* Counter before */ + dataParams[0].type = CK_SP800_108_OPTIONAL_COUNTER; + dataParams[0].pValue = &iterator; + dataParams[0].ulValueLen = sizeof(iterator); + + dataParams[1].type = CK_SP800_108_ITERATION_VARIABLE; + dataParams[1].pValue = NULL; + dataParams[1].ulValueLen = 0; + + dataParams[2].type = CK_SP800_108_BYTE_ARRAY; + dataParams[2].pValue = FixedInputData; + dataParams[2].ulValueLen = FixedInputData_len; + + dataParams_len = 3; + } else if (ctr_location == 2) { + /* Counter between */ + dataParams[0].type = CK_SP800_108_ITERATION_VARIABLE; + dataParams[0].pValue = NULL; + dataParams[0].ulValueLen = 0; + + dataParams[1].type = CK_SP800_108_OPTIONAL_COUNTER; + dataParams[1].pValue = &iterator; + dataParams[1].ulValueLen = sizeof(iterator); + + dataParams[2].type = CK_SP800_108_BYTE_ARRAY; + dataParams[2].pValue = FixedInputData; + dataParams[2].ulValueLen = FixedInputData_len; + + dataParams_len = 3; + } else { + /* Counter after */ + dataParams[0].type = CK_SP800_108_ITERATION_VARIABLE; + dataParams[0].pValue = NULL; + dataParams[0].ulValueLen = 0; + + dataParams[1].type = CK_SP800_108_BYTE_ARRAY; + dataParams[1].pValue = FixedInputData; + dataParams[1].ulValueLen = FixedInputData_len; + + dataParams[2].type = CK_SP800_108_OPTIONAL_COUNTER; + dataParams[2].pValue = &iterator; + dataParams[2].ulValueLen = sizeof(iterator); + + dataParams_len = 3; + } + } else { + dataParams[0].type = CK_SP800_108_ITERATION_VARIABLE; + dataParams[0].pValue = NULL; + dataParams[0].ulValueLen = 0; + + dataParams[1].type = CK_SP800_108_BYTE_ARRAY; + dataParams[1].pValue = FixedInputData; + dataParams[1].ulValueLen = FixedInputData_len; + + dataParams_len = 2; + } + } + + if (kdf.mechanism != CKM_SP800_108_FEEDBACK_KDF) { + kdfParams.prfType = prf_mech; + kdfParams.ulNumberOfDataParams = dataParams_len; + kdfParams.pDataParams = dataParams; + + kdf.pParameter = &kdfParams; + kdf.ulParameterLen = sizeof(kdfParams); + } else { + feedbackParams.prfType = prf_mech; + feedbackParams.ulNumberOfDataParams = dataParams_len; + feedbackParams.pDataParams = dataParams; + feedbackParams.ulIVLen = IV_len; + if (IV_len == 0) { + feedbackParams.pIV = NULL; + } else { + feedbackParams.pIV = IV; + } + + kdf.pParameter = &feedbackParams; + kdf.ulParameterLen = sizeof(feedbackParams); + } + + crv = NSC_DeriveKey(session, &kdf, prf_key, derive_template, derive_template_count, &derived_key); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_DeriveKey(derived_key) failed crv=0x%x\n", (unsigned int)crv); + goto done; + } + + crv = NSC_GetAttributeValue(session, derived_key, &output_key, 1); + if (crv != CKR_OK) { + fprintf(stderr, "NSC_GetAttribute(derived_value) failed crv=0x%x\n", (unsigned int)crv); + goto done; + } + + fputs("KO = ", kbkdf_resp); + to_hex_str(buf, KO, output_key.ulValueLen); + fputs(buf, kbkdf_resp); + fputs("\r\n", kbkdf_resp); + + continue; + } + } + +done: + if (kbkdf_req != NULL) { + fclose(kbkdf_req); + } + if (kbkdf_resp != stdout && kbkdf_resp != NULL) { + fclose(kbkdf_resp); + } + + return; +} + int main(int argc, char **argv) { @@ -8410,6 +8931,8 @@ main(int argc, char **argv) ikev1_psk(argv[2]); } else if (strcmp(argv[1], "ikev2") == 0) { ikev2(argv[2]); + } else if (strcmp(argv[1], "kbkdf") == 0) { + kbkdf(argv[2]); } return 0; } diff --git a/security/nss/cmd/lib/basicutil.c b/security/nss/cmd/lib/basicutil.c index de56fbdd9..476475d90 100644 --- a/security/nss/cmd/lib/basicutil.c +++ b/security/nss/cmd/lib/basicutil.c @@ -17,6 +17,7 @@ #include "basicutil.h" #include <stdarg.h> +#include <stddef.h> #include <sys/stat.h> #include <errno.h> @@ -632,7 +633,8 @@ void SECU_PrintPRandOSError(const char *progName) { char buffer[513]; - PRInt32 errLen = PR_GetErrorTextLength(); + PRInt32 errLenInt = PR_GetErrorTextLength(); + size_t errLen = errLenInt < 0 ? 0 : (size_t)errLenInt; if (errLen > 0 && errLen < sizeof buffer) { PR_GetErrorText(buffer); } @@ -739,7 +741,6 @@ SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str) int byteval = 0; int tmp = PORT_Strlen(str); - PORT_Assert(arena); PORT_Assert(item); if ((tmp % 2) != 0) { @@ -760,7 +761,9 @@ SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str) } else if ((str[i] >= 'A') && (str[i] <= 'F')) { tmp = str[i] - 'A' + 10; } else { - /* item is in arena and gets freed by the caller */ + if (!arena) { + SECITEM_FreeItem(item, PR_FALSE); + } return NULL; } diff --git a/security/nss/cmd/lib/pk11table.c b/security/nss/cmd/lib/pk11table.c index ec5d88926..f7a45fa84 100644 --- a/security/nss/cmd/lib/pk11table.c +++ b/security/nss/cmd/lib/pk11table.c @@ -102,7 +102,7 @@ const Constant _consts[] = { mkEntry(CKF_WRAP, MechanismFlags), mkEntry(CKF_UNWRAP, MechanismFlags), mkEntry(CKF_DERIVE, MechanismFlags), - mkEntry(CKF_EC_FP, MechanismFlags), + mkEntry(CKF_EC_F_P, MechanismFlags), mkEntry(CKF_EC_F_2M, MechanismFlags), mkEntry(CKF_EC_ECPARAMETERS, MechanismFlags), mkEntry(CKF_EC_NAMEDCURVE, MechanismFlags), @@ -128,7 +128,6 @@ const Constant _consts[] = { mkEntry(CKO_SECRET_KEY, Object), mkEntry(CKO_HW_FEATURE, Object), mkEntry(CKO_DOMAIN_PARAMETERS, Object), - mkEntry(CKO_KG_PARAMETERS, Object), mkEntry(CKO_NSS_CRL, Object), mkEntry(CKO_NSS_SMIME, Object), mkEntry(CKO_NSS_TRUST, Object), @@ -255,8 +254,8 @@ const Constant _consts[] = { mkEntry2(CKA_TRUST_TIME_STAMPING, Attribute, Trust), mkEntry2(CKA_CERT_SHA1_HASH, Attribute, None), mkEntry2(CKA_CERT_MD5_HASH, Attribute, None), - mkEntry2(CKA_NETSCAPE_DB, Attribute, None), - mkEntry2(CKA_NETSCAPE_TRUST, Attribute, Trust), + mkEntry2(CKA_NSS_DB, Attribute, None), + mkEntry2(CKA_NSS_TRUST, Attribute, Trust), mkEntry(CKM_RSA_PKCS, Mechanism), mkEntry(CKM_RSA_9796, Mechanism), @@ -473,16 +472,16 @@ const Constant _consts[] = { mkEntry(CKM_DH_PKCS_PARAMETER_GEN, Mechanism), mkEntry(CKM_NSS_AES_KEY_WRAP, Mechanism), mkEntry(CKM_NSS_AES_KEY_WRAP_PAD, Mechanism), - mkEntry(CKM_NETSCAPE_PBE_SHA1_DES_CBC, Mechanism), - mkEntry(CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, Mechanism), - mkEntry(CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC, Mechanism), - mkEntry(CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC, Mechanism), - mkEntry(CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4, Mechanism), - mkEntry(CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4, Mechanism), - mkEntry(CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC, Mechanism), - mkEntry(CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN, Mechanism), - mkEntry(CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN, Mechanism), - mkEntry(CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, Mechanism), + mkEntry(CKM_NSS_PBE_SHA1_DES_CBC, Mechanism), + mkEntry(CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC, Mechanism), + mkEntry(CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC, Mechanism), + mkEntry(CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC, Mechanism), + mkEntry(CKM_NSS_PBE_SHA1_40_BIT_RC4, Mechanism), + mkEntry(CKM_NSS_PBE_SHA1_128_BIT_RC4, Mechanism), + mkEntry(CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC, Mechanism), + mkEntry(CKM_NSS_PBE_SHA1_HMAC_KEY_GEN, Mechanism), + mkEntry(CKM_NSS_PBE_MD5_HMAC_KEY_GEN, Mechanism), + mkEntry(CKM_NSS_PBE_MD2_HMAC_KEY_GEN, Mechanism), mkEntry(CKM_TLS_PRF_GENERAL, Mechanism), mkEntry(CKM_NSS_TLS_PRF_GENERAL_SHA256, Mechanism), @@ -520,7 +519,6 @@ const Constant _consts[] = { mkEntry(CKR_KEY_FUNCTION_NOT_PERMITTED, Result), mkEntry(CKR_KEY_NOT_WRAPPABLE, Result), mkEntry(CKR_KEY_UNEXTRACTABLE, Result), - mkEntry(CKR_KEY_PARAMS_INVALID, Result), mkEntry(CKR_MECHANISM_INVALID, Result), mkEntry(CKR_MECHANISM_PARAM_INVALID, Result), mkEntry(CKR_OBJECT_HANDLE_INVALID, Result), diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c index 703845e98..b70a14172 100644 --- a/security/nss/cmd/lib/secutil.c +++ b/security/nss/cmd/lib/secutil.c @@ -494,23 +494,30 @@ SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii, if (ascii) { /* First convert ascii to binary */ SECItem filedata; - char *asc, *body; /* Read in ascii data */ rv = SECU_FileToItem(&filedata, inFile); if (rv != SECSuccess) return rv; - asc = (char *)filedata.data; - if (!asc) { + if (!filedata.data) { fprintf(stderr, "unable to read data from input file\n"); return SECFailure; } + /* need one additional byte for zero terminator */ + rv = SECITEM_ReallocItemV2(NULL, &filedata, filedata.len + 1); + if (rv != SECSuccess) { + PORT_Free(filedata.data); + return rv; + } + char *asc = (char *)filedata.data; + asc[filedata.len - 1] = '\0'; if (warnOnPrivateKeyInAsciiFile && strstr(asc, "PRIVATE KEY")) { fprintf(stderr, "Warning: ignoring private key. Consider to use " "pk12util.\n"); } + char *body; /* check for headers and trailers and remove them */ if ((body = strstr(asc, "-----BEGIN")) != NULL) { char *trailer = NULL; @@ -528,14 +535,7 @@ SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii, return SECFailure; } } else { - /* need one additional byte for zero terminator */ - rv = SECITEM_ReallocItemV2(NULL, &filedata, filedata.len + 1); - if (rv != SECSuccess) { - PORT_Free(filedata.data); - return rv; - } - body = (char *)filedata.data; - body[filedata.len - 1] = '\0'; + body = asc; } /* Convert to binary */ @@ -4159,3 +4159,57 @@ exportKeyingMaterials(PRFileDesc *fd, return SECSuccess; } + +SECStatus +readPSK(const char *arg, SECItem *psk, SECItem *label) +{ + SECStatus rv = SECFailure; + char *str = PORT_Strdup(arg); + if (!str) { + goto cleanup; + } + + char *pskBytes = strtok(str, ":"); + if (!pskBytes) { + goto cleanup; + } + if (PORT_Strncasecmp(pskBytes, "0x", 2) != 0) { + goto cleanup; + } + + psk = SECU_HexString2SECItem(NULL, psk, &pskBytes[2]); + if (!psk || !psk->data || psk->len != strlen(&str[2]) / 2) { + goto cleanup; + } + + SECItem labelItem = { siBuffer, NULL, 0 }; + char *inLabel = strtok(NULL, ":"); + if (inLabel) { + labelItem.data = (unsigned char *)PORT_Strdup(inLabel); + if (!labelItem.data) { + goto cleanup; + } + labelItem.len = strlen(inLabel); + + if (PORT_Strncasecmp(inLabel, "0x", 2) == 0) { + rv = SECU_SECItemHexStringToBinary(&labelItem); + if (rv != SECSuccess) { + SECITEM_FreeItem(&labelItem, PR_FALSE); + goto cleanup; + } + } + rv = SECSuccess; + } else { + PRUint8 defaultLabel[] = { 'C', 'l', 'i', 'e', 'n', 't', '_', + 'i', 'd', 'e', 'n', 't', 'i', 't', 'y' }; + SECItem src = { siBuffer, defaultLabel, sizeof(defaultLabel) }; + rv = SECITEM_CopyItem(NULL, &labelItem, &src); + } + if (rv == SECSuccess) { + *label = labelItem; + } + +cleanup: + PORT_Free(str); + return rv; +} diff --git a/security/nss/cmd/lib/secutil.h b/security/nss/cmd/lib/secutil.h index c6da961e7..0bdfa9508 100644 --- a/security/nss/cmd/lib/secutil.h +++ b/security/nss/cmd/lib/secutil.h @@ -424,6 +424,8 @@ SECStatus exportKeyingMaterials(PRFileDesc *fd, const secuExporter *exporters, unsigned int exporterCount); +SECStatus readPSK(const char *arg, SECItem *psk, SECItem *label); + /* * * Error messaging diff --git a/security/nss/cmd/lowhashtest/lowhashtest.c b/security/nss/cmd/lowhashtest/lowhashtest.c index fcc06a86e..95c23f343 100644 --- a/security/nss/cmd/lowhashtest/lowhashtest.c +++ b/security/nss/cmd/lowhashtest/lowhashtest.c @@ -415,7 +415,7 @@ main(int argc, char **argv) return 1; } - if (argc || !argv[1] || strlen(argv[1]) == 0) { + if (argc < 2 || !argv[1] || strlen(argv[1]) == 0) { rv += testMD5(initCtx); rv += testSHA1(initCtx); rv += testSHA224(initCtx); @@ -428,7 +428,7 @@ main(int argc, char **argv) rv += testSHA1(initCtx); } else if (strcmp(argv[1], "SHA224") == 0) { rv += testSHA224(initCtx); - } else if (strcmp(argv[1], "SHA226") == 0) { + } else if (strcmp(argv[1], "SHA256") == 0) { rv += testSHA256(initCtx); } else if (strcmp(argv[1], "SHA384") == 0) { rv += testSHA384(initCtx); diff --git a/security/nss/cmd/modutil/install-ds.c b/security/nss/cmd/modutil/install-ds.c index 576839f8f..a013d05a3 100644 --- a/security/nss/cmd/modutil/install-ds.c +++ b/security/nss/cmd/modutil/install-ds.c @@ -891,8 +891,6 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this, if (errStr) { tmp = PR_smprintf("%s: %s", Pk11Install_PlatformName_GetString(&_this->name), errStr); - tmp = PR_smprintf("%s: %s", - Pk11Install_PlatformName_GetString(&_this->name), errStr); PR_smprintf_free(errStr); errStr = tmp; goto loser; diff --git a/security/nss/cmd/pk11gcmtest/pk11gcmtest.c b/security/nss/cmd/pk11gcmtest/pk11gcmtest.c index 1b8bff5e4..8dcc0244b 100644 --- a/security/nss/cmd/pk11gcmtest/pk11gcmtest.c +++ b/security/nss/cmd/pk11gcmtest/pk11gcmtest.c @@ -45,7 +45,7 @@ aes_encrypt_buf( SECItem key_item; PK11SlotInfo *slot = NULL; PK11SymKey *symKey = NULL; - CK_GCM_PARAMS gcm_params; + CK_NSS_GCM_PARAMS gcm_params; SECItem param; /* Import key into NSS. */ @@ -102,7 +102,7 @@ aes_decrypt_buf( SECItem key_item; PK11SlotInfo *slot = NULL; PK11SymKey *symKey = NULL; - CK_GCM_PARAMS gcm_params; + CK_NSS_GCM_PARAMS gcm_params; SECItem param; if (inputlen + tagsize > sizeof(concatenated)) { diff --git a/security/nss/cmd/pk11mode/pk11mode.c b/security/nss/cmd/pk11mode/pk11mode.c index 16554536d..851d64f8f 100644 --- a/security/nss/cmd/pk11mode/pk11mode.c +++ b/security/nss/cmd/pk11mode/pk11mode.c @@ -16,7 +16,7 @@ #include <string.h> #include <stdarg.h> -#if defined(XP_UNIX) && !defined(NO_FORK_CHECK) +#if defined(XP_UNIX) && defined(DO_FORK_CHECK) #include <unistd.h> #include <sys/wait.h> #else diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c index 03e39d67b..1584d7ee0 100644 --- a/security/nss/cmd/selfserv/selfserv.c +++ b/security/nss/cmd/selfserv/selfserv.c @@ -138,6 +138,8 @@ static SECItem bigBuf; static int configureDHE = -1; /* -1: don't configure, 0 disable, >=1 enable*/ static int configureReuseECDHE = -1; /* -1: don't configure, 0 refresh, >=1 reuse*/ static int configureWeakDHE = -1; /* -1: don't configure, 0 disable, >=1 enable*/ +SECItem psk = { siBuffer, NULL, 0 }; +SECItem pskLabel = { siBuffer, NULL, 0 }; static PRThread *acceptorThread; @@ -167,7 +169,7 @@ PrintUsageHeader(const char *progName) " [ T <good|revoked|unknown|badsig|corrupted|none|ocsp>] [-A ca]\n" " [-C SSLCacheEntries] [-S dsa_nickname] [-Q]\n" " [-I groups] [-J signatureschemes] [-e ec_nickname]\n" - " -U [0|1] -H [0|1|2] -W [0|1]\n" + " -U [0|1] -H [0|1|2] -W [0|1] [-z externalPsk]\n" "\n", progName); } @@ -241,7 +243,11 @@ PrintParameterUsage() " LABEL[:OUTPUT-LENGTH[:CONTEXT]]\n" " where LABEL and CONTEXT can be either a free-form string or\n" " a hex string if it is preceded by \"0x\"; OUTPUT-LENGTH\n" - " is a decimal integer.\n", + " is a decimal integer.\n" + "-z Configure a TLS 1.3 External PSK with the given hex string for a key.\n" + " To specify a label, use ':' as a delimiter. For example:\n" + " 0xAAAABBBBCCCCDDDD:mylabel. Otherwise, the default label of\n" + " 'Client_identity' will be used.\n", stderr); } @@ -1841,6 +1847,32 @@ handshakeCallback(PRFileDesc *fd, void *client_data) } } +static SECStatus +importPsk(PRFileDesc *model_sock) +{ + SECU_PrintAsHex(stdout, &psk, "Using External PSK", 0); + PK11SlotInfo *slot = NULL; + PK11SymKey *symKey = NULL; + slot = PK11_GetInternalSlot(); + if (!slot) { + errWarn("PK11_GetInternalSlot failed"); + return SECFailure; + } + symKey = PK11_ImportSymKey(slot, CKM_HKDF_KEY_GEN, PK11_OriginUnwrap, + CKA_DERIVE, &psk, NULL); + PK11_FreeSlot(slot); + if (!symKey) { + errWarn("PK11_ImportSymKey failed\n"); + return SECFailure; + } + + SECStatus rv = SSL_AddExternalPsk(model_sock, symKey, + (const PRUint8 *)pskLabel.data, + pskLabel.len, ssl_hash_sha256); + PK11_FreeSymKey(symKey); + return rv; +} + void server_main( PRFileDesc *listen_sock, @@ -2050,6 +2082,13 @@ server_main( } } + if (psk.data) { + rv = importPsk(model_sock); + if (rv != SECSuccess) { + errExit("importPsk failed"); + } + } + if (MakeCertOK) SSL_BadCertHook(model_sock, myBadCertHandler, NULL); @@ -2125,6 +2164,20 @@ haveAChild(int argc, char **argv, PRProcessAttr *attr) return newProcess; } +#ifdef XP_UNIX +void +sigusr1_parent_handler(int sig) +{ + PRProcess *process; + int i; + fprintf(stderr, "SIG_USER: Parent got sig_user, killing children (%d).\n", numChildren); + for (i = 0; i < numChildren; i++) { + process = child[i]; + PR_KillProcess(process); /* it would be nice to kill with a sigusr signal */ + } +} +#endif + void beAGoodParent(int argc, char **argv, int maxProcs, PRFileDesc *listen_sock) { @@ -2134,6 +2187,19 @@ beAGoodParent(int argc, char **argv, int maxProcs, PRFileDesc *listen_sock) PRInt32 exitCode; PRStatus rv; +#ifdef XP_UNIX + struct sigaction act; + + /* set up the signal handler */ + act.sa_handler = sigusr1_parent_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + if (sigaction(SIGUSR1, &act, NULL)) { + fprintf(stderr, "Error installing signal handler.\n"); + exit(1); + } +#endif + rv = PR_SetFDInheritable(listen_sock, PR_TRUE); if (rv != PR_SUCCESS) errExit("PR_SetFDInheritable"); @@ -2264,10 +2330,9 @@ main(int argc, char **argv) /* please keep this list of options in ASCII collating sequence. ** numbers, then capital letters, then lower case, alphabetical. ** XXX: 'B', and 'q' were used in the past but removed - ** in 3.28, please leave some time before resuing those. - ** 'z' was removed in 3.39. */ + ** in 3.28, please leave some time before resuing those. */ optstate = PL_CreateOptState(argc, argv, - "2:A:C:DEGH:I:J:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:x:y"); + "2:A:C:DEGH:I:J:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:x:yz:"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { ++optionsFound; switch (optstate->option) { @@ -2489,6 +2554,16 @@ main(int argc, char **argv) zeroRTT = PR_TRUE; break; + case 'z': + rv = readPSK(optstate->value, &psk, &pskLabel); + if (rv != SECSuccess) { + PL_DestroyOptState(optstate); + fprintf(stderr, "Bad PSK specified.\n"); + Usage(progName); + exit(1); + } + break; + case 'Q': enableALPN = PR_TRUE; break; @@ -2588,7 +2663,8 @@ main(int argc, char **argv) exit(14); } - if (pidFile) { + envString = PR_GetEnvSecure(envVarName); + if (!envString && pidFile) { FILE *tmpfile = fopen(pidFile, "w+"); if (tmpfile) { @@ -2613,13 +2689,6 @@ main(int argc, char **argv) if (!tmp) tmp = PR_GetEnvSecure("TEMP"); - /* Call the NSS initialization routines */ - rv = NSS_Initialize(dir, certPrefix, certPrefix, SECMOD_DB, NSS_INIT_READONLY); - if (rv != SECSuccess) { - fputs("NSS_Init failed.\n", stderr); - exit(8); - } - if (envString) { /* we're one of the children in a multi-process server. */ listen_sock = PR_GetInheritedFD(inheritableSockName); @@ -2642,6 +2711,12 @@ main(int argc, char **argv) if (rv != SECSuccess) errExit("SSL_InheritMPServerSIDCache"); hasSidCache = PR_TRUE; + /* Call the NSS initialization routines */ + rv = NSS_Initialize(dir, certPrefix, certPrefix, SECMOD_DB, NSS_INIT_READONLY); + if (rv != SECSuccess) { + fputs("NSS_Init failed.\n", stderr); + exit(8); + } } else if (maxProcs > 1) { /* we're going to be the parent in a multi-process server. */ listen_sock = getBoundListenSocket(port); @@ -2652,6 +2727,12 @@ main(int argc, char **argv) beAGoodParent(argc, argv, maxProcs, listen_sock); exit(99); /* should never get here */ } else { + /* Call the NSS initialization routines */ + rv = NSS_Initialize(dir, certPrefix, certPrefix, SECMOD_DB, NSS_INIT_READONLY); + if (rv != SECSuccess) { + fputs("NSS_Init failed.\n", stderr); + exit(8); + } /* we're an ordinary single process server. */ listen_sock = getBoundListenSocket(port); prStatus = PR_SetFDInheritable(listen_sock, PR_FALSE); @@ -2838,6 +2919,8 @@ cleanup: if (antiReplay) { SSL_ReleaseAntiReplayContext(antiReplay); } + SECITEM_ZfreeItem(&psk, PR_FALSE); + SECITEM_ZfreeItem(&pskLabel, PR_FALSE); if (NSS_Shutdown() != SECSuccess) { SECU_PrintError(progName, "NSS_Shutdown"); if (loggerThread) { diff --git a/security/nss/cmd/shlibsign/shlibsign.c b/security/nss/cmd/shlibsign/shlibsign.c index b0a7512ab..ad8f3b84e 100644 --- a/security/nss/cmd/shlibsign/shlibsign.c +++ b/security/nss/cmd/shlibsign/shlibsign.c @@ -483,8 +483,8 @@ static const tuple_str errStrings[] = { { CKR_MUTEX_NOT_LOCKED, "CKR_MUTEX_NOT_LOCKED " }, { CKR_FUNCTION_REJECTED, "CKR_FUNCTION_REJECTED " }, { CKR_VENDOR_DEFINED, "CKR_VENDOR_DEFINED " }, - { 0xCE534351, "CKR_NETSCAPE_CERTDB_FAILED " }, - { 0xCE534352, "CKR_NETSCAPE_KEYDB_FAILED " } + { 0xCE534351, "CKR_NSS_CERTDB_FAILED " }, + { 0xCE534352, "CKR_NSS_KEYDB_FAILED " } }; diff --git a/security/nss/cmd/signtool/manifest.mn b/security/nss/cmd/signtool/manifest.mn index 40be262db..d1b9d48c0 100644 --- a/security/nss/cmd/signtool/manifest.mn +++ b/security/nss/cmd/signtool/manifest.mn @@ -6,6 +6,10 @@ CORE_DEPTH = ../.. MODULE = nss +ifdef ZLIB_INCLUDE_DIR +INCLUDES += -I$(ZLIB_INCLUDE_DIR) +endif + EXPORTS = CSRCS = signtool.c \ diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c index 6fa154106..c37df118e 100644 --- a/security/nss/cmd/tstclnt/tstclnt.c +++ b/security/nss/cmd/tstclnt/tstclnt.c @@ -109,6 +109,8 @@ SSLNamedGroup *enabledGroups = NULL; unsigned int enabledGroupsCount = 0; const SSLSignatureScheme *enabledSigSchemes = NULL; unsigned int enabledSigSchemeCount = 0; +SECItem psk = { siBuffer, NULL, 0 }; +SECItem pskLabel = { siBuffer, NULL, 0 }; const char * signatureSchemeName(SSLSignatureScheme scheme) @@ -229,7 +231,7 @@ PrintUsageHeader() " [-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n" " [-I groups] [-J signatureschemes]\n" " [-A requestfile] [-L totalconnections] [-P {client,server}]\n" - " [-N encryptedSniKeys] [-Q]\n" + " [-N encryptedSniKeys] [-Q] [-z externalPsk]\n" "\n", progName); } @@ -325,6 +327,12 @@ PrintParameterUsage() "%-20s a hex string if it is preceded by \"0x\"; OUTPUT-LENGTH\n" "%-20s is a decimal integer.\n", "-x", "", "", "", "", ""); + fprintf(stderr, + "%-20s Configure a TLS 1.3 External PSK with the given hex string for a key\n" + "%-20s To specify a label, use ':' as a delimiter. For example\n" + "%-20s 0xAAAABBBBCCCCDDDD:mylabel. Otherwise, the default label of\n" + "%-20s 'Client_identity' will be used.\n", + "-z externalPsk", "", "", ""); } static void @@ -1230,6 +1238,31 @@ connectToServer(PRFileDesc *s, PRPollDesc *pollset) return SECSuccess; } +static SECStatus +importPsk(PRFileDesc *s) +{ + SECU_PrintAsHex(stdout, &psk, "Using External PSK", 0); + PK11SlotInfo *slot = NULL; + PK11SymKey *symKey = NULL; + slot = PK11_GetInternalSlot(); + if (!slot) { + SECU_PrintError(progName, "PK11_GetInternalSlot failed"); + return SECFailure; + } + symKey = PK11_ImportSymKey(slot, CKM_HKDF_KEY_GEN, PK11_OriginUnwrap, + CKA_DERIVE, &psk, NULL); + PK11_FreeSlot(slot); + if (!symKey) { + SECU_PrintError(progName, "PK11_ImportSymKey failed"); + return SECFailure; + } + + SECStatus rv = SSL_AddExternalPsk(s, symKey, (const PRUint8 *)pskLabel.data, + pskLabel.len, ssl_hash_sha256); + PK11_FreeSymKey(symKey); + return rv; +} + static int run() { @@ -1498,6 +1531,15 @@ run() } } + if (psk.data) { + rv = importPsk(s); + if (rv != SECSuccess) { + SECU_PrintError(progName, "importPsk failed"); + error = 1; + goto done; + } + } + serverCertAuth.dbHandle = CERT_GetDefaultCertDB(); SSL_AuthCertificateHook(s, ownAuthCertificate, &serverCertAuth); @@ -1752,11 +1794,8 @@ main(int argc, char **argv) } } - /* Note: 'z' was removed in 3.39 - * Please leave some time before reusing these. - */ optstate = PL_CreateOptState(argc, argv, - "46A:BCDEFGHI:J:KL:M:N:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:x:"); + "46A:BCDEFGHI:J:KL:M:N:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:x:z:"); while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': @@ -2015,6 +2054,15 @@ main(int argc, char **argv) Usage(); } break; + + case 'z': + rv = readPSK(optstate->value, &psk, &pskLabel); + if (rv != SECSuccess) { + PL_DestroyOptState(optstate); + fprintf(stderr, "Bad PSK specified.\n"); + Usage(); + } + break; } } PL_DestroyOptState(optstate); @@ -2210,6 +2258,8 @@ done: PORT_Free(host); PORT_Free(zeroRttData); PORT_Free(encryptedSNIKeys); + SECITEM_ZfreeItem(&psk, PR_FALSE); + SECITEM_ZfreeItem(&pskLabel, PR_FALSE); if (enabledGroups) { PORT_Free(enabledGroups); |