diff options
Diffstat (limited to 'security/nss/cmd/selfserv/selfserv.c')
-rw-r--r-- | security/nss/cmd/selfserv/selfserv.c | 109 |
1 files changed, 96 insertions, 13 deletions
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) { |