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:
Roy Tam 2020-01-07 15:11:52 +08:00
parent b1bbd767b3
commit 430790c1b1
46 changed files with 969 additions and 346 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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':

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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)))

View File

@ -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);
}

View File

@ -911,7 +911,7 @@ hash_seq(
uint flag)
{
register uint32 bucket;
register BUFHEAD *bufp;
register BUFHEAD *bufp = NULL;
HTAB *hashp;
uint16 *bp, ndx;

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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. */

View File

@ -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;

View File

@ -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. */

View File

@ -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)))

View File

@ -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

View File

@ -730,7 +730,7 @@ pkix_pl_LdapResponse_GetResultCode(
resultMsg = &response->decoded.protocolOp.op.searchResponseResultMsg;
*pResultCode = *(char *)(resultMsg->resultCode.data);
*pResultCode = *(resultMsg->resultCode.data);
cleanup:

View File

@ -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 */

View File

@ -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:

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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:

View File

@ -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;

View File

@ -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")

View File

@ -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,

View File

@ -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);

View File

@ -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,
&params, 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, &params, 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, &params, 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, &params,
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, &params,
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;
}

View File

@ -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:

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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