cherry-picked mozilla NSS upstream changes (to rev 5fe63c0b, sha512.c changes are refined for VC6):
bug1182667(other parts), bug1117022, bug1190248, bug1192020, bug1185033, bug1199349, bug1199467, bug1199494
This commit is contained in:
parent
b1bbd767b3
commit
430790c1b1
|
@ -3552,7 +3552,7 @@ int main(int argc, char **argv)
|
|||
unsigned int keySize = 1024;
|
||||
unsigned long exponent = 65537;
|
||||
int rounds = 1;
|
||||
int ret;
|
||||
int ret = -1;
|
||||
|
||||
if (bltest.options[opt_KeySize].activated) {
|
||||
keySize = PORT_Atoi(bltest.options[opt_KeySize].arg);
|
||||
|
|
|
@ -508,8 +508,8 @@ get_serial_number(Pair *data)
|
|||
if (find_field_bool(data, "serial-auto", PR_TRUE)) {
|
||||
serialFile = fopen(filename, "r");
|
||||
if (serialFile != NULL) {
|
||||
fread(&serial, sizeof(int), 1, serialFile);
|
||||
if (ferror(serialFile) != 0) {
|
||||
size_t nread = fread(&serial, sizeof(int), 1, serialFile);
|
||||
if (ferror(serialFile) != 0 || nread != 1) {
|
||||
error_out("Error: Unable to read serial number file");
|
||||
}
|
||||
if (serial == -1) {
|
||||
|
|
|
@ -74,7 +74,9 @@ char *SEC_GetPassword(FILE *input, FILE *output, char *prompt,
|
|||
echoOff(infd);
|
||||
}
|
||||
|
||||
QUIET_FGETS ( phrase, sizeof(phrase), input);
|
||||
if (QUIET_FGETS(phrase, sizeof(phrase), input) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (isTTY) {
|
||||
fprintf(output, "\n");
|
||||
|
@ -87,7 +89,7 @@ char *SEC_GetPassword(FILE *input, FILE *output, char *prompt,
|
|||
/* Validate password */
|
||||
if (!(*ok)(phrase)) {
|
||||
/* Not weird enough */
|
||||
if (!isTTY) return 0;
|
||||
if (!isTTY) return NULL;
|
||||
fprintf(output, "Password must be at least 8 characters long with one or more\n");
|
||||
fprintf(output, "non-alphabetic characters\n");
|
||||
continue;
|
||||
|
|
|
@ -65,7 +65,7 @@ static const char inheritableSockName[] = { "SELFSERV_LISTEN_SOCKET" };
|
|||
#define MAX_BULK_TEST 1048576 /* 1 MB */
|
||||
static PRBool testBulk;
|
||||
static PRUint32 testBulkSize = DEFAULT_BULK_TEST;
|
||||
static PRUint32 testBulkTotal;
|
||||
static PRInt32 testBulkTotal;
|
||||
static char* testBulkBuf;
|
||||
static PRDescIdentity log_layer_id = PR_INVALID_IO_LAYER;
|
||||
static PRFileDesc *loggingFD;
|
||||
|
@ -74,10 +74,10 @@ static PRIOMethods loggingMethods;
|
|||
static PRBool logStats;
|
||||
static PRBool loggingLayer;
|
||||
static int logPeriod = 30;
|
||||
static PRUint32 loggerOps;
|
||||
static PRUint32 loggerBytes;
|
||||
static PRUint32 loggerBytesTCP;
|
||||
static PRUint32 bulkSentChunks;
|
||||
static PRInt32 loggerOps;
|
||||
static PRInt32 loggerBytes;
|
||||
static PRInt32 loggerBytesTCP;
|
||||
static PRInt32 bulkSentChunks;
|
||||
static enum ocspStaplingModeEnum {
|
||||
osm_disabled, /* server doesn't support stapling */
|
||||
osm_good, /* supply a signed good status */
|
||||
|
@ -428,10 +428,11 @@ printSecurityInfo(PRFileDesc *fd)
|
|||
suite.macBits, suite.macAlgorithmName);
|
||||
FPRINTF(stderr,
|
||||
"selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n"
|
||||
" Compression: %s\n",
|
||||
" Compression: %s, Extended Master Secret: %s\n",
|
||||
channel.authKeyBits, suite.authAlgorithmName,
|
||||
channel.keaKeyBits, suite.keaTypeName,
|
||||
channel.compressionMethodName);
|
||||
channel.compressionMethodName,
|
||||
channel.extendedMasterSecretUsed ? "Yes": "No");
|
||||
}
|
||||
}
|
||||
if (verbose) {
|
||||
|
@ -751,8 +752,8 @@ logger(void *arg)
|
|||
PRIntervalTime period;
|
||||
PRIntervalTime previousTime;
|
||||
PRIntervalTime latestTime;
|
||||
PRUint32 previousOps;
|
||||
PRUint32 ops;
|
||||
PRInt32 previousOps;
|
||||
PRInt32 ops;
|
||||
PRIntervalTime logPeriodTicks = PR_TicksPerSecond();
|
||||
PRFloat64 secondsPerTick = 1.0 / (PRFloat64)logPeriodTicks;
|
||||
int iterations = 0;
|
||||
|
@ -771,7 +772,7 @@ logger(void *arg)
|
|||
*/
|
||||
PR_Sleep(logPeriodTicks);
|
||||
secondsElapsed++;
|
||||
totalPeriodBytes += PR_ATOMIC_SET(&loggerBytes, 0);
|
||||
totalPeriodBytes += PR_ATOMIC_SET(&loggerBytes, 0);
|
||||
totalPeriodBytesTCP += PR_ATOMIC_SET(&loggerBytesTCP, 0);
|
||||
if (secondsElapsed != logPeriod) {
|
||||
continue;
|
||||
|
@ -837,6 +838,8 @@ PRBool testbypass = PR_FALSE;
|
|||
PRBool enableSessionTickets = PR_FALSE;
|
||||
PRBool enableCompression = PR_FALSE;
|
||||
PRBool failedToNegotiateName = PR_FALSE;
|
||||
PRBool enableExtendedMasterSecret = PR_FALSE;
|
||||
|
||||
static char *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX];
|
||||
static int virtServerNameIndex = 1;
|
||||
|
||||
|
@ -1942,6 +1945,13 @@ server_main(
|
|||
}
|
||||
}
|
||||
|
||||
if (enableExtendedMasterSecret) {
|
||||
rv = SSL_OptionSet(model_sock, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
|
||||
if (rv != SECSuccess) {
|
||||
errExit("error enabling extended master secret ");
|
||||
}
|
||||
}
|
||||
|
||||
for (kea = kt_rsa; kea < kt_kea_size; kea++) {
|
||||
if (cert[kea] != NULL) {
|
||||
secStatus = SSL_ConfigSecureServer(model_sock,
|
||||
|
@ -2218,7 +2228,7 @@ main(int argc, char **argv)
|
|||
** numbers, then capital letters, then lower case, alphabetical.
|
||||
*/
|
||||
optstate = PL_CreateOptState(argc, argv,
|
||||
"2:A:BC:DEH:L:M:NP:RS:T:U:V:W:Ya:bc:d:e:f:g:hi:jk:lmn:op:qrst:uvw:xyz");
|
||||
"2:A:BC:DEGH:L:M:NP:RS:T:U:V:W:Ya:bc:d:e:f:g:hi:jk:lmn:op:qrst:uvw:xyz");
|
||||
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||
++optionsFound;
|
||||
switch(optstate->option) {
|
||||
|
@ -2234,6 +2244,8 @@ main(int argc, char **argv)
|
|||
case 'E': disableStepDown = PR_TRUE; break;
|
||||
case 'H': configureDHE = (PORT_Atoi(optstate->value) != 0); break;
|
||||
|
||||
case 'G': enableExtendedMasterSecret = PR_TRUE; break;
|
||||
|
||||
case 'I': /* reserved for OCSP multi-stapling */ break;
|
||||
|
||||
case 'L':
|
||||
|
|
|
@ -73,6 +73,9 @@ GenerateCert(char *nickname, int keysize, char *token)
|
|||
LL_L2UI(serial, PR_Now());
|
||||
|
||||
subject = GetSubjectFromUser(serial);
|
||||
if (!subject) {
|
||||
FatalError("Unable to get subject from user");
|
||||
}
|
||||
|
||||
cert = GenerateSelfSignedObjectSigningCert(nickname, db, subject,
|
||||
serial, keysize, token);
|
||||
|
@ -122,7 +125,9 @@ GetSubjectFromUser(unsigned long serial)
|
|||
#else
|
||||
PR_fprintf(PR_STDOUT, "certificate common name: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp == '\0') {
|
||||
sprintf(common_name_buf, "%s (%lu)", DEFAULT_COMMON_NAME,
|
||||
|
@ -144,7 +149,9 @@ GetSubjectFromUser(unsigned long serial)
|
|||
#else
|
||||
PR_fprintf(PR_STDOUT, "organization: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp != '\0') {
|
||||
org = PORT_ZAlloc(strlen(cp) + 5);
|
||||
|
@ -163,7 +170,9 @@ GetSubjectFromUser(unsigned long serial)
|
|||
#else
|
||||
PR_fprintf(PR_STDOUT, "organization unit: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp != '\0') {
|
||||
orgunit = PORT_ZAlloc(strlen(cp) + 6);
|
||||
|
@ -181,7 +190,9 @@ GetSubjectFromUser(unsigned long serial)
|
|||
#else
|
||||
PR_fprintf(PR_STDOUT, "state or province: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp != '\0') {
|
||||
state = PORT_ZAlloc(strlen(cp) + 6);
|
||||
|
@ -199,7 +210,9 @@ GetSubjectFromUser(unsigned long serial)
|
|||
#else
|
||||
PR_fprintf(PR_STDOUT, "country (must be exactly 2 characters): ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(cp);
|
||||
if (strlen(cp) != 2) {
|
||||
*cp = '\0'; /* country code must be 2 chars */
|
||||
|
@ -220,7 +233,9 @@ GetSubjectFromUser(unsigned long serial)
|
|||
#else
|
||||
PR_fprintf(PR_STDOUT, "username: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp != '\0') {
|
||||
uid = PORT_ZAlloc(strlen(cp) + 7);
|
||||
|
@ -238,7 +253,9 @@ GetSubjectFromUser(unsigned long serial)
|
|||
#else
|
||||
PR_fprintf(PR_STDOUT, "email address: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp != '\0') {
|
||||
email = PORT_ZAlloc(strlen(cp) + 5);
|
||||
|
|
|
@ -129,10 +129,11 @@ void printSecurityInfo(PRFileDesc *fd)
|
|||
suite.macBits, suite.macAlgorithmName);
|
||||
FPRINTF(stderr,
|
||||
"tstclnt: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n"
|
||||
" Compression: %s\n",
|
||||
" Compression: %s, Extended Master Secret: %s\n",
|
||||
channel.authKeyBits, suite.authAlgorithmName,
|
||||
channel.keaKeyBits, suite.keaTypeName,
|
||||
channel.compressionMethodName);
|
||||
channel.compressionMethodName,
|
||||
channel.extendedMasterSecretUsed ? "Yes": "No");
|
||||
}
|
||||
}
|
||||
cert = SSL_RevealCert(fd);
|
||||
|
@ -231,6 +232,7 @@ static void PrintParameterUsage(void)
|
|||
fprintf(stderr, "%-20s Enable compression.\n", "-z");
|
||||
fprintf(stderr, "%-20s Enable false start.\n", "-g");
|
||||
fprintf(stderr, "%-20s Enable the cert_status extension (OCSP stapling).\n", "-T");
|
||||
fprintf(stderr, "%-20s Enable the extended master secret extension (session hash).\n", "-G");
|
||||
fprintf(stderr, "%-20s Require fresh revocation info from side channel.\n"
|
||||
"%-20s -F once means: require for server cert only\n"
|
||||
"%-20s -F twice means: require for intermediates, too\n"
|
||||
|
@ -919,6 +921,7 @@ int main(int argc, char **argv)
|
|||
int enableFalseStart = 0;
|
||||
int enableCertStatus = 0;
|
||||
int forceFallbackSCSV = 0;
|
||||
int enableExtendedMasterSecret = 0;
|
||||
PRSocketOptionData opt;
|
||||
PRNetAddr addr;
|
||||
PRPollDesc pollset[2];
|
||||
|
@ -967,7 +970,7 @@ int main(int argc, char **argv)
|
|||
SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
|
||||
|
||||
optstate = PL_CreateOptState(argc, argv,
|
||||
"46BCDFKM:OR:STV:W:Ya:bc:d:fgh:m:n:op:qr:st:uvw:xz");
|
||||
"46BCDFGKM:OR:STV:W:Ya:bc:d:fgh:m:n:op:qr:st:uvw:xz");
|
||||
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||
switch (optstate->option) {
|
||||
case '?':
|
||||
|
@ -989,6 +992,8 @@ int main(int argc, char **argv)
|
|||
serverCertAuth.testFreshStatusFromSideChannel = PR_TRUE;
|
||||
break;
|
||||
|
||||
case 'G': enableExtendedMasterSecret = PR_TRUE; break;
|
||||
|
||||
case 'I': /* reserved for OCSP multi-stapling */ break;
|
||||
|
||||
case 'O': serverCertAuth.shouldPause = PR_FALSE; break;
|
||||
|
@ -1386,6 +1391,15 @@ int main(int argc, char **argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* enable extended master secret mode */
|
||||
if (enableExtendedMasterSecret) {
|
||||
rv = SSL_OptionSet(s, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "error enabling extended master secret");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
SSL_SetPKCS11PinArg(s, &pwdata);
|
||||
|
||||
serverCertAuth.dbHandle = CERT_GetDefaultCertDB();
|
||||
|
|
|
@ -83,6 +83,26 @@ endif
|
|||
|
||||
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -fno-common -pipe -DDARWIN -DHAVE_STRERROR -DHAVE_BSD_FLOCK $(DARWIN_SDK_CFLAGS)
|
||||
|
||||
ifeq (clang,$(shell $(CC) -? 2>&1 >/dev/null | sed -e 's/:.*//;1q'))
|
||||
NSS_HAS_GCC48 = true
|
||||
endif
|
||||
ifndef NSS_HAS_GCC48
|
||||
NSS_HAS_GCC48 := $(shell \
|
||||
[ `$(CC) -dumpversion | cut -f 1 -d . -` -gt 4 -a \
|
||||
`$(CC) -dumpversion | cut -f 2 -d . -` -ge 8 -o \
|
||||
`$(CC) -dumpversion | cut -f 1 -d . -` -ge 5 ] && \
|
||||
echo true || echo false)
|
||||
export NSS_HAS_GCC48
|
||||
endif
|
||||
ifeq (true,$(NSS_HAS_GCC48))
|
||||
OS_CFLAGS += -Werror
|
||||
else
|
||||
# Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
|
||||
# Use this to disable use of that #pragma and the warnings it suppresses.
|
||||
OS_CFLAGS += -DNSS_NO_GCC48 -Wno-unused-variable -Wno-strict-aliasing
|
||||
$(warning Unable to find gcc >= 4.8 disabling -Werror)
|
||||
endif
|
||||
|
||||
ifdef BUILD_OPT
|
||||
ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
|
||||
OPTIMIZER = -Oz
|
||||
|
|
|
@ -134,7 +134,7 @@ ifeq ($(USE_PTHREADS),1)
|
|||
OS_PTHREAD = -lpthread
|
||||
endif
|
||||
|
||||
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -Wall -Werror -pipe -ffunction-sections -fdata-sections -DLINUX -Dlinux -DHAVE_STRERROR
|
||||
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -Wall -pipe -ffunction-sections -fdata-sections -DLINUX -Dlinux -DHAVE_STRERROR
|
||||
OS_LIBS = $(OS_PTHREAD) -ldl -lc
|
||||
|
||||
ifeq ($(COMPILER_TAG),_clang)
|
||||
|
@ -152,29 +152,21 @@ endif
|
|||
NSS_HAS_GCC48 = true
|
||||
endif
|
||||
|
||||
# Check for the existence of gcc 4.8
|
||||
ifndef NSS_HAS_GCC48
|
||||
define GCC48_TEST =
|
||||
int main() {\n
|
||||
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)\n
|
||||
return 1;\n
|
||||
#else\n
|
||||
return 0;\n
|
||||
#endif\n
|
||||
}\n
|
||||
endef
|
||||
TEST_GCC48 := /tmp/test_gcc48_$(shell echo $$$$)
|
||||
NSS_HAS_GCC48 := (,$(shell echo -e "$(GCC48_TEST)" > $(TEST_GCC48).c && \
|
||||
$(CC) -o $(TEST_GCC48) $(TEST_GCC48).c && \
|
||||
$(TEST_GCC48) && echo true || echo false; \
|
||||
rm -f $(TEST_GCC48) $(TEST_GCC48).c))
|
||||
NSS_HAS_GCC48 := $(shell \
|
||||
[ `$(CC) -dumpversion | cut -f 1 -d . -` -gt 4 -a \
|
||||
`$(CC) -dumpversion | cut -f 2 -d . -` -ge 8 -o \
|
||||
`$(CC) -dumpversion | cut -f 1 -d . -` -ge 5 ] && \
|
||||
echo true || echo false)
|
||||
export NSS_HAS_GCC48
|
||||
endif
|
||||
|
||||
ifeq (true,$(NSS_HAS_GCC48))
|
||||
OS_CFLAGS += -Werror
|
||||
else
|
||||
# Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
|
||||
# Here, we disable use of that #pragma and the warnings it suppresses.
|
||||
OS_CFLAGS += -DNSS_NO_GCC48 -Wno-unused-variable
|
||||
# Use this to disable use of that #pragma and the warnings it suppresses.
|
||||
OS_CFLAGS += -DNSS_NO_GCC48
|
||||
$(warning Unable to find gcc >= 4.8 disabling -Werror)
|
||||
endif
|
||||
|
||||
ifdef USE_PTHREADS
|
||||
|
|
|
@ -424,12 +424,12 @@ $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.S
|
|||
$(OBJDIR)/$(PROG_PREFIX)%: %.cpp
|
||||
@$(MAKE_OBJDIR)
|
||||
ifdef USE_NT_C_SYNTAX
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
ifdef NEED_ABSOLUTE_PATH
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
$(CCC) -o $@ -c $(CFLAGS) $<
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $<
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -440,16 +440,16 @@ $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.cc
|
|||
$(MAKE_OBJDIR)
|
||||
ifdef STRICT_CPLUSPLUS_SUFFIX
|
||||
echo "#line 1 \"$<\"" | cat - $< > $(OBJDIR)/t_$*.cc
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(OBJDIR)/t_$*.cc
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(OBJDIR)/t_$*.cc
|
||||
rm -f $(OBJDIR)/t_$*.cc
|
||||
else
|
||||
ifdef USE_NT_C_SYNTAX
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
ifdef NEED_ABSOLUTE_PATH
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
$(CCC) -o $@ -c $(CFLAGS) $<
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $<
|
||||
endif
|
||||
endif
|
||||
endif #STRICT_CPLUSPLUS_SUFFIX
|
||||
|
@ -458,22 +458,22 @@ $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.cpp
|
|||
@$(MAKE_OBJDIR)
|
||||
ifdef STRICT_CPLUSPLUS_SUFFIX
|
||||
echo "#line 1 \"$<\"" | cat - $< > $(OBJDIR)/t_$*.cc
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(OBJDIR)/t_$*.cc
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(OBJDIR)/t_$*.cc
|
||||
rm -f $(OBJDIR)/t_$*.cc
|
||||
else
|
||||
ifdef USE_NT_C_SYNTAX
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
ifdef NEED_ABSOLUTE_PATH
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
$(CCC) -o $@ -c $(CFLAGS) $<
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $<
|
||||
endif
|
||||
endif
|
||||
endif #STRICT_CPLUSPLUS_SUFFIX
|
||||
|
||||
%.i: %.cpp
|
||||
$(CCC) -C -E $(CFLAGS) $< > $@
|
||||
$(CCC) -C -E $(CFLAGS) $(CXXFLAGS) $< > $@
|
||||
|
||||
%.i: %.c
|
||||
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
|
||||
|
|
|
@ -158,10 +158,11 @@ long new_lseek(int fd, long offset, int origin)
|
|||
{
|
||||
char buffer[1024];
|
||||
long len = seek_pos-end_pos;
|
||||
memset(&buffer, 0, 1024);
|
||||
memset(buffer, 0, 1024);
|
||||
while(len > 0)
|
||||
{
|
||||
write(fd, (char*)&buffer, (size_t)(1024 > len ? len : 1024));
|
||||
if(write(fd, buffer, (size_t)(1024 > len ? len : 1024)) < 0)
|
||||
return(-1);
|
||||
len -= 1024;
|
||||
}
|
||||
return(lseek(fd, seek_pos, SEEK_SET));
|
||||
|
@ -981,7 +982,7 @@ overflow_page(HTAB *hashp)
|
|||
if (offset > SPLITMASK) {
|
||||
if (++splitnum >= NCACHED) {
|
||||
#ifndef macintosh
|
||||
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
|
||||
(void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
@ -996,7 +997,7 @@ overflow_page(HTAB *hashp)
|
|||
free_page++;
|
||||
if (free_page >= NCACHED) {
|
||||
#ifndef macintosh
|
||||
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
|
||||
(void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
@ -1022,8 +1023,7 @@ overflow_page(HTAB *hashp)
|
|||
if (offset > SPLITMASK) {
|
||||
if (++splitnum >= NCACHED) {
|
||||
#ifndef macintosh
|
||||
(void)write(STDERR_FILENO, OVMSG,
|
||||
sizeof(OVMSG) - 1);
|
||||
(void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -911,7 +911,7 @@ hash_seq(
|
|||
uint flag)
|
||||
{
|
||||
register uint32 bucket;
|
||||
register BUFHEAD *bufp;
|
||||
register BUFHEAD *bufp = NULL;
|
||||
HTAB *hashp;
|
||||
uint16 *bp, ndx;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* for SHA-1, SHA-224, and SHA-256 it's 440 bits.
|
||||
* for SHA-384 and SHA-512 it's 888 bits */
|
||||
#define PRNG_SEEDLEN (440/PR_BITS_PER_BYTE)
|
||||
static const PRInt64 PRNG_MAX_ADDITIONAL_BYTES = LL_INIT(0x1, 0x0);
|
||||
#define PRNG_MAX_ADDITIONAL_BYTES PR_INT64(0x100000000)
|
||||
/* 2^35 bits or 2^32 bytes */
|
||||
#define PRNG_MAX_REQUEST_SIZE 0x10000 /* 2^19 bits or 2^16 bytes */
|
||||
#define PRNG_ADDITONAL_DATA_CACHE_SIZE (8*1024) /* must be less than
|
||||
|
|
|
@ -120,8 +120,8 @@ ec_GFp_nistp192_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
|
|||
if (((r2b == 0xffffffff) && (r2a == 0xffffffff)
|
||||
&& (r1b == 0xffffffff) ) &&
|
||||
((r1a == 0xffffffff) ||
|
||||
(r1a == 0xfffffffe) && (r0a == 0xffffffff) &&
|
||||
(r0b == 0xffffffff)) ) {
|
||||
((r1a == 0xfffffffe) && (r0a == 0xffffffff) &&
|
||||
(r0b == 0xffffffff))) ) {
|
||||
/* do a quick subtract */
|
||||
carry = 0;
|
||||
MP_ADD_CARRY(r0a, 1, r0a, carry);
|
||||
|
|
|
@ -22,7 +22,7 @@ ec_GFp_nistp224_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
|
|||
mp_digit carry;
|
||||
#ifdef ECL_THIRTY_TWO_BIT
|
||||
mp_digit a6a = 0, a6b = 0,
|
||||
a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0;
|
||||
a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3b = 0;
|
||||
mp_digit r0a, r0b, r1a, r1b, r2a, r2b, r3a;
|
||||
#else
|
||||
mp_digit a6 = 0, a5 = 0, a4 = 0, a3b = 0, a5a = 0;
|
||||
|
|
|
@ -4190,6 +4190,7 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
|
|||
|
||||
MP_SIGN(rem) = ZPOS;
|
||||
MP_SIGN(div) = ZPOS;
|
||||
MP_SIGN(&part) = ZPOS;
|
||||
|
||||
/* A working temporary for division */
|
||||
MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem)));
|
||||
|
@ -4197,8 +4198,6 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
|
|||
/* Normalize to optimize guessing */
|
||||
MP_CHECKOK( s_mp_norm(rem, div, &d) );
|
||||
|
||||
part = *rem;
|
||||
|
||||
/* Perform the division itself...woo! */
|
||||
MP_USED(quot) = MP_ALLOC(quot);
|
||||
|
||||
|
@ -4207,11 +4206,15 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
|
|||
while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) {
|
||||
int i;
|
||||
int unusedRem;
|
||||
int partExtended = 0; /* set to true if we need to extend part */
|
||||
|
||||
unusedRem = MP_USED(rem) - MP_USED(div);
|
||||
MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem;
|
||||
MP_ALLOC(&part) = MP_ALLOC(rem) - unusedRem;
|
||||
MP_USED(&part) = MP_USED(div);
|
||||
|
||||
/* We have now truncated the part of the remainder to the same length as
|
||||
* the divisor. If part is smaller than div, extend part by one digit. */
|
||||
if (s_mp_cmp(&part, div) < 0) {
|
||||
-- unusedRem;
|
||||
#if MP_ARGCHK == 2
|
||||
|
@ -4220,26 +4223,34 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
|
|||
-- MP_DIGITS(&part);
|
||||
++ MP_USED(&part);
|
||||
++ MP_ALLOC(&part);
|
||||
partExtended = 1;
|
||||
}
|
||||
|
||||
/* Compute a guess for the next quotient digit */
|
||||
q_msd = MP_DIGIT(&part, MP_USED(&part) - 1);
|
||||
div_msd = MP_DIGIT(div, MP_USED(div) - 1);
|
||||
if (q_msd >= div_msd) {
|
||||
if (!partExtended) {
|
||||
/* In this case, q_msd /= div_msd is always 1. First, since div_msd is
|
||||
* normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since
|
||||
* we didn't extend part, q_msd >= div_msd. Therefore we know that
|
||||
* div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we
|
||||
* get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */
|
||||
q_msd = 1;
|
||||
} else if (MP_USED(&part) > 1) {
|
||||
} else {
|
||||
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
|
||||
q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);
|
||||
q_msd /= div_msd;
|
||||
if (q_msd == RADIX)
|
||||
--q_msd;
|
||||
#else
|
||||
mp_digit r;
|
||||
MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
|
||||
div_msd, &q_msd, &r) );
|
||||
if (q_msd == div_msd) {
|
||||
q_msd = MP_DIGIT_MAX;
|
||||
} else {
|
||||
mp_digit r;
|
||||
MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
|
||||
div_msd, &q_msd, &r) );
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
q_msd = 0;
|
||||
}
|
||||
#if MP_ARGCHK == 2
|
||||
assert(q_msd > 0); /* This case should never occur any more. */
|
||||
|
|
|
@ -1143,7 +1143,7 @@ makeGfromIndex(HASH_HashType hashtype,
|
|||
unsigned int len;
|
||||
mp_err err = MP_OKAY;
|
||||
SECStatus rv = SECSuccess;
|
||||
const SECHashObject *hashobj;
|
||||
const SECHashObject *hashobj = NULL;
|
||||
void *hashcx = NULL;
|
||||
|
||||
MP_DIGITS(&e) = 0;
|
||||
|
|
|
@ -67,11 +67,11 @@ static const PRUint32 H256[8] = {
|
|||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||||
};
|
||||
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
#if (_MSC_VER >= 1300)
|
||||
#include <stdlib.h>
|
||||
#pragma intrinsic(_byteswap_ulong)
|
||||
#define SHA_HTONL(x) _byteswap_ulong(x)
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
#elif defined(_MSC_VER) && defined(NSS_X86_OR_X64)
|
||||
#ifndef FORCEINLINE
|
||||
#if (_MSC_VER >= 1200)
|
||||
|
@ -92,7 +92,6 @@ swap4b(PRUint32 dwd)
|
|||
}
|
||||
|
||||
#define SHA_HTONL(x) swap4b(x)
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
|
||||
#elif defined(__GNUC__) && defined(NSS_X86_OR_X64)
|
||||
static __inline__ PRUint32 swap4b(PRUint32 value)
|
||||
|
@ -101,7 +100,6 @@ static __inline__ PRUint32 swap4b(PRUint32 value)
|
|||
return (value);
|
||||
}
|
||||
#define SHA_HTONL(x) swap4b(x)
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
|
||||
#elif defined(__GNUC__) && (defined(__thumb2__) || \
|
||||
(!defined(__thumb__) && \
|
||||
|
@ -121,14 +119,14 @@ static __inline__ PRUint32 swap4b(PRUint32 value)
|
|||
return ret;
|
||||
}
|
||||
#define SHA_HTONL(x) swap4b(x)
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
|
||||
#else
|
||||
#define SWAP4MASK 0x00FF00FF
|
||||
#define SHA_HTONL(x) (t1 = (x), t1 = (t1 << 16) | (t1 >> 16), \
|
||||
((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK))
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
#endif
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
#endif /* defined(IS_LITTLE_ENDIAN) */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma intrinsic (_lrotr, _lrotl)
|
||||
|
@ -665,6 +663,7 @@ void SHA224_Clone(SHA224Context *dest, SHA224Context *src)
|
|||
#define ULLC(hi,lo) 0x ## hi ## lo ## ULL
|
||||
#endif
|
||||
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma intrinsic(_byteswap_uint64)
|
||||
#define SHA_HTONLL(x) _byteswap_uint64(x)
|
||||
|
@ -686,19 +685,20 @@ static __inline__ PRUint64 swap8b(PRUint64 value)
|
|||
(t1 >> 32) | (t1 << 32))
|
||||
#endif
|
||||
#define BYTESWAP8(x) x = SHA_HTONLL(x)
|
||||
#endif /* defined(IS_LITTLE_ENDIAN) */
|
||||
|
||||
#else /* no long long */
|
||||
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
#define ULLC(hi,lo) { 0x ## lo ## U, 0x ## hi ## U }
|
||||
#else
|
||||
#define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U }
|
||||
#endif
|
||||
|
||||
#define SHA_HTONLL(x) ( BYTESWAP4(x.lo), BYTESWAP4(x.hi), \
|
||||
x.hi ^= x.lo ^= x.hi ^= x.lo, x)
|
||||
#define BYTESWAP8(x) do { PRUint32 tmp; BYTESWAP4(x.lo); BYTESWAP4(x.hi); \
|
||||
tmp = x.lo; x.lo = x.hi; x.hi = tmp; } while (0)
|
||||
#else
|
||||
#define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* SHA-384 and SHA-512 constants, K512. */
|
||||
|
|
|
@ -76,7 +76,7 @@ dostime(char *time, const char *s);
|
|||
|
||||
#ifdef NSS_X86_OR_X64
|
||||
/* The following macros throw up warnings. */
|
||||
#ifdef __GNUC__
|
||||
#if defined(__GNUC__) && !defined(NSS_NO_GCC48)
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
#define x86ShortToUint32(ii) ((const PRUint32)*((const PRUint16 *)(ii)))
|
||||
|
|
|
@ -359,7 +359,7 @@ pkix_pl_LdapDefaultClient_VerifyBindResponse(
|
|||
"pkix_pl_LdapDefaultClient_VerifyBindResponse");
|
||||
PKIX_NULLCHECK_TWO(client, client->rcvBuf);
|
||||
|
||||
decode.data = (void *)(client->rcvBuf);
|
||||
decode.data = (unsigned char *)(client->rcvBuf);
|
||||
decode.len = bufLen;
|
||||
|
||||
PKIX_CHECK(pkix_pl_LdapDefaultClient_DecodeBindResponse
|
||||
|
|
|
@ -730,7 +730,7 @@ pkix_pl_LdapResponse_GetResultCode(
|
|||
|
||||
resultMsg = &response->decoded.protocolOp.op.searchResponseResultMsg;
|
||||
|
||||
*pResultCode = *(char *)(resultMsg->resultCode.data);
|
||||
*pResultCode = *(resultMsg->resultCode.data);
|
||||
|
||||
cleanup:
|
||||
|
||||
|
|
|
@ -600,7 +600,7 @@ PKIX_PL_Object_Alloc(
|
|||
object = NULL;
|
||||
|
||||
/* Atomically increment object counter */
|
||||
PR_ATOMIC_INCREMENT(&ctEntry->objCounter);
|
||||
PR_ATOMIC_INCREMENT((PRInt32*)&ctEntry->objCounter);
|
||||
|
||||
cleanup:
|
||||
|
||||
|
@ -897,7 +897,7 @@ PKIX_PL_Object_DecRef(
|
|||
}
|
||||
|
||||
/* Atomically decrement object counter */
|
||||
PR_ATOMIC_DECREMENT(&ctEntry->objCounter);
|
||||
PR_ATOMIC_DECREMENT((PRInt32*)&ctEntry->objCounter);
|
||||
|
||||
/* pkix_pl_Object_Destroy assumes the lock is held */
|
||||
/* It will call unlock and destroy the object */
|
||||
|
|
|
@ -380,6 +380,8 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
|
|||
case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256:
|
||||
case CKM_TLS_KEY_AND_MAC_DERIVE:
|
||||
case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
|
||||
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
|
||||
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
|
||||
case CKM_SHA_1_HMAC:
|
||||
case CKM_SHA_1_HMAC_GENERAL:
|
||||
case CKM_SHA224_HMAC:
|
||||
|
@ -575,6 +577,8 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
|
|||
case CKM_TLS_MASTER_KEY_DERIVE:
|
||||
case CKM_TLS_KEY_AND_MAC_DERIVE:
|
||||
case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
|
||||
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
|
||||
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
|
||||
return CKM_SSL3_PRE_MASTER_KEY_GEN;
|
||||
case CKM_SHA_1_HMAC:
|
||||
case CKM_SHA_1_HMAC_GENERAL:
|
||||
|
|
|
@ -1261,7 +1261,8 @@ pk11_mergeByObjectIDs(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
|
|||
PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
int error, i;
|
||||
int error = SEC_ERROR_LIBRARY_FAILURE;
|
||||
int i;
|
||||
|
||||
for (i=0; i < count; i++) {
|
||||
/* try to update the entire database. On failure, keep going,
|
||||
|
@ -1325,7 +1326,8 @@ PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
|
|||
PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
|
||||
{
|
||||
SECStatus rv = SECSuccess, lrv = SECSuccess;
|
||||
int error, count = 0;
|
||||
int error = SEC_ERROR_LIBRARY_FAILURE;
|
||||
int count = 0;
|
||||
CK_ATTRIBUTE search[2];
|
||||
CK_OBJECT_HANDLE *objectIDs = NULL;
|
||||
CK_BBOOL ck_true = CK_TRUE;
|
||||
|
|
|
@ -1577,7 +1577,7 @@ PK11_WriteRawAttribute(PK11ObjectType objType, void *objSpec,
|
|||
CK_ATTRIBUTE_TYPE attrType, SECItem *item)
|
||||
{
|
||||
PK11SlotInfo *slot = NULL;
|
||||
CK_OBJECT_HANDLE handle;
|
||||
CK_OBJECT_HANDLE handle = 0;
|
||||
CK_ATTRIBUTE setTemplate;
|
||||
CK_RV crv;
|
||||
CK_SESSION_HANDLE rwsession;
|
||||
|
@ -1630,7 +1630,7 @@ PK11_ReadRawAttribute(PK11ObjectType objType, void *objSpec,
|
|||
CK_ATTRIBUTE_TYPE attrType, SECItem *item)
|
||||
{
|
||||
PK11SlotInfo *slot = NULL;
|
||||
CK_OBJECT_HANDLE handle;
|
||||
CK_OBJECT_HANDLE handle = 0;
|
||||
|
||||
switch (objType) {
|
||||
case PK11_TypeGeneric:
|
||||
|
|
|
@ -234,13 +234,17 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
|
|||
rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate,
|
||||
derPKI);
|
||||
if( rv != SECSuccess ) {
|
||||
goto finish;
|
||||
/* If SEC_ASN1DecodeItem fails, we cannot assume anything about the
|
||||
* validity of the data in pki. The best we can do is free the arena
|
||||
* and return.
|
||||
*/
|
||||
PORT_FreeArena(temparena, PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
|
||||
publicValue, isPerm, isPrivate, keyUsage, privk, wincx);
|
||||
|
||||
finish:
|
||||
/* this zeroes the key and frees the arena */
|
||||
SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/);
|
||||
return rv;
|
||||
|
|
|
@ -1378,7 +1378,7 @@ nsslowkey_PutPWCheckEntry(NSSLOWKEYDBHandle *handle,NSSLOWKEYPasswordEntry *entr
|
|||
NSSLOWKEYDBKey *dbkey = NULL;
|
||||
SECItem *item = NULL;
|
||||
SECItem salt;
|
||||
SECOidTag algid;
|
||||
SECOidTag algid = SEC_OID_UNKNOWN;
|
||||
SECStatus rv = SECFailure;
|
||||
PLArenaPool *arena;
|
||||
int ret;
|
||||
|
|
|
@ -601,7 +601,7 @@ legacy_Open(const char *configdir, const char *certPrefix,
|
|||
if (certDB) *certDB = NULL;
|
||||
|
||||
if (certDB) {
|
||||
NSSLOWCERTCertDBHandle *certdbPtr;
|
||||
NSSLOWCERTCertDBHandle *certdbPtr = NULL;
|
||||
|
||||
crv = lg_OpenCertDB(configdir, certPrefix, readOnly, &certdbPtr);
|
||||
if (crv != CKR_OK) {
|
||||
|
|
|
@ -475,6 +475,10 @@ static const struct mechanismList mechanisms[] = {
|
|||
{CKM_TLS12_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
|
||||
{CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256,
|
||||
{48, 48, CKF_DERIVE}, PR_FALSE},
|
||||
{CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE,
|
||||
{48,128, CKF_DERIVE}, PR_FALSE},
|
||||
{CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH,
|
||||
{48,128, CKF_DERIVE}, PR_FALSE},
|
||||
/* ---------------------- PBE Key Derivations ------------------------ */
|
||||
{CKM_PBE_MD2_DES_CBC, {8, 8, CKF_DERIVE}, PR_TRUE},
|
||||
{CKM_PBE_MD5_DES_CBC, {8, 8, CKF_DERIVE}, PR_TRUE},
|
||||
|
@ -2603,7 +2607,7 @@ CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout)
|
|||
--slot->sessionCount;
|
||||
SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock));
|
||||
if (session->info.flags & CKF_RW_SESSION) {
|
||||
PR_ATOMIC_DECREMENT(&slot->rwSessionCount);
|
||||
(void)PR_ATOMIC_DECREMENT(&slot->rwSessionCount);
|
||||
}
|
||||
} else {
|
||||
SKIP_AFTER_FORK(PZ_Unlock(lock));
|
||||
|
@ -3720,7 +3724,7 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
|
|||
++slot->sessionCount;
|
||||
PZ_Unlock(slot->slotLock);
|
||||
if (session->info.flags & CKF_RW_SESSION) {
|
||||
PR_ATOMIC_INCREMENT(&slot->rwSessionCount);
|
||||
(void)PR_ATOMIC_INCREMENT(&slot->rwSessionCount);
|
||||
}
|
||||
|
||||
do {
|
||||
|
@ -3788,7 +3792,7 @@ CK_RV NSC_CloseSession(CK_SESSION_HANDLE hSession)
|
|||
sftk_freeDB(handle);
|
||||
}
|
||||
if (session->info.flags & CKF_RW_SESSION) {
|
||||
PR_ATOMIC_DECREMENT(&slot->rwSessionCount);
|
||||
(void)PR_ATOMIC_DECREMENT(&slot->rwSessionCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3840,7 +3840,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
|
|||
* produce them any more. The affected algorithm was 3DES.
|
||||
*/
|
||||
PRBool faultyPBE3DES = PR_FALSE;
|
||||
HASH_HashType hashType;
|
||||
HASH_HashType hashType = HASH_AlgNULL;
|
||||
|
||||
CHECK_FORK();
|
||||
|
||||
|
@ -4081,7 +4081,7 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
|
|||
*/
|
||||
CK_MECHANISM mech = {0, NULL, 0};
|
||||
|
||||
CK_ULONG modulusLen;
|
||||
CK_ULONG modulusLen = 0;
|
||||
CK_ULONG subPrimeLen = 0;
|
||||
PRBool isEncryptable = PR_FALSE;
|
||||
PRBool canSignVerify = PR_FALSE;
|
||||
|
@ -6007,7 +6007,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
|
|||
isDH = PR_TRUE;
|
||||
}
|
||||
|
||||
/* first do the consistancy checks */
|
||||
/* first do the consistency checks */
|
||||
if (!isDH && (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) {
|
||||
crv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
break;
|
||||
|
@ -6136,6 +6136,101 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Extended master key derivation [draft-ietf-tls-session-hash] */
|
||||
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
|
||||
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
|
||||
{
|
||||
CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *ems_params;
|
||||
SSL3RSAPreMasterSecret *rsa_pms;
|
||||
SECStatus status;
|
||||
SECItem pms = { siBuffer, NULL, 0 };
|
||||
SECItem seed = { siBuffer, NULL, 0 };
|
||||
SECItem master = { siBuffer, NULL, 0 };
|
||||
|
||||
ems_params = (CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS*)
|
||||
pMechanism->pParameter;
|
||||
|
||||
/* First do the consistency checks */
|
||||
if ((mechanism == CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE) &&
|
||||
(att->attrib.ulValueLen != SSL3_PMS_LENGTH)) {
|
||||
crv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
break;
|
||||
}
|
||||
att2 = sftk_FindAttribute(sourceKey,CKA_KEY_TYPE);
|
||||
if ((att2 == NULL) ||
|
||||
(*(CK_KEY_TYPE *)att2->attrib.pValue != CKK_GENERIC_SECRET)) {
|
||||
if (att2) sftk_FreeAttribute(att2);
|
||||
crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
|
||||
break;
|
||||
}
|
||||
sftk_FreeAttribute(att2);
|
||||
if (keyType != CKK_GENERIC_SECRET) {
|
||||
crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
|
||||
break;
|
||||
}
|
||||
if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) {
|
||||
crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Do the key derivation */
|
||||
pms.data = (unsigned char*) att->attrib.pValue;
|
||||
pms.len = att->attrib.ulValueLen;
|
||||
seed.data = ems_params->pSessionHash;
|
||||
seed.len = ems_params->ulSessionHashLen;
|
||||
master.data = key_block;
|
||||
master.len = SSL3_MASTER_SECRET_LENGTH;
|
||||
if (ems_params-> prfHashMechanism == CKM_TLS_PRF) {
|
||||
/*
|
||||
* In this case, the session hash is the concatenation of SHA-1
|
||||
* and MD5, so it should be 36 bytes long.
|
||||
*/
|
||||
if (seed.len != MD5_LENGTH + SHA1_LENGTH) {
|
||||
crv = CKR_TEMPLATE_INCONSISTENT;
|
||||
break;
|
||||
}
|
||||
|
||||
status = TLS_PRF(&pms, "extended master secret",
|
||||
&seed, &master, isFIPS);
|
||||
} else {
|
||||
const SECHashObject *hashObj;
|
||||
|
||||
tlsPrfHash = GetHashTypeFromMechanism(ems_params->prfHashMechanism);
|
||||
if (tlsPrfHash == HASH_AlgNULL) {
|
||||
crv = CKR_MECHANISM_PARAM_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
hashObj = HASH_GetRawHashObject(tlsPrfHash);
|
||||
if (seed.len != hashObj->length) {
|
||||
crv = CKR_TEMPLATE_INCONSISTENT;
|
||||
break;
|
||||
}
|
||||
|
||||
status = TLS_P_hash(tlsPrfHash, &pms, "extended master secret",
|
||||
&seed, &master, isFIPS);
|
||||
}
|
||||
|
||||
/* Reflect the version if required */
|
||||
if (ems_params->pVersion) {
|
||||
SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
|
||||
rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue;
|
||||
/* don't leak more key material than necessary for SSL to work */
|
||||
if ((sessKey == NULL) || sessKey->wasDerived) {
|
||||
ems_params->pVersion->major = 0xff;
|
||||
ems_params->pVersion->minor = 0xff;
|
||||
} else {
|
||||
ems_params->pVersion->major = rsa_pms->client_version[0];
|
||||
ems_params->pVersion->minor = rsa_pms->client_version[1];
|
||||
}
|
||||
}
|
||||
|
||||
/* Store the results */
|
||||
crv = sftk_forceAttribute(key, CKA_VALUE, key_block,
|
||||
SSL3_MASTER_SECRET_LENGTH);
|
||||
break;
|
||||
}
|
||||
|
||||
case CKM_TLS12_KEY_AND_MAC_DERIVE:
|
||||
case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
|
||||
case CKM_TLS_KEY_AND_MAC_DERIVE:
|
||||
|
|
|
@ -2408,7 +2408,7 @@ sftk_getCertDB(SFTKSlot *slot)
|
|||
PZ_Lock(slot->slotLock);
|
||||
dbHandle = slot->certDB;
|
||||
if (dbHandle) {
|
||||
PR_ATOMIC_INCREMENT(&dbHandle->ref);
|
||||
(void)PR_ATOMIC_INCREMENT(&dbHandle->ref);
|
||||
}
|
||||
PZ_Unlock(slot->slotLock);
|
||||
return dbHandle;
|
||||
|
@ -2426,7 +2426,7 @@ sftk_getKeyDB(SFTKSlot *slot)
|
|||
SKIP_AFTER_FORK(PZ_Lock(slot->slotLock));
|
||||
dbHandle = slot->keyDB;
|
||||
if (dbHandle) {
|
||||
PR_ATOMIC_INCREMENT(&dbHandle->ref);
|
||||
(void)PR_ATOMIC_INCREMENT(&dbHandle->ref);
|
||||
}
|
||||
SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock));
|
||||
return dbHandle;
|
||||
|
@ -2444,7 +2444,7 @@ sftk_getDBForTokenObject(SFTKSlot *slot, CK_OBJECT_HANDLE objectID)
|
|||
PZ_Lock(slot->slotLock);
|
||||
dbHandle = objectID & SFTK_KEYDB_TYPE ? slot->keyDB : slot->certDB;
|
||||
if (dbHandle) {
|
||||
PR_ATOMIC_INCREMENT(&dbHandle->ref);
|
||||
(void)PR_ATOMIC_INCREMENT(&dbHandle->ref);
|
||||
}
|
||||
PZ_Unlock(slot->slotLock);
|
||||
return dbHandle;
|
||||
|
|
|
@ -434,3 +434,9 @@ ER3(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 134),
|
|||
|
||||
ER3(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 135),
|
||||
"The peer used an unsupported combination of signature and hash algorithm.")
|
||||
|
||||
ER3(SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 136),
|
||||
"The peer tried to resume without a correct extended_master_secret extension")
|
||||
|
||||
ER3(SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 137),
|
||||
"The peer tried to resume with an unexpected extended_master_secret extension")
|
||||
|
|
|
@ -431,7 +431,7 @@ key_and_mac_derive_fail:
|
|||
* so isRSA is always true.
|
||||
*/
|
||||
SECStatus
|
||||
ssl3_MasterKeyDeriveBypass(
|
||||
ssl3_MasterSecretDeriveBypass(
|
||||
ssl3CipherSpec * pwSpec,
|
||||
const unsigned char * cr,
|
||||
const unsigned char * sr,
|
||||
|
|
|
@ -196,6 +196,14 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
|
|||
*/
|
||||
#define SSL_ENABLE_SERVER_DHE 29
|
||||
|
||||
/* Use draft-ietf-tls-session-hash. Controls whether we offer the
|
||||
* extended_master_secret extension which, when accepted, hashes
|
||||
* the handshake transcript into the master secret. This option is
|
||||
* disabled by default.
|
||||
*/
|
||||
#define SSL_ENABLE_EXTENDED_MASTER_SECRET 30
|
||||
|
||||
|
||||
#ifdef SSL_DEPRECATED_FUNCTION
|
||||
/* Old deprecated function names */
|
||||
SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on);
|
||||
|
|
|
@ -62,6 +62,10 @@ static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss,
|
|||
const unsigned char *b,
|
||||
unsigned int l);
|
||||
static SECOidTag ssl3_TLSHashAlgorithmToOID(SSLHashType hashFunc);
|
||||
static SECStatus ssl3_ComputeHandshakeHashes(sslSocket *ss,
|
||||
ssl3CipherSpec *spec,
|
||||
SSL3Hashes *hashes,
|
||||
PRUint32 sender);
|
||||
static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
|
||||
|
||||
static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
|
||||
|
@ -2221,7 +2225,11 @@ fail:
|
|||
* Sets error code, but caller probably should override to disambiguate.
|
||||
* NULL pms means re-use old master_secret.
|
||||
*
|
||||
* This code is common to the bypass and PKCS11 execution paths.
|
||||
* This code is common to the bypass and PKCS11 execution paths. For
|
||||
* the bypass case, pms is NULL. If the old master secret is reused,
|
||||
* pms is NULL and the master secret is already in either
|
||||
* pwSpec->msItem.len (the bypass case) or pwSpec->master_secret.
|
||||
*
|
||||
* For the bypass case, pms is NULL.
|
||||
*/
|
||||
SECStatus
|
||||
|
@ -3627,13 +3635,70 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* This method uses PKCS11 to derive the MS from the PMS, where PMS
|
||||
** is a PKCS11 symkey. This is used in all cases except the
|
||||
** "triple bypass" with RSA key exchange.
|
||||
** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec.
|
||||
/* This method completes the derivation of the MS from the PMS.
|
||||
**
|
||||
** 1. Derive the MS, if possible, else return an error.
|
||||
**
|
||||
** 2. Check the version if |pms_version| is non-zero and if wrong,
|
||||
** return an error.
|
||||
**
|
||||
** 3. If |msp| is nonzero, return MS in |*msp|.
|
||||
|
||||
** Called from:
|
||||
** ssl3_ComputeMasterSecretInt
|
||||
** tls_ComputeExtendedMasterSecretInt
|
||||
*/
|
||||
static SECStatus
|
||||
ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
|
||||
ssl3_ComputeMasterSecretFinish(sslSocket *ss,
|
||||
CK_MECHANISM_TYPE master_derive,
|
||||
CK_MECHANISM_TYPE key_derive,
|
||||
CK_VERSION *pms_version,
|
||||
SECItem *params, CK_FLAGS keyFlags,
|
||||
PK11SymKey *pms, PK11SymKey **msp)
|
||||
{
|
||||
PK11SymKey *ms = NULL;
|
||||
|
||||
ms = PK11_DeriveWithFlags(pms, master_derive,
|
||||
params, key_derive,
|
||||
CKA_DERIVE, 0, keyFlags);
|
||||
if (!ms) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (pms_version && ss->opt.detectRollBack) {
|
||||
SSL3ProtocolVersion client_version;
|
||||
client_version = pms_version->major << 8 | pms_version->minor;
|
||||
|
||||
if (IS_DTLS(ss)) {
|
||||
client_version = dtls_DTLSVersionToTLSVersion(client_version);
|
||||
}
|
||||
|
||||
if (client_version != ss->clientHelloVersion) {
|
||||
/* Destroy MS. Version roll-back detected. */
|
||||
PK11_FreeSymKey(ms);
|
||||
ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
if (msp) {
|
||||
*msp = ms;
|
||||
} else {
|
||||
PK11_FreeSymKey(ms);
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* Compute the ordinary (pre draft-ietf-tls-session-hash) master
|
||||
** secret and return it in |*msp|.
|
||||
**
|
||||
** Called from: ssl3_ComputeMasterSecret
|
||||
*/
|
||||
static SECStatus
|
||||
ssl3_ComputeMasterSecretInt(sslSocket *ss, PK11SymKey *pms,
|
||||
PK11SymKey **msp)
|
||||
{
|
||||
ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec;
|
||||
const ssl3KEADef *kea_def= ss->ssl3.hs.kea_def;
|
||||
|
@ -3643,26 +3708,23 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
|
|||
(pwSpec->version > SSL_LIBRARY_VERSION_3_0));
|
||||
PRBool isTLS12=
|
||||
(PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
/*
|
||||
/*
|
||||
* Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH
|
||||
* which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size
|
||||
* data into a 48-byte value.
|
||||
* data into a 48-byte value, and does not expect to return the version.
|
||||
*/
|
||||
PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
|
||||
(ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
|
||||
SECStatus rv = SECFailure;
|
||||
CK_MECHANISM_TYPE master_derive;
|
||||
CK_MECHANISM_TYPE key_derive;
|
||||
SECItem params;
|
||||
CK_FLAGS keyFlags;
|
||||
CK_VERSION pms_version;
|
||||
CK_VERSION *pms_version_ptr = NULL;
|
||||
/* master_params may be used as a CK_SSL3_MASTER_KEY_DERIVE_PARAMS */
|
||||
CK_TLS12_MASTER_KEY_DERIVE_PARAMS master_params;
|
||||
unsigned int master_params_len;
|
||||
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
|
||||
PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
|
||||
if (isTLS12) {
|
||||
if(isDH) master_derive = CKM_TLS12_MASTER_KEY_DERIVE_DH;
|
||||
else master_derive = CKM_TLS12_MASTER_KEY_DERIVE;
|
||||
|
@ -3680,93 +3742,142 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
|
|||
keyFlags = 0;
|
||||
}
|
||||
|
||||
if (pms || !pwSpec->master_secret) {
|
||||
if (isDH) {
|
||||
master_params.pVersion = NULL;
|
||||
} else {
|
||||
master_params.pVersion = &pms_version;
|
||||
}
|
||||
master_params.RandomInfo.pClientRandom = cr;
|
||||
master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
|
||||
master_params.RandomInfo.pServerRandom = sr;
|
||||
master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
|
||||
if (isTLS12) {
|
||||
master_params.prfHashMechanism = CKM_SHA256;
|
||||
master_params_len = sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS);
|
||||
} else {
|
||||
master_params_len = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
|
||||
}
|
||||
|
||||
params.data = (unsigned char *) &master_params;
|
||||
params.len = master_params_len;
|
||||
if (!isDH) {
|
||||
pms_version_ptr = &pms_version;
|
||||
}
|
||||
|
||||
if (pms != NULL) {
|
||||
#if defined(TRACE)
|
||||
if (ssl_trace >= 100) {
|
||||
SECStatus extractRV = PK11_ExtractKeyValue(pms);
|
||||
if (extractRV == SECSuccess) {
|
||||
SECItem * keyData = PK11_GetKeyData(pms);
|
||||
if (keyData && keyData->data && keyData->len) {
|
||||
ssl_PrintBuf(ss, "Pre-Master Secret",
|
||||
keyData->data, keyData->len);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
pwSpec->master_secret = PK11_DeriveWithFlags(pms, master_derive,
|
||||
¶ms, key_derive, CKA_DERIVE, 0, keyFlags);
|
||||
if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) {
|
||||
SSL3ProtocolVersion client_version;
|
||||
client_version = pms_version.major << 8 | pms_version.minor;
|
||||
|
||||
if (IS_DTLS(ss)) {
|
||||
client_version = dtls_DTLSVersionToTLSVersion(client_version);
|
||||
}
|
||||
|
||||
if (client_version != ss->clientHelloVersion) {
|
||||
/* Destroy it. Version roll-back detected. */
|
||||
PK11_FreeSymKey(pwSpec->master_secret);
|
||||
pwSpec->master_secret = NULL;
|
||||
}
|
||||
}
|
||||
if (pwSpec->master_secret == NULL) {
|
||||
/* Generate a faux master secret in the same slot as the old one. */
|
||||
PK11SlotInfo * slot = PK11_GetSlotFromKey((PK11SymKey *)pms);
|
||||
PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);
|
||||
|
||||
PK11_FreeSlot(slot);
|
||||
if (fpms != NULL) {
|
||||
pwSpec->master_secret = PK11_DeriveWithFlags(fpms,
|
||||
master_derive, ¶ms, key_derive,
|
||||
CKA_DERIVE, 0, keyFlags);
|
||||
PK11_FreeSymKey(fpms);
|
||||
}
|
||||
}
|
||||
master_params.pVersion = pms_version_ptr;
|
||||
master_params.RandomInfo.pClientRandom = cr;
|
||||
master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
|
||||
master_params.RandomInfo.pServerRandom = sr;
|
||||
master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
|
||||
if (isTLS12) {
|
||||
master_params.prfHashMechanism = CKM_SHA256;
|
||||
master_params_len = sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS);
|
||||
} else {
|
||||
/* prfHashMechanism is not relevant with this PRF */
|
||||
master_params_len = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
|
||||
}
|
||||
if (pwSpec->master_secret == NULL) {
|
||||
/* Generate a faux master secret from the internal slot. */
|
||||
PK11SlotInfo * slot = PK11_GetInternalSlot();
|
||||
PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);
|
||||
|
||||
PK11_FreeSlot(slot);
|
||||
if (fpms != NULL) {
|
||||
pwSpec->master_secret = PK11_DeriveWithFlags(fpms,
|
||||
master_derive, ¶ms, key_derive,
|
||||
CKA_DERIVE, 0, keyFlags);
|
||||
if (pwSpec->master_secret == NULL) {
|
||||
pwSpec->master_secret = fpms; /* use the fpms as the master. */
|
||||
fpms = NULL;
|
||||
}
|
||||
}
|
||||
if (fpms) {
|
||||
PK11_FreeSymKey(fpms);
|
||||
}
|
||||
params.data = (unsigned char *) &master_params;
|
||||
params.len = master_params_len;
|
||||
|
||||
return ssl3_ComputeMasterSecretFinish(ss, master_derive, key_derive,
|
||||
pms_version_ptr, ¶ms,
|
||||
keyFlags, pms, msp);
|
||||
}
|
||||
|
||||
/* Compute the draft-ietf-tls-session-hash master
|
||||
** secret and return it in |*msp|.
|
||||
**
|
||||
** Called from: ssl3_ComputeMasterSecret
|
||||
*/
|
||||
static SECStatus
|
||||
tls_ComputeExtendedMasterSecretInt(sslSocket *ss, PK11SymKey *pms,
|
||||
PK11SymKey **msp)
|
||||
{
|
||||
ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
|
||||
CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS extended_master_params;
|
||||
SSL3Hashes hashes;
|
||||
/*
|
||||
* Determine whether to use the DH/ECDH or RSA derivation modes.
|
||||
*/
|
||||
/*
|
||||
* TODO(ekr@rtfm.com): Verify that the slot can handle this key expansion
|
||||
* mode. Bug 1198298 */
|
||||
PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
|
||||
(ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
|
||||
CK_MECHANISM_TYPE master_derive;
|
||||
CK_MECHANISM_TYPE key_derive;
|
||||
SECItem params;
|
||||
const CK_FLAGS keyFlags = CKF_SIGN | CKF_VERIFY;
|
||||
CK_VERSION pms_version;
|
||||
CK_VERSION *pms_version_ptr = NULL;
|
||||
SECStatus rv;
|
||||
|
||||
rv = ssl3_ComputeHandshakeHashes(ss, pwSpec, &hashes, 0);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_Assert(0); /* Should never fail */
|
||||
ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
if (pwSpec->master_secret == NULL) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
|
||||
return rv;
|
||||
|
||||
if (isDH) {
|
||||
master_derive = CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH;
|
||||
} else {
|
||||
master_derive = CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE;
|
||||
pms_version_ptr = &pms_version;
|
||||
}
|
||||
|
||||
if (pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
|
||||
/* TLS 1.2 */
|
||||
extended_master_params.prfHashMechanism = CKM_SHA256;
|
||||
key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE;
|
||||
} else {
|
||||
/* TLS < 1.2 */
|
||||
extended_master_params.prfHashMechanism = CKM_TLS_PRF;
|
||||
key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
|
||||
}
|
||||
|
||||
extended_master_params.pVersion = pms_version_ptr;
|
||||
extended_master_params.pSessionHash = hashes.u.raw;
|
||||
extended_master_params.ulSessionHashLen = hashes.len;
|
||||
|
||||
params.data = (unsigned char *) &extended_master_params;
|
||||
params.len = sizeof extended_master_params;
|
||||
|
||||
return ssl3_ComputeMasterSecretFinish(ss, master_derive, key_derive,
|
||||
pms_version_ptr, ¶ms,
|
||||
keyFlags, pms, msp);
|
||||
}
|
||||
|
||||
|
||||
/* Wrapper method to compute the master secret and return it in |*msp|.
|
||||
**
|
||||
** Called from ssl3_ComputeMasterSecret
|
||||
*/
|
||||
static SECStatus
|
||||
ssl3_ComputeMasterSecret(sslSocket *ss, PK11SymKey *pms,
|
||||
PK11SymKey **msp)
|
||||
{
|
||||
PORT_Assert(pms != NULL);
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
||||
PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
|
||||
|
||||
if (ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
|
||||
return tls_ComputeExtendedMasterSecretInt(ss, pms, msp);
|
||||
} else {
|
||||
return ssl3_ComputeMasterSecretInt(ss, pms, msp);
|
||||
}
|
||||
}
|
||||
|
||||
/* This method uses PKCS11 to derive the MS from the PMS, where PMS
|
||||
** is a PKCS11 symkey. We call ssl3_ComputeMasterSecret to do the
|
||||
** computations and then modify the pwSpec->state as a side effect.
|
||||
**
|
||||
** This is used in all cases except the "triple bypass" with RSA key
|
||||
** exchange.
|
||||
**
|
||||
** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec.
|
||||
*/
|
||||
static SECStatus
|
||||
ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
|
||||
{
|
||||
SECStatus rv;
|
||||
PK11SymKey* ms = NULL;
|
||||
ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
|
||||
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
|
||||
PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
|
||||
|
||||
if (pms) {
|
||||
rv = ssl3_ComputeMasterSecret(ss, pms, &ms);
|
||||
pwSpec->master_secret = ms;
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifndef NO_PKCS11_BYPASS
|
||||
if (ss->opt.bypassPKCS11) {
|
||||
SECItem * keydata;
|
||||
|
@ -3777,7 +3888,7 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
|
|||
rv = PK11_ExtractKeyValue(pwSpec->master_secret);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
/* This returns the address of the secItem inside the key struct,
|
||||
* not a copy or a reference. So, there's no need to free it.
|
||||
*/
|
||||
|
@ -3792,10 +3903,10 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Derive encryption and MAC Keys (and IVs) from master secret
|
||||
* Sets a useful error code when returning SECFailure.
|
||||
|
@ -4628,11 +4739,6 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
|
|||
/* compute them without PKCS11 */
|
||||
PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
|
||||
|
||||
if (!spec->msItem.data) {
|
||||
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ss->ssl3.hs.sha_clone(sha_cx, ss->ssl3.hs.sha_cx);
|
||||
ss->ssl3.hs.sha_obj->end(sha_cx, hashes->u.raw, &hashes->len,
|
||||
sizeof(hashes->u.raw));
|
||||
|
@ -4651,11 +4757,6 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
|
|||
#define md5cx ((MD5Context *)md5_cx)
|
||||
#define shacx ((SHA1Context *)sha_cx)
|
||||
|
||||
if (!spec->msItem.data) {
|
||||
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
MD5_Clone (md5cx, (MD5Context *)ss->ssl3.hs.md5_cx);
|
||||
SHA1_Clone(shacx, (SHA1Context *)ss->ssl3.hs.sha_cx);
|
||||
|
||||
|
@ -4663,6 +4764,12 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
|
|||
/* compute hashes for SSL3. */
|
||||
unsigned char s[4];
|
||||
|
||||
if (!spec->msItem.data) {
|
||||
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
s[0] = (unsigned char)(sender >> 24);
|
||||
s[1] = (unsigned char)(sender >> 16);
|
||||
s[2] = (unsigned char)(sender >> 8);
|
||||
|
@ -4735,11 +4842,6 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
|
|||
unsigned char stackBuf[1024];
|
||||
unsigned char *stateBuf = NULL;
|
||||
|
||||
if (!spec->master_secret) {
|
||||
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
h = ss->ssl3.hs.sha;
|
||||
stateBuf = PK11_SaveContextAlloc(h, stackBuf,
|
||||
sizeof(stackBuf), &stateLen);
|
||||
|
@ -4779,11 +4881,6 @@ tls12_loser:
|
|||
unsigned char md5StackBuf[256];
|
||||
unsigned char shaStackBuf[512];
|
||||
|
||||
if (!spec->master_secret) {
|
||||
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
md5StateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.md5, md5StackBuf,
|
||||
sizeof md5StackBuf, &md5StateLen);
|
||||
if (md5StateBuf == NULL) {
|
||||
|
@ -4804,6 +4901,12 @@ tls12_loser:
|
|||
/* compute hashes for SSL3. */
|
||||
unsigned char s[4];
|
||||
|
||||
if (!spec->master_secret) {
|
||||
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
s[0] = (unsigned char)(sender >> 24);
|
||||
s[1] = (unsigned char)(sender >> 16);
|
||||
s[2] = (unsigned char)(sender >> 8);
|
||||
|
@ -6049,14 +6152,6 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
|
|||
}
|
||||
}
|
||||
|
||||
rv = ssl3_InitPendingCipherSpec(ss, pms);
|
||||
PK11_FreeSymKey(pms); pms = NULL;
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
|
||||
isTLS ? enc_pms.len + 2 : enc_pms.len);
|
||||
if (rv != SECSuccess) {
|
||||
|
@ -6071,6 +6166,15 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
|
|||
goto loser; /* err set by ssl3_AppendHandshake* */
|
||||
}
|
||||
|
||||
rv = ssl3_InitPendingCipherSpec(ss, pms);
|
||||
PK11_FreeSymKey(pms);
|
||||
pms = NULL;
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = SECSuccess;
|
||||
|
||||
loser:
|
||||
|
@ -6140,14 +6244,6 @@ sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
|
|||
SECKEY_DestroyPrivateKey(privKey);
|
||||
privKey = NULL;
|
||||
|
||||
rv = ssl3_InitPendingCipherSpec(ss, pms);
|
||||
PK11_FreeSymKey(pms); pms = NULL;
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
|
||||
pubKey->u.dh.publicValue.len + 2);
|
||||
if (rv != SECSuccess) {
|
||||
|
@ -6163,8 +6259,16 @@ sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
|
|||
goto loser; /* err set by ssl3_AppendHandshake* */
|
||||
}
|
||||
|
||||
rv = SECSuccess;
|
||||
rv = ssl3_InitPendingCipherSpec(ss, pms);
|
||||
PK11_FreeSymKey(pms);
|
||||
pms = NULL;
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = SECSuccess;
|
||||
|
||||
loser:
|
||||
|
||||
|
@ -6561,6 +6665,32 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
|||
|
||||
SECItem wrappedMS; /* wrapped master secret. */
|
||||
|
||||
/* [draft-ietf-tls-session-hash-06; Section 5.3]
|
||||
*
|
||||
* o If the original session did not use the "extended_master_secret"
|
||||
* extension but the new ServerHello contains the extension, the
|
||||
* client MUST abort the handshake.
|
||||
*/
|
||||
if (!sid->u.ssl3.keys.extendedMasterSecretUsed &&
|
||||
ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
|
||||
errCode = SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET;
|
||||
goto alert_loser;
|
||||
}
|
||||
|
||||
/*
|
||||
* o If the original session used an extended master secret but the new
|
||||
* ServerHello does not contain the "extended_master_secret"
|
||||
* extension, the client SHOULD abort the handshake.
|
||||
*
|
||||
* TODO(ekr@rtfm.com): Add option to refuse to resume when EMS is not
|
||||
* used at all (bug 1176526).
|
||||
*/
|
||||
if (sid->u.ssl3.keys.extendedMasterSecretUsed &&
|
||||
!ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
|
||||
errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET;
|
||||
goto alert_loser;
|
||||
}
|
||||
|
||||
ss->sec.authAlgorithm = sid->authAlgorithm;
|
||||
ss->sec.authKeyBits = sid->authKeyBits;
|
||||
ss->sec.keaType = sid->keaType;
|
||||
|
@ -6662,7 +6792,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
|||
ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
|
||||
}
|
||||
|
||||
/* NULL value for PMS signifies re-use of the old MS */
|
||||
/* NULL value for PMS because we are reusing the old MS */
|
||||
rv = ssl3_InitPendingCipherSpec(ss, NULL);
|
||||
if (rv != SECSuccess) {
|
||||
goto alert_loser; /* err code was set */
|
||||
|
@ -6691,6 +6821,9 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
|||
sid->u.ssl3.sessionIDLength = sidBytes.len;
|
||||
PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len);
|
||||
|
||||
sid->u.ssl3.keys.extendedMasterSecretUsed =
|
||||
ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn);
|
||||
|
||||
ss->ssl3.hs.isResuming = PR_FALSE;
|
||||
if (ss->ssl3.hs.kea_def->signKeyType != sign_null) {
|
||||
/* All current cipher suites other than those with sign_null (i.e.,
|
||||
|
@ -7628,6 +7761,7 @@ ssl3_NewSessionID(sslSocket *ss, PRBool is_server)
|
|||
sid->u.ssl3.policy = SSL_ALLOWED;
|
||||
sid->u.ssl3.clientWriteKey = NULL;
|
||||
sid->u.ssl3.serverWriteKey = NULL;
|
||||
sid->u.ssl3.keys.extendedMasterSecretUsed = PR_FALSE;
|
||||
|
||||
if (is_server) {
|
||||
SECStatus rv;
|
||||
|
@ -8188,6 +8322,8 @@ compression_found:
|
|||
/* If there are any failures while processing the old sid,
|
||||
* we don't consider them to be errors. Instead, We just behave
|
||||
* as if the client had sent us no sid to begin with, and make a new one.
|
||||
* The exception here is attempts to resume extended_master_secret
|
||||
* sessions without the extension, which causes an alert.
|
||||
*/
|
||||
if (sid != NULL) do {
|
||||
ssl3CipherSpec *pwSpec;
|
||||
|
@ -8199,6 +8335,30 @@ compression_found:
|
|||
break; /* not an error */
|
||||
}
|
||||
|
||||
/* [draft-ietf-tls-session-hash-06; Section 5.3]
|
||||
* o If the original session did not use the "extended_master_secret"
|
||||
* extension but the new ClientHello contains the extension, then the
|
||||
* server MUST NOT perform the abbreviated handshake. Instead, it
|
||||
* SHOULD continue with a full handshake (as described in
|
||||
* Section 5.2) to negotiate a new session.
|
||||
*
|
||||
* o If the original session used the "extended_master_secret"
|
||||
* extension but the new ClientHello does not contain the extension,
|
||||
* the server MUST abort the abbreviated handshake.
|
||||
*/
|
||||
if (ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
|
||||
if (!sid->u.ssl3.keys.extendedMasterSecretUsed) {
|
||||
break; /* not an error */
|
||||
}
|
||||
} else {
|
||||
if (sid->u.ssl3.keys.extendedMasterSecretUsed) {
|
||||
/* Note: we do not destroy the session */
|
||||
desc = handshake_failure;
|
||||
errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET;
|
||||
goto alert_loser;
|
||||
}
|
||||
}
|
||||
|
||||
if (ss->sec.ci.sid) {
|
||||
if (ss->sec.uncache)
|
||||
ss->sec.uncache(ss->sec.ci.sid);
|
||||
|
@ -8339,7 +8499,7 @@ compression_found:
|
|||
haveSpecWriteLock = PR_FALSE;
|
||||
}
|
||||
|
||||
/* NULL value for PMS signifies re-use of the old MS */
|
||||
/* NULL value for PMS because we are re-using the old MS */
|
||||
rv = ssl3_InitPendingCipherSpec(ss, NULL);
|
||||
if (rv != SECSuccess) {
|
||||
errCode = PORT_GetError();
|
||||
|
@ -8530,6 +8690,8 @@ compression_found:
|
|||
}
|
||||
ss->sec.ci.sid = sid;
|
||||
|
||||
sid->u.ssl3.keys.extendedMasterSecretUsed =
|
||||
ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn);
|
||||
ss->ssl3.hs.isResuming = PR_FALSE;
|
||||
ssl_GetXmitBufLock(ss);
|
||||
rv = ssl3_SendServerHelloSequence(ss);
|
||||
|
@ -9276,7 +9438,7 @@ ssl3_SendCertificateRequest(sslSocket *ss)
|
|||
int nnames = 0;
|
||||
int certTypesLength;
|
||||
PRUint8 sigAlgs[MAX_SIGNATURE_ALGORITHMS * 2];
|
||||
unsigned int sigAlgsLength;
|
||||
unsigned int sigAlgsLength = 0;
|
||||
|
||||
SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",
|
||||
SSL_GETPID(), ss->fd));
|
||||
|
@ -9540,18 +9702,17 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
|
|||
PRUint32 length,
|
||||
SECKEYPrivateKey *serverKey)
|
||||
{
|
||||
PK11SymKey * pms;
|
||||
#ifndef NO_PKCS11_BYPASS
|
||||
unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random;
|
||||
unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random;
|
||||
ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec;
|
||||
unsigned int outLen = 0;
|
||||
#endif
|
||||
PRBool isTLS = PR_FALSE;
|
||||
SECItem pmsItem = {siBuffer, NULL, 0};
|
||||
unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH];
|
||||
#endif
|
||||
SECStatus rv;
|
||||
SECItem enc_pms;
|
||||
unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH];
|
||||
SECItem pmsItem = {siBuffer, NULL, 0};
|
||||
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
|
||||
|
@ -9559,8 +9720,10 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
|
|||
|
||||
enc_pms.data = b;
|
||||
enc_pms.len = length;
|
||||
#ifndef NO_PKCS11_BYPASS
|
||||
pmsItem.data = rsaPmsBuf;
|
||||
pmsItem.len = sizeof rsaPmsBuf;
|
||||
#endif
|
||||
|
||||
if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
|
||||
PRInt32 kLen;
|
||||
|
@ -9572,13 +9735,24 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
|
|||
if ((unsigned)kLen < enc_pms.len) {
|
||||
enc_pms.len = kLen;
|
||||
}
|
||||
#ifndef NO_PKCS11_BYPASS
|
||||
isTLS = PR_TRUE;
|
||||
#endif
|
||||
} else {
|
||||
#ifndef NO_PKCS11_BYPASS
|
||||
isTLS = (PRBool)(ss->ssl3.hs.kea_def->tls_keygen != 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NO_PKCS11_BYPASS
|
||||
if (ss->opt.bypassPKCS11) {
|
||||
/* We have not implemented a tls_ExtendedMasterKeyDeriveBypass
|
||||
* and will not negotiate this extension in bypass mode. This
|
||||
* assert just double-checks that.
|
||||
*/
|
||||
PORT_Assert(
|
||||
!ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn));
|
||||
|
||||
/* TRIPLE BYPASS, get PMS directly from RSA decryption.
|
||||
* Use PK11_PrivDecryptPKCS1 to decrypt the PMS to a buffer,
|
||||
* then, check for version rollback attack, then
|
||||
|
@ -9606,8 +9780,8 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
|
|||
}
|
||||
}
|
||||
/* have PMS, build MS without PKCS11 */
|
||||
rv = ssl3_MasterKeyDeriveBypass(pwSpec, cr, sr, &pmsItem, isTLS,
|
||||
PR_TRUE);
|
||||
rv = ssl3_MasterSecretDeriveBypass(pwSpec, cr, sr, &pmsItem, isTLS,
|
||||
PR_TRUE);
|
||||
if (rv != SECSuccess) {
|
||||
pwSpec->msItem.data = pwSpec->raw_master_secret;
|
||||
pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH;
|
||||
|
@ -9617,46 +9791,107 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
|
|||
} else
|
||||
#endif
|
||||
{
|
||||
PK11SymKey *tmpPms[2] = {NULL, NULL};
|
||||
PK11SlotInfo *slot;
|
||||
int useFauxPms = 0;
|
||||
#define currentPms tmpPms[!useFauxPms]
|
||||
#define unusedPms tmpPms[useFauxPms]
|
||||
#define realPms tmpPms[1]
|
||||
#define fauxPms tmpPms[0]
|
||||
|
||||
#ifndef NO_PKCS11_BYPASS
|
||||
double_bypass:
|
||||
#endif
|
||||
/*
|
||||
* unwrap pms out of the incoming buffer
|
||||
* Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do
|
||||
* the unwrap. Rather, it is the mechanism with which the
|
||||
* unwrapped pms will be used.
|
||||
*/
|
||||
pms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
|
||||
CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
|
||||
if (pms != NULL) {
|
||||
PRINT_BUF(60, (ss, "decrypted premaster secret:",
|
||||
PK11_GetKeyData(pms)->data,
|
||||
PK11_GetKeyData(pms)->len));
|
||||
} else {
|
||||
/* unwrap failed. Generate a bogus PMS and carry on. */
|
||||
PK11SlotInfo * slot = PK11_GetSlotFromPrivateKey(serverKey);
|
||||
|
||||
ssl_GetSpecWriteLock(ss);
|
||||
pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot);
|
||||
ssl_ReleaseSpecWriteLock(ss);
|
||||
PK11_FreeSlot(slot);
|
||||
}
|
||||
/*
|
||||
* Get as close to algorithm 2 from RFC 5246; Section 7.4.7.1
|
||||
* as we can within the constraints of the PKCS#11 interface.
|
||||
*
|
||||
* 1. Unconditionally generate a bogus PMS (what RFC 5246
|
||||
* calls R).
|
||||
* 2. Attempt the RSA decryption to recover the PMS (what
|
||||
* RFC 5246 calls M).
|
||||
* 3. Set PMS = (M == NULL) ? R : M
|
||||
* 4. Use ssl3_ComputeMasterSecret(PMS) to attempt to derive
|
||||
* the MS from PMS. This includes performing the version
|
||||
* check and length check.
|
||||
* 5. If either the initial RSA decryption failed or
|
||||
* ssl3_ComputeMasterSecret(PMS) failed, then discard
|
||||
* M and set PMS = R. Else, discard R and set PMS = M.
|
||||
*
|
||||
* We do two derivations here because we can't rely on having
|
||||
* a function that only performs the PMS version and length
|
||||
* check. The only redundant cost is that this runs the PRF,
|
||||
* which isn't necessary here.
|
||||
*/
|
||||
|
||||
if (pms == NULL) {
|
||||
/* last gasp. */
|
||||
/* Generate the bogus PMS (R) */
|
||||
slot = PK11_GetSlotFromPrivateKey(serverKey);
|
||||
if (!slot) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (!PK11_DoesMechanism(slot, CKM_SSL3_MASTER_KEY_DERIVE)) {
|
||||
PK11_FreeSlot(slot);
|
||||
slot = PK11_GetBestSlot(CKM_SSL3_MASTER_KEY_DERIVE, NULL);
|
||||
if (!slot) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
ssl_GetSpecWriteLock(ss);
|
||||
fauxPms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot);
|
||||
ssl_ReleaseSpecWriteLock(ss);
|
||||
PK11_FreeSlot(slot);
|
||||
|
||||
if (fauxPms == NULL) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/*
|
||||
* unwrap pms out of the incoming buffer
|
||||
* Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do
|
||||
* the unwrap. Rather, it is the mechanism with which the
|
||||
* unwrapped pms will be used.
|
||||
*/
|
||||
realPms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
|
||||
CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
|
||||
/* Temporarily use the PMS if unwrapping the real PMS fails. */
|
||||
useFauxPms |= (realPms == NULL);
|
||||
|
||||
/* Attempt to derive the MS from the PMS. This is the only way to
|
||||
* check the version field in the RSA PMS. If this fails, we
|
||||
* then use the faux PMS in place of the PMS. Note that this
|
||||
* operation should never fail if we are using the faux PMS
|
||||
* since it is correctly formatted. */
|
||||
rv = ssl3_ComputeMasterSecret(ss, currentPms, NULL);
|
||||
|
||||
/* If we succeeded, then select the true PMS and discard the
|
||||
* FPMS. Else, select the FPMS and select the true PMS */
|
||||
useFauxPms |= (rv != SECSuccess);
|
||||
|
||||
if (unusedPms) {
|
||||
PK11_FreeSymKey(unusedPms);
|
||||
}
|
||||
|
||||
/* This step will derive the MS from the PMS, among other things. */
|
||||
rv = ssl3_InitPendingCipherSpec(ss, pms);
|
||||
PK11_FreeSymKey(pms);
|
||||
rv = ssl3_InitPendingCipherSpec(ss, currentPms);
|
||||
PK11_FreeSymKey(currentPms);
|
||||
}
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
SEND_ALERT
|
||||
return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
|
||||
}
|
||||
|
||||
#undef currentPms
|
||||
#undef unusedPms
|
||||
#undef realPms
|
||||
#undef fauxPms
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
|
@ -319,14 +319,6 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
|
|||
SECKEY_DestroyPrivateKey(privKey);
|
||||
privKey = NULL;
|
||||
|
||||
rv = ssl3_InitPendingCipherSpec(ss, pms);
|
||||
PK11_FreeSymKey(pms); pms = NULL;
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
|
||||
pubKey->u.ec.publicValue.len + 1);
|
||||
if (rv != SECSuccess) {
|
||||
|
@ -343,6 +335,14 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
|
|||
goto loser; /* err set by ssl3_AppendHandshake* */
|
||||
}
|
||||
|
||||
rv = ssl3_InitPendingCipherSpec(ss, pms);
|
||||
PK11_FreeSymKey(pms); pms = NULL;
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = SECSuccess;
|
||||
|
||||
loser:
|
||||
|
|
|
@ -91,6 +91,12 @@ static PRInt32 ssl3_ClientSendDraftVersionXtn(sslSocket *ss, PRBool append,
|
|||
PRUint32 maxBytes);
|
||||
static SECStatus ssl3_ServerHandleDraftVersionXtn(sslSocket *ss, PRUint16 ex_type,
|
||||
SECItem *data);
|
||||
static PRInt32 ssl3_SendExtendedMasterSecretXtn(sslSocket *ss, PRBool append,
|
||||
PRUint32 maxBytes);
|
||||
static SECStatus ssl3_HandleExtendedMasterSecretXtn(sslSocket *ss,
|
||||
PRUint16 ex_type,
|
||||
SECItem *data);
|
||||
|
||||
|
||||
/*
|
||||
* Write bytes. Using this function means the SECItem structure
|
||||
|
@ -256,6 +262,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
|
|||
{ ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
|
||||
{ ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
|
||||
{ ssl_tls13_draft_version_xtn, &ssl3_ServerHandleDraftVersionXtn },
|
||||
{ ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
|
@ -270,6 +277,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
|
|||
{ ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn },
|
||||
{ ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
|
||||
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
|
||||
{ ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
|
@ -299,6 +307,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
|
|||
{ ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
|
||||
{ ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
|
||||
{ ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn },
|
||||
{ ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn},
|
||||
/* any extra entries will appear as { 0, NULL } */
|
||||
};
|
||||
|
||||
|
@ -1182,6 +1191,7 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
|||
+ cert_length /* cert */
|
||||
+ 1 /* server name type */
|
||||
+ srvNameLen /* name len + length field */
|
||||
+ 1 /* extendedMasterSecretUsed */
|
||||
+ sizeof(ticket.ticket_lifetime_hint);
|
||||
padding_length = AES_BLOCK_SIZE -
|
||||
(ciphertext_length % AES_BLOCK_SIZE);
|
||||
|
@ -1280,6 +1290,11 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
|||
if (rv != SECSuccess) goto loser;
|
||||
}
|
||||
|
||||
/* extendedMasterSecretUsed */
|
||||
rv = ssl3_AppendNumberToItem(
|
||||
&plaintext, ss->sec.ci.sid->u.ssl3.keys.extendedMasterSecretUsed, 1);
|
||||
if (rv != SECSuccess) goto loser;
|
||||
|
||||
PORT_Assert(plaintext.len == padding_length);
|
||||
for (i = 0; i < padding_length; i++)
|
||||
plaintext.data[i] = (unsigned char)padding_length;
|
||||
|
@ -1637,9 +1652,10 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
|||
goto loser;
|
||||
}
|
||||
|
||||
/* Read ticket_version (which is ignored for now.) */
|
||||
/* Read ticket_version and reject if the version is wrong */
|
||||
temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
|
||||
if (temp < 0) goto no_ticket;
|
||||
if (temp != TLS_EX_SESS_TICKET_VERSION) goto no_ticket;
|
||||
|
||||
parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp;
|
||||
|
||||
/* Read SSLVersion. */
|
||||
|
@ -1740,6 +1756,13 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
|||
parsed_session_ticket->srvName.type = nameType;
|
||||
}
|
||||
|
||||
/* Read extendedMasterSecretUsed */
|
||||
temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
|
||||
if (temp < 0)
|
||||
goto no_ticket;
|
||||
PORT_Assert(temp == PR_TRUE || temp == PR_FALSE);
|
||||
parsed_session_ticket->extendedMasterSecretUsed = (PRBool)temp;
|
||||
|
||||
/* Done parsing. Check that all bytes have been consumed. */
|
||||
if (buffer_len != padding_length)
|
||||
goto no_ticket;
|
||||
|
@ -1786,6 +1809,8 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
|||
parsed_session_ticket->ms_is_wrapped;
|
||||
sid->u.ssl3.masterValid = PR_TRUE;
|
||||
sid->u.ssl3.keys.resumable = PR_TRUE;
|
||||
sid->u.ssl3.keys.extendedMasterSecretUsed = parsed_session_ticket->
|
||||
extendedMasterSecretUsed;
|
||||
|
||||
/* Copy over client cert from session ticket if there is one. */
|
||||
if (parsed_session_ticket->peer_cert.data != NULL) {
|
||||
|
@ -2559,3 +2584,90 @@ ssl3_ServerHandleDraftVersionXtn(sslSocket * ss, PRUint16 ex_type,
|
|||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static PRInt32
|
||||
ssl3_SendExtendedMasterSecretXtn(sslSocket * ss, PRBool append,
|
||||
PRUint32 maxBytes)
|
||||
{
|
||||
PRInt32 extension_length;
|
||||
|
||||
if (!ss->opt.enableExtendedMS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NO_PKCS11_BYPASS
|
||||
/* Extended MS can only be used w/o bypass mode */
|
||||
if (ss->opt.bypassPKCS11) {
|
||||
PORT_Assert(0);
|
||||
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Always send the extension in this function, since the
|
||||
* client always sends it and this function is only called on
|
||||
* the server if we negotiated the extension. */
|
||||
extension_length = 4; /* Type + length (0) */
|
||||
if (maxBytes < extension_length) {
|
||||
PORT_Assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (append) {
|
||||
SECStatus rv;
|
||||
rv = ssl3_AppendHandshakeNumber(ss, ssl_extended_master_secret_xtn, 2);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
||||
ssl_extended_master_secret_xtn;
|
||||
}
|
||||
|
||||
return extension_length;
|
||||
|
||||
loser:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static SECStatus
|
||||
ssl3_HandleExtendedMasterSecretXtn(sslSocket * ss, PRUint16 ex_type,
|
||||
SECItem *data)
|
||||
{
|
||||
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_0) {
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
if (!ss->opt.enableExtendedMS) {
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
#ifndef NO_PKCS11_BYPASS
|
||||
/* Extended MS can only be used w/o bypass mode */
|
||||
if (ss->opt.bypassPKCS11) {
|
||||
PORT_Assert(0);
|
||||
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data->len != 0) {
|
||||
SSL_TRC(30, ("%d: SSL3[%d]: Bogus extended master secret extension",
|
||||
SSL_GETPID(), ss->fd));
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SSL_DBG(("%d: SSL[%d]: Negotiated extended master secret extension.",
|
||||
SSL_GETPID(), ss->fd));
|
||||
|
||||
/* Keep track of negotiated extensions. */
|
||||
ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
|
||||
|
||||
if (ss->sec.isServer) {
|
||||
return ssl3_RegisterServerHelloExtensionSender(
|
||||
ss, ex_type, ssl3_SendExtendedMasterSecretXtn);
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
|
@ -205,6 +205,9 @@ SSL_ERROR_RX_SHORT_DTLS_READ = (SSL_ERROR_BASE + 133),
|
|||
SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 134),
|
||||
SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 135),
|
||||
|
||||
SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 136),
|
||||
SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 137),
|
||||
|
||||
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
|
||||
} SSLErrorCodes;
|
||||
#endif /* NO_SECURITY_ERROR_ENUM */
|
||||
|
|
|
@ -347,6 +347,7 @@ typedef struct sslOptionsStr {
|
|||
unsigned int reuseServerECDHEKey : 1; /* 28 */
|
||||
unsigned int enableFallbackSCSV : 1; /* 29 */
|
||||
unsigned int enableServerDhe : 1; /* 30 */
|
||||
unsigned int enableExtendedMS : 1; /* 31 */
|
||||
} sslOptions;
|
||||
|
||||
typedef enum { sslHandshakingUndetermined = 0,
|
||||
|
@ -520,6 +521,7 @@ typedef struct {
|
|||
PRUint16 wrapped_master_secret_len;
|
||||
PRUint8 msIsWrapped;
|
||||
PRUint8 resumable;
|
||||
PRUint8 extendedMasterSecretUsed;
|
||||
} ssl3SidKeys; /* 52 bytes */
|
||||
|
||||
typedef struct {
|
||||
|
@ -1073,6 +1075,7 @@ typedef struct SessionTicketStr {
|
|||
CK_MECHANISM_TYPE msWrapMech;
|
||||
PRUint16 ms_length;
|
||||
SSL3Opaque master_secret[48];
|
||||
PRBool extendedMasterSecretUsed;
|
||||
ClientIdentity client_identity;
|
||||
SECItem peer_cert;
|
||||
PRUint32 timestamp;
|
||||
|
@ -1598,7 +1601,7 @@ extern PRBool ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
|
|||
extern SECStatus ssl3_KeyAndMacDeriveBypass(ssl3CipherSpec * pwSpec,
|
||||
const unsigned char * cr, const unsigned char * sr,
|
||||
PRBool isTLS, PRBool isExport);
|
||||
extern SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec,
|
||||
extern SECStatus ssl3_MasterSecretDeriveBypass( ssl3CipherSpec * pwSpec,
|
||||
const unsigned char * cr, const unsigned char * sr,
|
||||
const SECItem * pms, PRBool isTLS, PRBool isRSA);
|
||||
|
||||
|
@ -1849,7 +1852,7 @@ extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
|
|||
|
||||
/* Tell clients to consider tickets valid for this long. */
|
||||
#define TLS_EX_SESS_TICKET_LIFETIME_HINT (2 * 24 * 60 * 60) /* 2 days */
|
||||
#define TLS_EX_SESS_TICKET_VERSION (0x0100)
|
||||
#define TLS_EX_SESS_TICKET_VERSION (0x0101)
|
||||
|
||||
extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data,
|
||||
unsigned int length);
|
||||
|
|
|
@ -67,6 +67,8 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
|
|||
inf.creationTime = sid->creationTime;
|
||||
inf.lastAccessTime = sid->lastAccessTime;
|
||||
inf.expirationTime = sid->expirationTime;
|
||||
inf.extendedMasterSecretUsed = sid->u.ssl3.keys.extendedMasterSecretUsed;
|
||||
|
||||
if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
|
||||
inf.sessionIDLength = SSL2_SESSIONID_BYTES;
|
||||
memcpy(inf.sessionID, sid->u.ssl2.sessionID,
|
||||
|
|
|
@ -120,14 +120,14 @@ struct sidCacheEntryStr {
|
|||
/* 2 */ ssl3CipherSuite cipherSuite;
|
||||
/* 2 */ PRUint16 compression; /* SSLCompressionMethod */
|
||||
|
||||
/* 52 */ ssl3SidKeys keys; /* keys, wrapped as needed. */
|
||||
/* 54 */ ssl3SidKeys keys; /* keys, wrapped as needed. */
|
||||
|
||||
/* 4 */ PRUint32 masterWrapMech;
|
||||
/* 4 */ SSL3KEAType exchKeyType;
|
||||
/* 4 */ PRInt32 certIndex;
|
||||
/* 4 */ PRInt32 srvNameIndex;
|
||||
/* 32 */ PRUint8 srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */
|
||||
/*104 */} ssl3;
|
||||
/*108 */} ssl3;
|
||||
/* force sizeof(sidCacheEntry) to be a multiple of cache line size */
|
||||
struct {
|
||||
/*120 */ PRUint8 filler[120]; /* 72+120==192, a multiple of 16 */
|
||||
|
@ -507,7 +507,6 @@ ConvertFromSID(sidCacheEntry *to, sslSessionID *from)
|
|||
to->sessionIDLength = from->u.ssl3.sessionIDLength;
|
||||
to->u.ssl3.certIndex = -1;
|
||||
to->u.ssl3.srvNameIndex = -1;
|
||||
|
||||
PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID,
|
||||
to->sessionIDLength);
|
||||
|
||||
|
@ -637,7 +636,7 @@ ConvertToSID(sidCacheEntry * from,
|
|||
to->authKeyBits = from->authKeyBits;
|
||||
to->keaType = from->keaType;
|
||||
to->keaKeyBits = from->keaKeyBits;
|
||||
|
||||
|
||||
return to;
|
||||
|
||||
loser:
|
||||
|
@ -1027,10 +1026,6 @@ CloseCache(cacheDesc *cache)
|
|||
memset(cache, 0, sizeof *cache);
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
static SECStatus
|
||||
InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
|
||||
int maxSrvNameCacheEntries, PRUint32 ssl2_timeout,
|
||||
|
@ -1232,20 +1227,32 @@ InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
|
|||
/* Fix pointers in our private copy of cache descriptor to point to
|
||||
** spaces in shared memory
|
||||
*/
|
||||
ptr = (ptrdiff_t)cache->cacheMem;
|
||||
*(ptrdiff_t *)(&cache->sidCacheLocks) += ptr;
|
||||
*(ptrdiff_t *)(&cache->keyCacheLock ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->certCacheLock) += ptr;
|
||||
*(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr;
|
||||
*(ptrdiff_t *)(&cache->sidCacheSets ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->sidCacheData ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->certCacheData) += ptr;
|
||||
*(ptrdiff_t *)(&cache->keyCacheData ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr;
|
||||
*(ptrdiff_t *)(&cache->ticketEncKey ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->ticketMacKey ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->ticketKeysValid) += ptr;
|
||||
*(ptrdiff_t *)(&cache->srvNameCacheData) += ptr;
|
||||
cache->sidCacheLocks = (sidCacheLock *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->sidCacheLocks);
|
||||
cache->keyCacheLock = (sidCacheLock *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->keyCacheLock);
|
||||
cache->certCacheLock = (sidCacheLock *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->certCacheLock);
|
||||
cache->srvNameCacheLock = (sidCacheLock *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->srvNameCacheLock);
|
||||
cache->sidCacheSets = (sidCacheSet *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->sidCacheSets);
|
||||
cache->sidCacheData = (sidCacheEntry *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->sidCacheData);
|
||||
cache->certCacheData = (certCacheEntry *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->certCacheData);
|
||||
cache->keyCacheData = (SSLWrappedSymWrappingKey *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->keyCacheData);
|
||||
cache->ticketKeyNameSuffix = (PRUint8 *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix);
|
||||
cache->ticketEncKey = (encKeyCacheEntry *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->ticketEncKey);
|
||||
cache->ticketMacKey = (encKeyCacheEntry *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->ticketMacKey);
|
||||
cache->ticketKeysValid = (PRUint32 *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->ticketKeysValid);
|
||||
cache->srvNameCacheData = (srvNameCacheEntry *)
|
||||
(cache->cacheMem + (ptrdiff_t)cache->srvNameCacheData);
|
||||
|
||||
/* initialize the locks */
|
||||
init_time = ssl_Time();
|
||||
|
@ -1270,9 +1277,6 @@ loser:
|
|||
CloseCache(cache);
|
||||
return SECFailure;
|
||||
}
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
PRUint32
|
||||
SSL_GetMaxServerCacheLocks(void)
|
||||
|
@ -1491,7 +1495,6 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
|
|||
char * fmString = NULL;
|
||||
char * myEnvString = NULL;
|
||||
unsigned int decoLen;
|
||||
ptrdiff_t ptr;
|
||||
inheritance inherit;
|
||||
cacheDesc my;
|
||||
#ifdef WINNT
|
||||
|
@ -1587,20 +1590,32 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
|
|||
/* Fix pointers in our private copy of cache descriptor to point to
|
||||
** spaces in shared memory, whose address is now in "my".
|
||||
*/
|
||||
ptr = (ptrdiff_t)my.cacheMem;
|
||||
*(ptrdiff_t *)(&cache->sidCacheLocks) += ptr;
|
||||
*(ptrdiff_t *)(&cache->keyCacheLock ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->certCacheLock) += ptr;
|
||||
*(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr;
|
||||
*(ptrdiff_t *)(&cache->sidCacheSets ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->sidCacheData ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->certCacheData) += ptr;
|
||||
*(ptrdiff_t *)(&cache->keyCacheData ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr;
|
||||
*(ptrdiff_t *)(&cache->ticketEncKey ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->ticketMacKey ) += ptr;
|
||||
*(ptrdiff_t *)(&cache->ticketKeysValid) += ptr;
|
||||
*(ptrdiff_t *)(&cache->srvNameCacheData) += ptr;
|
||||
cache->sidCacheLocks = (sidCacheLock *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->sidCacheLocks);
|
||||
cache->keyCacheLock = (sidCacheLock *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->keyCacheLock);
|
||||
cache->certCacheLock = (sidCacheLock *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->certCacheLock);
|
||||
cache->srvNameCacheLock = (sidCacheLock *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->srvNameCacheLock);
|
||||
cache->sidCacheSets = (sidCacheSet *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->sidCacheSets);
|
||||
cache->sidCacheData = (sidCacheEntry *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->sidCacheData);
|
||||
cache->certCacheData = (certCacheEntry *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->certCacheData);
|
||||
cache->keyCacheData = (SSLWrappedSymWrappingKey *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->keyCacheData);
|
||||
cache->ticketKeyNameSuffix = (PRUint8 *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix);
|
||||
cache->ticketEncKey = (encKeyCacheEntry *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->ticketEncKey);
|
||||
cache->ticketMacKey = (encKeyCacheEntry *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->ticketMacKey);
|
||||
cache->ticketKeysValid = (PRUint32 *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->ticketKeysValid);
|
||||
cache->srvNameCacheData = (srvNameCacheEntry *)
|
||||
(my.cacheMem + (ptrdiff_t)cache->srvNameCacheData);
|
||||
|
||||
cache->cacheMemMap = my.cacheMemMap;
|
||||
cache->cacheMem = my.cacheMem;
|
||||
|
|
|
@ -85,6 +85,7 @@ static sslOptions ssl_defaults = {
|
|||
PR_TRUE, /* reuseServerECDHEKey */
|
||||
PR_FALSE, /* enableFallbackSCSV */
|
||||
PR_TRUE, /* enableServerDhe */
|
||||
PR_FALSE /* enableExtendedMS */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -825,6 +826,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
|
|||
ss->opt.enableServerDhe = on;
|
||||
break;
|
||||
|
||||
case SSL_ENABLE_EXTENDED_MASTER_SECRET:
|
||||
ss->opt.enableExtendedMS = on;
|
||||
break;
|
||||
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
rv = SECFailure;
|
||||
|
@ -901,6 +906,8 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
|
|||
on = ss->opt.reuseServerECDHEKey; break;
|
||||
case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break;
|
||||
case SSL_ENABLE_SERVER_DHE: on = ss->opt.enableServerDhe; break;
|
||||
case SSL_ENABLE_EXTENDED_MASTER_SECRET:
|
||||
on = ss->opt.enableExtendedMS; break;
|
||||
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
|
@ -973,6 +980,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
|
|||
case SSL_ENABLE_SERVER_DHE:
|
||||
on = ssl_defaults.enableServerDhe;
|
||||
break;
|
||||
case SSL_ENABLE_EXTENDED_MASTER_SECRET:
|
||||
on = ssl_defaults.enableExtendedMS;
|
||||
break;
|
||||
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
|
@ -1160,6 +1170,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
|
|||
ssl_defaults.enableServerDhe = on;
|
||||
break;
|
||||
|
||||
case SSL_ENABLE_EXTENDED_MASTER_SECRET:
|
||||
ssl_defaults.enableExtendedMS = on;
|
||||
break;
|
||||
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
|
|
|
@ -146,6 +146,12 @@ typedef struct SSLChannelInfoStr {
|
|||
/* compression method info */
|
||||
const char * compressionMethodName;
|
||||
SSLCompressionMethod compressionMethod;
|
||||
|
||||
/* The following fields are added in NSS 3.21.
|
||||
* This field only has meaning in TLS < 1.3 and will be set to
|
||||
* PR_FALSE in TLS 1.3.
|
||||
*/
|
||||
PRBool extendedMasterSecretUsed;
|
||||
} SSLChannelInfo;
|
||||
|
||||
/* Preliminary channel info */
|
||||
|
@ -230,13 +236,14 @@ typedef enum {
|
|||
ssl_use_srtp_xtn = 14,
|
||||
ssl_app_layer_protocol_xtn = 16,
|
||||
ssl_padding_xtn = 21,
|
||||
ssl_extended_master_secret_xtn = 23,
|
||||
ssl_session_ticket_xtn = 35,
|
||||
ssl_next_proto_nego_xtn = 13172,
|
||||
ssl_renegotiation_info_xtn = 0xff01,
|
||||
ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */
|
||||
} SSLExtensionType;
|
||||
|
||||
#define SSL_MAX_EXTENSIONS 11 /* doesn't include ssl_padding_xtn. */
|
||||
#define SSL_MAX_EXTENSIONS 12 /* doesn't include ssl_padding_xtn. */
|
||||
|
||||
typedef enum {
|
||||
ssl_dhe_group_none = 0,
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
/*
|
||||
* NSS-defined object classes
|
||||
*
|
||||
*
|
||||
*/
|
||||
#define CKO_NSS (CKO_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
|
||||
|
||||
|
@ -166,7 +166,7 @@
|
|||
#define CKM_NSS_JPAKE_ROUND1_SHA512 (CKM_NSS + 10)
|
||||
|
||||
/* J-PAKE round 2 key derivation mechanisms.
|
||||
*
|
||||
*
|
||||
* Required template attributes: CKA_NSS_JPAKE_PEERID
|
||||
* Input key type: CKK_NSS_JPAKE_ROUND1
|
||||
* Output key type: CKK_NSS_JPAKE_ROUND2
|
||||
|
@ -178,14 +178,14 @@
|
|||
#define CKM_NSS_JPAKE_ROUND2_SHA384 (CKM_NSS + 13)
|
||||
#define CKM_NSS_JPAKE_ROUND2_SHA512 (CKM_NSS + 14)
|
||||
|
||||
/* J-PAKE final key material derivation mechanisms
|
||||
/* J-PAKE final key material derivation mechanisms
|
||||
*
|
||||
* Input key type: CKK_NSS_JPAKE_ROUND2
|
||||
* Output key type: CKK_GENERIC_SECRET
|
||||
* Output key class: CKO_SECRET_KEY
|
||||
* Parameter type: CK_NSS_JPAKEFinalParams
|
||||
*
|
||||
* You must apply a KDF (e.g. CKM_NSS_HKDF_*) to resultant keying material
|
||||
* You must apply a KDF (e.g. CKM_NSS_HKDF_*) to resultant keying material
|
||||
* to get a key with uniformly distributed bits.
|
||||
*/
|
||||
#define CKM_NSS_JPAKE_FINAL_SHA1 (CKM_NSS + 15)
|
||||
|
@ -216,6 +216,10 @@
|
|||
#define CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256 (CKM_NSS + 23)
|
||||
#define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
|
||||
|
||||
/* TLS extended master secret derivation */
|
||||
#define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE (CKM_NSS + 25)
|
||||
#define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH (CKM_NSS + 26)
|
||||
|
||||
/*
|
||||
* HISTORICAL:
|
||||
* Do not attempt to use these. They are only used by NETSCAPE's internal
|
||||
|
@ -294,7 +298,7 @@ typedef struct CK_NSS_MAC_CONSTANT_TIME_PARAMS {
|
|||
|
||||
/* Mandatory parameter for the CKM_NSS_HKDF_* key deriviation mechanisms.
|
||||
See RFC 5869.
|
||||
|
||||
|
||||
bExtract: If set, HKDF-Extract will be applied to the input key. If
|
||||
the optional salt is given, it is used; otherwise, the salt is
|
||||
set to a sequence of zeros equal in length to the HMAC output.
|
||||
|
@ -319,6 +323,31 @@ typedef struct CK_NSS_HKDFParams {
|
|||
CK_ULONG ulInfoLen;
|
||||
} CK_NSS_HKDFParams;
|
||||
|
||||
/*
|
||||
* Parameter for the TLS extended master secret key derivation mechanisms:
|
||||
*
|
||||
* * CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE
|
||||
* * CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH
|
||||
*
|
||||
* For the TLS 1.2 PRF, the prfHashMechanism parameter determines the hash
|
||||
* function used. For earlier versions of the PRF, set the prfHashMechanism
|
||||
* value to CKM_TLS_PRF.
|
||||
*
|
||||
* The session hash input is expected to be the output of the same hash
|
||||
* function as the PRF uses (as required by draft-ietf-tls-session-hash). So
|
||||
* the ulSessionHashLen member must be equal the output length of the hash
|
||||
* function specified by the prfHashMechanism member (or, for pre-TLS 1.2 PRF,
|
||||
* the length of concatenated MD5 and SHA-1 digests).
|
||||
*
|
||||
*/
|
||||
typedef struct CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS {
|
||||
CK_MECHANISM_TYPE prfHashMechanism;
|
||||
CK_BYTE_PTR pSessionHash;
|
||||
CK_ULONG ulSessionHashLen;
|
||||
CK_VERSION_PTR pVersion;
|
||||
} CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS;
|
||||
|
||||
|
||||
/*
|
||||
* Trust info
|
||||
*
|
||||
|
@ -343,7 +372,7 @@ typedef CK_ULONG CK_TRUST;
|
|||
#define CKT_NSS_NOT_TRUSTED (CKT_NSS + 10)
|
||||
#define CKT_NSS_TRUST_UNKNOWN (CKT_NSS + 5) /* default */
|
||||
|
||||
/*
|
||||
/*
|
||||
* These may well remain NSS-specific; I'm only using them
|
||||
* to cache resolution data.
|
||||
*/
|
||||
|
@ -454,7 +483,7 @@ typedef CK_TRUST __CKT_NSS_MUST_VERIFY __attribute__((deprecated
|
|||
#define SECMOD_MODULE_DB_FUNCTION_FIND 0
|
||||
#define SECMOD_MODULE_DB_FUNCTION_ADD 1
|
||||
#define SECMOD_MODULE_DB_FUNCTION_DEL 2
|
||||
#define SECMOD_MODULE_DB_FUNCTION_RELEASE 3
|
||||
#define SECMOD_MODULE_DB_FUNCTION_RELEASE 3
|
||||
typedef char ** (PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function,
|
||||
char *parameters, void *moduleSpec);
|
||||
|
||||
|
|
|
@ -87,8 +87,14 @@ extern char *PORT_ArenaStrdup(PLArenaPool *arena, const char *str);
|
|||
SEC_END_PROTOS
|
||||
|
||||
#define PORT_Assert PR_ASSERT
|
||||
/* This runs a function that should return SECSuccess. */
|
||||
/* The value is asserted in a debug build, otherwise it is ignored. */
|
||||
/* This runs a function that should return SECSuccess.
|
||||
* Intended for NSS internal use only.
|
||||
* The return value is asserted in a debug build, otherwise it is ignored.
|
||||
* This is no substitute for proper error handling. It is OK only if you
|
||||
* have ensured that the function cannot fail by other means such as checking
|
||||
* prerequisites. In that case this can be used as a safeguard against
|
||||
* unexpected changes in a function.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
#define PORT_CheckSuccess(f) PR_ASSERT((f) == SECSuccess)
|
||||
#else
|
||||
|
|
|
@ -75,14 +75,15 @@
|
|||
|
||||
/*
|
||||
* Smart string cat functions. Automatically manage the memory.
|
||||
* The first parameter is the source string. If it's null, we
|
||||
* The first parameter is the destination string. If it's null, we
|
||||
* allocate memory for it. If it's not, we reallocate memory
|
||||
* so the the concanenated string fits.
|
||||
*/
|
||||
static char *
|
||||
nssutil_DupnCat(char *baseString, const char *str, int str_len)
|
||||
{
|
||||
int len = (baseString ? PORT_Strlen(baseString) : 0) + 1;
|
||||
int baseStringLen = baseString ? PORT_Strlen(baseString) : 0;
|
||||
int len = baseStringLen + 1;
|
||||
char *newString;
|
||||
|
||||
len += str_len;
|
||||
|
@ -91,8 +92,9 @@ nssutil_DupnCat(char *baseString, const char *str, int str_len)
|
|||
PORT_Free(baseString);
|
||||
return NULL;
|
||||
}
|
||||
if (baseString == NULL) *newString = 0;
|
||||
return PORT_Strncat(newString,str, str_len);
|
||||
PORT_Memcpy(&newString[baseStringLen], str, str_len);
|
||||
newString[len - 1] = 0;
|
||||
return newString;
|
||||
}
|
||||
|
||||
/* Same as nssutil_DupnCat except it concatenates the full string, not a
|
||||
|
@ -480,7 +482,7 @@ nssutil_DeleteSecmodDBEntry(const char *appName,
|
|||
char *block = NULL;
|
||||
char *name = NULL;
|
||||
char *lib = NULL;
|
||||
int name_len, lib_len = 0;
|
||||
int name_len = 0, lib_len = 0;
|
||||
PRBool skip = PR_FALSE;
|
||||
PRBool found = PR_FALSE;
|
||||
|
||||
|
|
|
@ -32,10 +32,10 @@ if [ -z "${CLEANUP}" -o "${CLEANUP}" = "${SCRIPTNAME}" ]; then
|
|||
echo "--------------"
|
||||
LINES_CNT=$(cat ${RESULTS} | grep ">Passed<" | wc -l | sed s/\ *//)
|
||||
echo "Passed: ${LINES_CNT}"
|
||||
LINES_CNT=$(cat ${RESULTS} | grep ">Failed<" | wc -l | sed s/\ *//)
|
||||
echo "Failed: ${LINES_CNT}"
|
||||
LINES_CNT=$(cat ${RESULTS} | grep ">Failed Core<" | wc -l | sed s/\ *//)
|
||||
echo "Failed with core: ${LINES_CNT}"
|
||||
FAILED_CNT=$(cat ${RESULTS} | grep ">Failed<" | wc -l | sed s/\ *//)
|
||||
echo "Failed: ${FAILED_CNT}"
|
||||
CORE_CNT=$(cat ${RESULTS} | grep ">Failed Core<" | wc -l | sed s/\ *//)
|
||||
echo "Failed with core: ${CORE_CNT}"
|
||||
LINES_CNT=$(cat ${RESULTS} | grep ">Unknown<" | wc -l | sed s/\ *//)
|
||||
echo "Unknown status: ${LINES_CNT}"
|
||||
if [ ${LINES_CNT} -gt 0 ]; then
|
||||
|
@ -46,4 +46,8 @@ if [ -z "${CLEANUP}" -o "${CLEANUP}" = "${SCRIPTNAME}" ]; then
|
|||
html "END_OF_TEST<BR>"
|
||||
html "</BODY></HTML>"
|
||||
rm -f ${TEMPFILES} 2>/dev/null
|
||||
if [ ${FAILED_CNT} -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fi
|
||||
|
|
Loading…
Reference in New Issue