189
190
"-D means disable Nagle delays in TCP\n"
190
191
"-E means disable export ciphersuites and SSL step down key gen\n"
191
192
"-R means disable detection of rollback from TLS to SSL3\n"
193
"-a configure server for SNI.\n"
194
"-k expected name negotiated on server sockets"
192
195
"-b means try binding to the port and exit\n"
193
196
"-m means test the model-socket feature of SSL_ImportFD.\n"
194
197
"-r flag is interepreted as follows:\n"
200
203
"-u means enable Session Ticket extension for TLS.\n"
201
204
"-v means verbose output\n"
202
205
"-x means use export policy.\n"
206
"-z means enable compression.\n"
203
207
"-L seconds means log statistics every 'seconds' seconds (default=30).\n"
204
208
"-M maxProcs tells how many processes to run in a multi-process server\n"
205
209
"-N means do NOT use the server session cache. Incompatible with -M.\n"
387
391
suite.effectiveKeyBits, suite.symCipherName,
388
392
suite.macBits, suite.macAlgorithmName);
390
"selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n",
394
"selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n"
395
" Compression: %s\n",
391
396
channel.authKeyBits, suite.authAlgorithmName,
392
channel.keaKeyBits, suite.keaTypeName);
397
channel.keaKeyBits, suite.keaTypeName,
398
channel.compressionMethodName);
402
SECItem *hostInfo = SSL_GetNegotiatedHostInfo(fd);
404
char namePref[] = "selfserv: Negotiated server name: ";
406
fprintf(stderr, "%s", namePref);
407
fwrite(hostInfo->data, hostInfo->len, 1, stderr);
408
SECITEM_FreeItem(hostInfo, PR_TRUE);
410
fprintf(stderr, "\n");
396
414
cert = SSL_PeerCertificate(fd);
426
444
return (MakeCertOK ? SECSuccess : SECFailure);
447
#define MAX_VIRT_SERVER_NAME_ARRAY_INDEX 10
449
/* Simple SNI socket config function that does not use SSL_ReconfigFD.
450
* Only uses one server name but verifies that the names match. */
452
mySSLSNISocketConfig(PRFileDesc *fd, const SECItem *sniNameArr,
453
PRUint32 sniNameArrSize, void *arg)
456
const SECItem *current = sniNameArr;
457
const char **nameArr = (const char**)arg;
458
const secuPWData *pwdata;
459
CERTCertificate * cert = NULL;
460
SECKEYPrivateKey * privKey = NULL;
462
PORT_Assert(fd && sniNameArr);
463
if (!fd || !sniNameArr) {
464
return SSL_SNI_SEND_ALERT;
467
pwdata = SSL_RevealPinArg(fd);
469
for (;current && i < sniNameArrSize;i++) {
471
for (;j < MAX_VIRT_SERVER_NAME_ARRAY_INDEX && nameArr[j];j++) {
472
if (!PORT_Strncmp(nameArr[j],
473
(const char *)current[i].data,
475
PORT_Strlen(nameArr[j]) == current[i].len) {
476
const char *nickName = nameArr[j];
481
/* if pwdata is NULL, then we would not get the key and
482
* return an error status. */
483
cert = PK11_FindCertFromNickname(nickName, &pwdata);
485
goto loser; /* Send alert */
487
privKey = PK11_FindKeyByAnyCert(cert, &pwdata);
488
if (privKey == NULL) {
489
goto loser; /* Send alert */
491
if (SSL_ConfigSecureServer(fd, cert, privKey,
492
kt_rsa) != SECSuccess) {
493
goto loser; /* Send alert */
495
SECKEY_DestroyPrivateKey(privKey);
496
CERT_DestroyCertificate(cert);
503
SECKEY_DestroyPrivateKey(privKey);
506
CERT_DestroyCertificate(cert);
508
return SSL_SNI_SEND_ALERT;
429
512
/**************************************************************************
430
513
** Begin thread management routines and data.
431
514
**************************************************************************/
717
800
PRBool disableLocking = PR_FALSE;
718
801
PRBool testbypass = PR_FALSE;
719
802
PRBool enableSessionTickets = PR_FALSE;
803
PRBool enableCompression = PR_FALSE;
804
PRBool failedToNegotiateName = PR_FALSE;
805
static char *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX];
721
807
static const char stopCmd[] = { "GET /stop " };
722
808
static const char getCmd[] = { "GET " };
1610
handshakeCallback(PRFileDesc *fd, void *client_data)
1612
const char *handshakeName = (const char *)client_data;
1613
if (handshakeName && !failedToNegotiateName) {
1614
SECItem *hostInfo = SSL_GetNegotiatedHostInfo(fd);
1615
if (!hostInfo || PORT_Strncmp(handshakeName, (char*)hostInfo->data,
1617
failedToNegotiateName = PR_TRUE;
1525
1624
PRFileDesc * listen_sock,
1526
1625
int requestCert,
1527
1626
SECKEYPrivateKey ** privKey,
1528
CERTCertificate ** cert)
1627
CERTCertificate ** cert,
1628
const char *expectedHostNameVal)
1530
1630
PRFileDesc *model_sock = NULL;
1702
if (enableCompression) {
1703
rv = SSL_OptionSet(model_sock, SSL_ENABLE_DEFLATE, PR_TRUE);
1704
if (rv != SECSuccess) {
1705
errExit("error enabling compression ");
1709
rv = SSL_SNISocketConfigHook(model_sock, mySSLSNISocketConfig,
1710
(void*)&virtServerNameArray);
1711
if (rv != SECSuccess) {
1712
errExit("error enabling SNI extension ");
1602
1715
for (kea = kt_rsa; kea < kt_kea_size; kea++) {
1603
1716
if (cert[kea] != NULL) {
1604
1717
secStatus = SSL_ConfigSecureServer(model_sock,
1631
1744
errExit("SSL_CipherPrefSetDefault:SSL_RSA_WITH_NULL_MD5");
1747
if (expectedHostNameVal) {
1748
SSL_HandshakeCallback(model_sock, handshakeCallback,
1749
(void*)expectedHostNameVal);
1635
1752
if (requestCert) {
1636
1753
SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate,
1818
1935
SSL3Statistics *ssl3stats;
1820
1937
secuPWData pwdata = { PW_NONE, 0 };
1938
int virtServerNameIndex = 1;
1939
char *expectedHostNameVal = NULL;
1822
1941
tmp = strrchr(argv[0], '/');
1823
1942
tmp = tmp ? tmp + 1 : argv[0];
1824
1943
progName = strrchr(tmp, '\\');
1830
1949
** numbers, then capital letters, then lower case, alphabetical.
1832
1951
optstate = PL_CreateOptState(argc, argv,
1833
"2:3BC:DEL:M:NP:RSTbc:d:e:f:g:hi:jlmn:op:qrst:uvw:xy");
1952
"2:3BC:DEL:M:NP:RSTa:bc:d:e:f:g:hi:jk:lmn:op:qrst:uvw:xyz");
1834
1953
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
1835
1954
++optionsFound;
1836
1955
switch(optstate->option) {
1870
1989
case 'T': disableTLS = PR_TRUE; break;
1991
case 'a': if (virtServerNameIndex >= MAX_VIRT_SERVER_NAME_ARRAY_INDEX) {
1994
virtServerNameArray[virtServerNameIndex++] =
1995
PORT_Strdup(optstate->value); break;
1872
1997
case 'b': bindOnly = PR_TRUE; break;
1874
1999
case 'c': cipherString = PORT_Strdup(optstate->value); break;
1898
2023
loggingLayer = PR_TRUE;
2026
case 'k': expectedHostNameVal = PORT_Strdup(optstate->value);
1901
2029
case 'l': useLocalThreads = PR_TRUE; break;
1903
2031
case 'm': useModelSocket = PR_TRUE; break;
1905
case 'n': nickName = PORT_Strdup(optstate->value); break;
2033
case 'n': nickName = PORT_Strdup(optstate->value);
2034
virtServerNameArray[0] = PORT_Strdup(optstate->value);
1907
2037
case 'P': certPrefix = PORT_Strdup(optstate->value); break;
2230
2362
if (rv == SECSuccess) {
2231
server_main(listen_sock, requestCert, privKey, cert);
2363
server_main(listen_sock, requestCert, privKey, cert,
2364
expectedHostNameVal);
2234
2367
VLOG(("selfserv: server_thread: exiting"));
2251
2388
SECKEY_DestroyPrivateKey(privKey[i]);
2391
for (i = 0;virtServerNameArray[i];i++) {
2392
PORT_Free(virtServerNameArray[i]);
2256
2396
if (debugCache) {
2257
2397
nss_DumpCertificateCacheInfo();
2260
2399
if (nickName) {
2261
2400
PORT_Free(nickName);
2402
if (expectedHostNameVal) {
2403
PORT_Free(expectedHostNameVal);
2264
2406
PORT_Free(passwd);