"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "nss/cmd/selfserv/selfserv.c" between
nss-3.61.tar.gz and nss-3.62.tar.gz

About: NSS is a set of libraries, APIs, utilities, and documentation designed to support cross-platform development of security-enabled client and server applications. It provides a complete implementation of the crypto libraries used by Mozilla and other companies.

selfserv.c  (nss-3.61):selfserv.c  (nss-3.62)
skipping to change at line 45 skipping to change at line 45
#include "plgetopt.h" #include "plgetopt.h"
#include "pk11func.h" #include "pk11func.h"
#include "secitem.h" #include "secitem.h"
#include "nss.h" #include "nss.h"
#include "ssl.h" #include "ssl.h"
#include "sslproto.h" #include "sslproto.h"
#include "sslexp.h" #include "sslexp.h"
#include "cert.h" #include "cert.h"
#include "certt.h" #include "certt.h"
#include "ocsp.h" #include "ocsp.h"
#include "nssb64.h"
#ifndef PORT_Sprintf #ifndef PORT_Sprintf
#define PORT_Sprintf sprintf #define PORT_Sprintf sprintf
#endif #endif
#ifndef PORT_Strstr #ifndef PORT_Strstr
#define PORT_Strstr strstr #define PORT_Strstr strstr
#endif #endif
#ifndef PORT_Malloc #ifndef PORT_Malloc
skipping to change at line 143 skipping to change at line 144
static PRBool noDelay; static PRBool noDelay;
static int requestCert; static int requestCert;
static int verbose; static int verbose;
static SECItem bigBuf; static SECItem bigBuf;
static int configureDHE = -1; /* -1: don't configure, 0 disable, >=1 enab le*/ static int configureDHE = -1; /* -1: don't configure, 0 disable, >=1 enab le*/
static int configureReuseECDHE = -1; /* -1: don't configure, 0 refresh, >=1 reus e*/ static int configureReuseECDHE = -1; /* -1: don't configure, 0 refresh, >=1 reus e*/
static int configureWeakDHE = -1; /* -1: don't configure, 0 disable, >=1 enab le*/ static int configureWeakDHE = -1; /* -1: don't configure, 0 disable, >=1 enab le*/
SECItem psk = { siBuffer, NULL, 0 }; SECItem psk = { siBuffer, NULL, 0 };
SECItem pskLabel = { siBuffer, NULL, 0 }; SECItem pskLabel = { siBuffer, NULL, 0 };
char *echParamsStr = NULL;
static PRThread *acceptorThread; static PRThread *acceptorThread;
static PRLogModuleInfo *lm; static PRLogModuleInfo *lm;
#define PRINTF \ #define PRINTF \
if (verbose) \ if (verbose) \
printf printf
#define FPRINTF \ #define FPRINTF \
if (verbose) \ if (verbose) \
skipping to change at line 250 skipping to change at line 252
" (for TLS 1.3; only has an effect with 3 or more -r options)\n" " (for TLS 1.3; only has an effect with 3 or more -r options)\n"
"-x Export and print keying material after successful handshake\n" "-x Export and print keying material after successful handshake\n"
" The argument is a comma separated list of exporters in the form:\n" " The argument is a comma separated list of exporters in the form:\n"
" LABEL[:OUTPUT-LENGTH[:CONTEXT]]\n" " LABEL[:OUTPUT-LENGTH[:CONTEXT]]\n"
" where LABEL and CONTEXT can be either a free-form string or\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" " 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" "-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" " To specify a label, use ':' as a delimiter. For example:\n"
" 0xAAAABBBBCCCCDDDD:mylabel. Otherwise, the default label of\n" " 0xAAAABBBBCCCCDDDD:mylabel. Otherwise, the default label of\n"
" 'Client_identity' will be used.\n", " 'Client_identity' will be used.\n"
"-X Configure the server for ECH via the given <ECHParams>. ECHParams\n
"
" are expected in one of two formats:\n"
" 1. A string containing the ECH public name prefixed by the substr
ing\n"
" \"publicname:\". For example, \"publicname:example.com\". In t
his mode,\n"
" an ephemeral ECH keypair is generated and ECHConfigs are print
ed to stdout.\n"
" 2. As a Base64 tuple of <ECHRawPrivateKey> || <ECHConfigs>. In th
is mode, the\n"
" raw private key is used to bootstrap the HPKE context.\n",
stderr); stderr);
} }
static void static void
Usage(const char *progName) Usage(const char *progName)
{ {
PrintUsageHeader(progName); PrintUsageHeader(progName);
PrintParameterUsage(); PrintParameterUsage();
} }
skipping to change at line 1876 skipping to change at line 1885
return SECFailure; return SECFailure;
} }
SECStatus rv = SSL_AddExternalPsk(model_sock, symKey, SECStatus rv = SSL_AddExternalPsk(model_sock, symKey,
(const PRUint8 *)pskLabel.data, (const PRUint8 *)pskLabel.data,
pskLabel.len, ssl_hash_sha256); pskLabel.len, ssl_hash_sha256);
PK11_FreeSymKey(symKey); PK11_FreeSymKey(symKey);
return rv; return rv;
} }
static SECStatus
configureEchWithPublicName(PRFileDesc *model_sock, const char *public_name)
{
SECStatus rv;
#define OID_LEN 65
unsigned char paramBuf[OID_LEN];
SECItem ecParams = { siBuffer, paramBuf, sizeof(paramBuf) };
SECKEYPublicKey *pubKey = NULL;
SECKEYPrivateKey *privKey = NULL;
SECOidData *oidData;
char *echConfigBase64 = NULL;
PRUint8 configBuf[1000];
unsigned int len = 0;
unsigned int echCipherSuite = ((unsigned int)HpkeKdfHkdfSha256 << 16) |
HpkeAeadChaCha20Poly1305;
PK11SlotInfo *slot = PK11_GetInternalKeySlot();
if (!slot) {
errWarn("PK11_GetInternalKeySlot failed");
return SECFailure;
}
oidData = SECOID_FindOIDByTag(SEC_OID_CURVE25519);
if (oidData && (2 + oidData->oid.len) < sizeof(paramBuf)) {
ecParams.data[0] = SEC_ASN1_OBJECT_ID;
ecParams.data[1] = oidData->oid.len;
memcpy(ecParams.data + 2, oidData->oid.data, oidData->oid.len);
ecParams.len = oidData->oid.len + 2;
} else {
errWarn("SECOID_FindOIDByTag failed");
goto loser;
}
privKey = PK11_GenerateKeyPair(slot, CKM_EC_KEY_PAIR_GEN, &ecParams,
&pubKey, PR_FALSE, PR_FALSE, NULL);
if (!privKey || !pubKey) {
errWarn("Failed to generate ECH keypair");
goto loser;
}
rv = SSL_EncodeEchConfig(echParamsStr, &echCipherSuite, 1,
HpkeDhKemX25519Sha256, pubKey, 50,
configBuf, &len, sizeof(configBuf));
if (rv != SECSuccess) {
errWarn("SSL_EncodeEchConfig failed");
goto loser;
}
rv = SSL_SetServerEchConfigs(model_sock, pubKey, privKey, configBuf, len);
if (rv != SECSuccess) {
errWarn("SSL_SetServerEchConfigs failed");
goto loser;
}
SECItem echConfigItem = { siBuffer, configBuf, len };
echConfigBase64 = NSSBase64_EncodeItem(NULL, NULL, 0, &echConfigItem);
if (!echConfigBase64) {
errWarn("NSSBase64_EncodeItem failed");
goto loser;
}
// Remove the newline characters that NSSBase64_EncodeItem unhelpfully inser
ts.
char *newline = strstr(echConfigBase64, "\r\n");
if (newline) {
memmove(newline, newline + 2, strlen(newline + 2) + 1);
}
printf("%s\n", echConfigBase64);
PORT_Free(echConfigBase64);
SECKEY_DestroyPrivateKey(privKey);
SECKEY_DestroyPublicKey(pubKey);
PK11_FreeSlot(slot);
return SECSuccess;
loser:
PORT_Free(echConfigBase64);
SECKEY_DestroyPrivateKey(privKey);
SECKEY_DestroyPublicKey(pubKey);
PK11_FreeSlot(slot);
return SECFailure;
}
static SECStatus
configureEchWithData(PRFileDesc *model_sock)
{
/* The input should be a Base64-encoded ECHKey struct:
* struct {
* opaque pkcs8_ech_keypair<0..2^16-1>;
* ECHConfigs configs<0..2^16>; // draft-ietf-tls-esni-09
* } ECHKey;
*
* This is not a standardized format, rather it's designed for
* interoperability with https://github.com/xvzcf/tls-interop-runner.
* It is the user's responsibility to ensure that the PKCS8 keypair
* corresponds to the public key embedded in the ECHConfigs.
*/
#define REMAINING_BYTES(rdr, buf) \
buf->len - (rdr - buf->data)
SECStatus rv;
size_t len;
unsigned char *reader;
PK11SlotInfo *slot = NULL;
SECItem *decoded = NULL;
SECKEYPublicKey *pk = NULL;
SECKEYPrivateKey *sk = NULL;
SECItem pkcs8Key = { siBuffer, NULL, 0 };
decoded = NSSBase64_DecodeBuffer(NULL, NULL, echParamsStr, PORT_Strlen(echPa
ramsStr));
if (!decoded || decoded->len < 2) {
errWarn("Couldn't decode ECHParams");
goto loser;
};
reader = decoded->data;
len = (*(reader++) << 8);
len |= *(reader++);
if (len > (REMAINING_BYTES(reader, decoded) - 2)) {
errWarn("Bad ECHParams encoding");
goto loser;
}
pkcs8Key.data = reader;
pkcs8Key.len = len;
reader += len;
/* Convert the key bytes to key handles */
slot = PK11_GetInternalKeySlot();
rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot, &pkcs8Key, NULL, NULL, PR_FALSE, PR_FALSE, KU_ALL, &sk, NULL);
if (rv != SECSuccess || !sk) {
errWarn("ECH key import failed");
goto loser;
}
pk = SECKEY_ConvertToPublicKey(sk);
if (!pk) {
errWarn("ECH key conversion failed");
goto loser;
}
/* Remainder is the ECHConfigs. */
rv = SSL_SetServerEchConfigs(model_sock, pk, sk, reader,
REMAINING_BYTES(reader, decoded));
if (rv != SECSuccess) {
errWarn("SSL_SetServerEchConfigs failed");
goto loser;
}
PK11_FreeSlot(slot);
SECKEY_DestroyPrivateKey(sk);
SECKEY_DestroyPublicKey(pk);
SECITEM_FreeItem(decoded, PR_TRUE);
return SECSuccess;
loser:
if (slot) {
PK11_FreeSlot(slot);
}
SECKEY_DestroyPrivateKey(sk);
SECKEY_DestroyPublicKey(pk);
SECITEM_FreeItem(decoded, PR_TRUE);
return SECFailure;
}
static SECStatus
configureEch(PRFileDesc *model_sock)
{
if (!PORT_Strncmp(echParamsStr, "publicname:", PORT_Strlen("publicname:")))
{
return configureEchWithPublicName(model_sock,
&echParamsStr[PORT_Strlen("publicname:
")]);
}
return configureEchWithData(model_sock);
}
void void
server_main( server_main(
PRFileDesc *listen_sock, PRFileDesc *listen_sock,
SECKEYPrivateKey **privKey, SECKEYPrivateKey **privKey,
CERTCertificate **cert, CERTCertificate **cert,
const char *expectedHostNameVal) const char *expectedHostNameVal)
{ {
int i; int i;
PRFileDesc *model_sock = NULL; PRFileDesc *model_sock = NULL;
int rv; int rv;
skipping to change at line 2092 skipping to change at line 2273
} }
} }
if (psk.data) { if (psk.data) {
rv = importPsk(model_sock); rv = importPsk(model_sock);
if (rv != SECSuccess) { if (rv != SECSuccess) {
errExit("importPsk failed"); errExit("importPsk failed");
} }
} }
if (echParamsStr) {
rv = configureEch(model_sock);
if (rv != SECSuccess) {
errExit("configureEch failed");
}
}
if (MakeCertOK) if (MakeCertOK)
SSL_BadCertHook(model_sock, myBadCertHandler, NULL); SSL_BadCertHook(model_sock, myBadCertHandler, NULL);
/* end of ssl configuration. */ /* end of ssl configuration. */
/* Now, do the accepting, here in the main thread. */ /* Now, do the accepting, here in the main thread. */
rv = do_accepts(listen_sock, model_sock); rv = do_accepts(listen_sock, model_sock);
terminateWorkerThreads(); terminateWorkerThreads();
skipping to change at line 2335 skipping to change at line 2523
progName = progName ? progName + 1 : tmp; progName = progName ? progName + 1 : tmp;
PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions); SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
/* please keep this list of options in ASCII collating sequence. /* please keep this list of options in ASCII collating sequence.
** numbers, then capital letters, then lower case, alphabetical. ** numbers, then capital letters, then lower case, alphabetical.
** XXX: 'B', and 'q' were used in the past but removed ** XXX: 'B', and 'q' were used in the past but removed
** in 3.28, please leave some time before resuing those. */ ** in 3.28, please leave some time before resuing those. */
optstate = PL_CreateOptState(argc, argv, 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:yz:"); "2:A:C:DEGH:I:J:L:M:NP:QRS:T:U:V:W:X:YZa:bc:d:e :f:g:hi:jk:lmn:op:rst:uvw:x:yz:");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
++optionsFound; ++optionsFound;
switch (optstate->option) { switch (optstate->option) {
case '2': case '2':
fileName = optstate->value; fileName = optstate->value;
break; break;
case 'A': case 'A':
ocspStaplingCA = PORT_Strdup(optstate->value); ocspStaplingCA = PORT_Strdup(optstate->value);
break; break;
skipping to change at line 2602 skipping to change at line 2790
rv = parseExporters(optstate->value, rv = parseExporters(optstate->value,
&enabledExporters, &enabledExporterCount); &enabledExporters, &enabledExporterCount);
if (rv != SECSuccess) { if (rv != SECSuccess) {
PL_DestroyOptState(optstate); PL_DestroyOptState(optstate);
fprintf(stderr, "Bad exporter specified.\n"); fprintf(stderr, "Bad exporter specified.\n");
fprintf(stderr, "Run '%s -h' for usage information.\n", prog Name); fprintf(stderr, "Run '%s -h' for usage information.\n", prog Name);
exit(5); exit(5);
} }
break; break;
case 'X':
echParamsStr = PORT_Strdup(optstate->value);
if (echParamsStr == NULL) {
PL_DestroyOptState(optstate);
fprintf(stderr, "echParamsStr copy failed.\n");
exit(5);
}
break;
default: default:
case '?': case '?':
fprintf(stderr, "Unrecognized or bad option specified.\n"); fprintf(stderr, "Unrecognized or bad option specified: %c\n", op tstate->option);
fprintf(stderr, "Run '%s -h' for usage information.\n", progName ); fprintf(stderr, "Run '%s -h' for usage information.\n", progName );
exit(4); exit(4);
break; break;
} }
} }
PL_DestroyOptState(optstate); PL_DestroyOptState(optstate);
if (status == PL_OPT_BAD) { if (status == PL_OPT_BAD) {
fprintf(stderr, "Unrecognized or bad option specified.\n"); fprintf(stderr, "Unrecognized or bad option specified.\n");
fprintf(stderr, "Run '%s -h' for usage information.\n", progName); fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
exit(5); exit(5);
skipping to change at line 2924 skipping to change at line 3120
PORT_FreeArena(certStatusArena, PR_FALSE); PORT_FreeArena(certStatusArena, PR_FALSE);
} }
if (enabledGroups) { if (enabledGroups) {
PORT_Free(enabledGroups); PORT_Free(enabledGroups);
} }
if (antiReplay) { if (antiReplay) {
SSL_ReleaseAntiReplayContext(antiReplay); SSL_ReleaseAntiReplayContext(antiReplay);
} }
SECITEM_ZfreeItem(&psk, PR_FALSE); SECITEM_ZfreeItem(&psk, PR_FALSE);
SECITEM_ZfreeItem(&pskLabel, PR_FALSE); SECITEM_ZfreeItem(&pskLabel, PR_FALSE);
PORT_Free(echParamsStr);
if (NSS_Shutdown() != SECSuccess) { if (NSS_Shutdown() != SECSuccess) {
SECU_PrintError(progName, "NSS_Shutdown"); SECU_PrintError(progName, "NSS_Shutdown");
if (loggerThread) { if (loggerThread) {
PR_JoinThread(loggerThread); PR_JoinThread(loggerThread);
} }
PR_Cleanup(); PR_Cleanup();
exit(1); exit(1);
} }
PR_Cleanup(); PR_Cleanup();
printf("selfserv: normal termination\n"); printf("selfserv: normal termination\n");
 End of changes. 9 change blocks. 
3 lines changed or deleted 209 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)