summaryrefslogtreecommitdiffstats
path: root/security/nss/cmd/selfserv/selfserv.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/cmd/selfserv/selfserv.c')
-rw-r--r--security/nss/cmd/selfserv/selfserv.c109
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) {