mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 858231: Update NSS to NSS 3.15 Beta 5. r=wtc.
Inclues fixes for bug 869262, bug 863947, bug 866362, bug 863871, and bug 808217.
This commit is contained in:
parent
bf68457834
commit
fe7a4f9783
@ -1 +1 @@
|
||||
NSS_3_15_BETA4
|
||||
NSS_3_15_BETA5
|
||||
|
@ -1033,8 +1033,7 @@ misalignBuffer(PLArenaPool *arena, bltestIO *io, int off)
|
||||
ptrdiff_t offset = (ptrdiff_t)io->buf.data % WORDSIZE;
|
||||
int length = io->buf.len;
|
||||
if (offset != off) {
|
||||
SECITEM_ReallocItem(arena, &io->buf, length, length + 2*WORDSIZE);
|
||||
io->buf.len = length + 2*WORDSIZE; /* why doesn't realloc do this? */
|
||||
SECITEM_ReallocItemV2(arena, &io->buf, length + 2*WORDSIZE);
|
||||
/* offset may have changed? */
|
||||
offset = (ptrdiff_t)io->buf.data % WORDSIZE;
|
||||
if (offset != off) {
|
||||
|
@ -530,7 +530,7 @@ SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii)
|
||||
}
|
||||
} else {
|
||||
/* need one additional byte for zero terminator */
|
||||
rv = SECITEM_ReallocItem(NULL, &filedata, filedata.len, filedata.len+1);
|
||||
rv = SECITEM_ReallocItemV2(NULL, &filedata, filedata.len+1);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_Free(filedata.data);
|
||||
return rv;
|
||||
|
@ -92,7 +92,7 @@ static enum ocspStaplingModeEnum {
|
||||
} ocspStaplingMode = osm_disabled;
|
||||
typedef enum ocspStaplingModeEnum ocspStaplingModeType;
|
||||
static char *ocspStaplingCA = NULL;
|
||||
CERTCertificate * certForStatusWeakReference = NULL;
|
||||
static SECItemArray *certStatus[kt_kea_size] = { NULL };
|
||||
|
||||
const int ssl2CipherSuites[] = {
|
||||
SSL_EN_RC4_128_WITH_MD5, /* A */
|
||||
@ -1108,7 +1108,7 @@ makeCorruptedOCSPResponse(PLArenaPool *arena)
|
||||
|
||||
SECItemArray *
|
||||
makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm,
|
||||
PRFileDesc *model_sock, CERTCertificate *cert)
|
||||
CERTCertificate *cert, secuPWData *pwdata)
|
||||
{
|
||||
SECItemArray *result = NULL;
|
||||
SECItem *ocspResponse = NULL;
|
||||
@ -1118,9 +1118,8 @@ makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm,
|
||||
CERTCertificate *ca;
|
||||
PRTime now = PR_Now();
|
||||
PRTime nextUpdate;
|
||||
secuPWData *pwdata;
|
||||
|
||||
PORT_Assert(model_sock != NULL && cert != NULL);
|
||||
PORT_Assert(cert != NULL);
|
||||
|
||||
ca = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), ocspStaplingCA);
|
||||
if (!ca)
|
||||
@ -1164,8 +1163,6 @@ makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm,
|
||||
singleResponses[0] = sr;
|
||||
singleResponses[1] = NULL;
|
||||
|
||||
pwdata = SSL_RevealPinArg(model_sock);
|
||||
|
||||
ocspResponse = CERT_CreateEncodedOCSPSuccessResponse(arena,
|
||||
(osm == osm_badsig) ? NULL : ca,
|
||||
ocspResponderID_byName, now, singleResponses,
|
||||
@ -1189,6 +1186,53 @@ makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm,
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
setupCertStatus(PLArenaPool *arena, enum ocspStaplingModeEnum ocspStaplingMode,
|
||||
CERTCertificate *cert, SSLKEAType kea, secuPWData *pwdata)
|
||||
{
|
||||
if (ocspStaplingMode == osm_random) {
|
||||
/* 6 different responses */
|
||||
int r = rand() % 6;
|
||||
switch (r) {
|
||||
case 0: ocspStaplingMode = osm_good; break;
|
||||
case 1: ocspStaplingMode = osm_revoked; break;
|
||||
case 2: ocspStaplingMode = osm_unknown; break;
|
||||
case 3: ocspStaplingMode = osm_badsig; break;
|
||||
case 4: ocspStaplingMode = osm_corrupted; break;
|
||||
case 5: ocspStaplingMode = osm_failure; break;
|
||||
default: PORT_Assert(0); break;
|
||||
}
|
||||
}
|
||||
if (ocspStaplingMode != osm_disabled) {
|
||||
SECItemArray *multiOcspResponses = NULL;
|
||||
switch (ocspStaplingMode) {
|
||||
case osm_good:
|
||||
case osm_revoked:
|
||||
case osm_unknown:
|
||||
case osm_badsig:
|
||||
multiOcspResponses =
|
||||
makeSignedOCSPResponse(arena, ocspStaplingMode, cert,
|
||||
pwdata);
|
||||
break;
|
||||
case osm_corrupted:
|
||||
multiOcspResponses = makeCorruptedOCSPResponse(arena);
|
||||
break;
|
||||
case osm_failure:
|
||||
multiOcspResponses = makeTryLaterOCSPResponse(arena);
|
||||
break;
|
||||
case osm_ocsp:
|
||||
errExit("stapling mode \"ocsp\" not implemented");
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (multiOcspResponses) {
|
||||
certStatus[kea] = multiOcspResponses;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
handle_connection(
|
||||
PRFileDesc *tcp_sock,
|
||||
@ -1216,8 +1260,7 @@ handle_connection(
|
||||
char fileName[513];
|
||||
char proto[128];
|
||||
PRDescIdentity aboveLayer = PR_INVALID_IO_LAYER;
|
||||
PLArenaPool *arena = NULL;
|
||||
ocspStaplingModeType osm;
|
||||
SSLKEAType kea;
|
||||
|
||||
pBuf = buf;
|
||||
bufRem = sizeof buf;
|
||||
@ -1244,57 +1287,11 @@ handle_connection(
|
||||
ssl_sock = tcp_sock;
|
||||
}
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!arena)
|
||||
errExit("cannot allocate arena");
|
||||
|
||||
osm = ocspStaplingMode;
|
||||
if (osm == osm_random) {
|
||||
/* 6 different responses */
|
||||
int r = rand() % 6;
|
||||
switch (r) {
|
||||
case 0: osm = osm_good; break;
|
||||
case 1: osm = osm_revoked; break;
|
||||
case 2: osm = osm_unknown; break;
|
||||
case 3: osm = osm_badsig; break;
|
||||
case 4: osm = osm_corrupted; break;
|
||||
case 5: osm = osm_failure; break;
|
||||
default: PORT_Assert(0); break;
|
||||
}
|
||||
for (kea = kt_rsa; kea < kt_kea_size; kea++) {
|
||||
if (certStatus[kea] != NULL) {
|
||||
SSL_SetStapledOCSPResponses(ssl_sock, certStatus[kea], kea);
|
||||
}
|
||||
}
|
||||
if (osm != osm_disabled) {
|
||||
SECItemArray *multiOcspResponses = NULL;
|
||||
switch (osm) {
|
||||
case osm_good:
|
||||
case osm_revoked:
|
||||
case osm_unknown:
|
||||
case osm_badsig:
|
||||
multiOcspResponses =
|
||||
makeSignedOCSPResponse(arena, osm, ssl_sock,
|
||||
certForStatusWeakReference);
|
||||
break;
|
||||
case osm_corrupted:
|
||||
multiOcspResponses = makeCorruptedOCSPResponse(arena);
|
||||
break;
|
||||
case osm_failure:
|
||||
multiOcspResponses = makeTryLaterOCSPResponse(arena);
|
||||
break;
|
||||
case osm_ocsp:
|
||||
errExit("stapling mode \"ocsp\" not implemented");
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (multiOcspResponses) {
|
||||
SSL_SetStapledOCSPResponses(ssl_sock, multiOcspResponses,
|
||||
PR_FALSE /* no ownership transfer */);
|
||||
}
|
||||
}
|
||||
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
arena = NULL;
|
||||
|
||||
if (loggingLayer) {
|
||||
/* find the layer where our new layer is to be pushed */
|
||||
@ -1910,9 +1907,6 @@ server_main(
|
||||
|
||||
for (kea = kt_rsa; kea < kt_kea_size; kea++) {
|
||||
if (cert[kea] != NULL) {
|
||||
if (!certForStatusWeakReference)
|
||||
certForStatusWeakReference = cert[kea];
|
||||
|
||||
secStatus = SSL_ConfigSecureServer(model_sock,
|
||||
cert[kea], privKey[kea], kea);
|
||||
if (secStatus != SECSuccess)
|
||||
@ -2172,6 +2166,7 @@ main(int argc, char **argv)
|
||||
PRUint32 i;
|
||||
secuPWData pwdata = { PW_NONE, 0 };
|
||||
char *expectedHostNameVal = NULL;
|
||||
PLArenaPool *certStatusArena = NULL;
|
||||
|
||||
tmp = strrchr(argv[0], '/');
|
||||
tmp = tmp ? tmp + 1 : argv[0];
|
||||
@ -2569,6 +2564,10 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
certStatusArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!certStatusArena)
|
||||
errExit("cannot allocate certStatusArena");
|
||||
|
||||
if (nickName) {
|
||||
cert[kt_rsa] = PK11_FindCertFromNickname(nickName, &pwdata);
|
||||
if (cert[kt_rsa] == NULL) {
|
||||
@ -2591,6 +2590,8 @@ main(int argc, char **argv)
|
||||
fprintf(stderr, "selfserv: %s can%s bypass\n", nickName,
|
||||
bypassOK ? "" : "not");
|
||||
}
|
||||
setupCertStatus(certStatusArena, ocspStaplingMode, cert[kt_rsa], kt_rsa,
|
||||
&pwdata);
|
||||
}
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
if (ecNickName) {
|
||||
@ -2615,7 +2616,9 @@ main(int argc, char **argv)
|
||||
}
|
||||
fprintf(stderr, "selfserv: %s can%s bypass\n", ecNickName,
|
||||
bypassOK ? "" : "not");
|
||||
}
|
||||
}
|
||||
setupCertStatus(certStatusArena, ocspStaplingMode, cert[kt_ecdh], kt_ecdh,
|
||||
&pwdata);
|
||||
}
|
||||
#endif /* NSS_ENABLE_ECC */
|
||||
|
||||
@ -2697,6 +2700,9 @@ cleanup:
|
||||
if (hasSidCache) {
|
||||
SSL_ShutdownServerSessionIDCache();
|
||||
}
|
||||
if (certStatusArena) {
|
||||
PORT_FreeArena(certStatusArena, PR_FALSE);
|
||||
}
|
||||
if (NSS_Shutdown() != SECSuccess) {
|
||||
SECU_PrintError(progName, "NSS_Shutdown");
|
||||
if (loggerThread) {
|
||||
@ -2709,4 +2715,3 @@ cleanup:
|
||||
printf("selfserv: normal termination\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -10,4 +10,3 @@
|
||||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
@ -1036,8 +1036,10 @@ AppendAVA(stringBuf *bufp, CERTAVA *ava, CertStrictnessLevel strict)
|
||||
} else {
|
||||
/* must truncate the escaped and quoted value */
|
||||
char bigTmpBuf[TMPBUF_LEN * 3 + 3];
|
||||
PORT_Assert(valueLen < sizeof tmpBuf);
|
||||
rv = escapeAndQuote(bigTmpBuf, sizeof bigTmpBuf,
|
||||
(char *)avaValue->data, valueLen, &mode);
|
||||
(char *)avaValue->data,
|
||||
PR_MIN(avaValue->len, valueLen), &mode);
|
||||
|
||||
bigTmpBuf[valueLen--] = '\0'; /* hard stop here */
|
||||
/* See if we're in the middle of a multi-byte UTF8 character */
|
||||
|
@ -3,7 +3,6 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
my $cvs_id = '@(#) $RCSfile$ $Revision$ $Date$';
|
||||
use strict;
|
||||
|
||||
my %constants;
|
||||
@ -11,7 +10,6 @@ my $count = 0;
|
||||
my $o;
|
||||
my @objects = ();
|
||||
my @objsize;
|
||||
my $cvsid;
|
||||
|
||||
$constants{CKO_DATA} = "static const CK_OBJECT_CLASS cko_data = CKO_DATA;\n";
|
||||
$constants{CK_TRUE} = "static const CK_BBOOL ck_true = CK_TRUE;\n";
|
||||
@ -24,21 +22,6 @@ while(<>) {
|
||||
s/^((?:[^"#]+|"[^"]*")*)(\s*#.*$)/$1/;
|
||||
next if (/^\s*$/);
|
||||
|
||||
if( /(^CVS_ID\s+)(.*)/ ) {
|
||||
$cvsid = $2 . "\"; $cvs_id\"";
|
||||
my $scratch = $cvsid;
|
||||
$size = 1 + $scratch =~ s/[^"\n]//g;
|
||||
@{$objects[0][0]} = ( "CKA_CLASS", "&cko_data", "sizeof(CK_OBJECT_CLASS)" );
|
||||
@{$objects[0][1]} = ( "CKA_TOKEN", "&ck_true", "sizeof(CK_BBOOL)" );
|
||||
@{$objects[0][2]} = ( "CKA_PRIVATE", "&ck_false", "sizeof(CK_BBOOL)" );
|
||||
@{$objects[0][3]} = ( "CKA_MODIFIABLE", "&ck_false", "sizeof(CK_BBOOL)" );
|
||||
@{$objects[0][4]} = ( "CKA_LABEL", "\"CVS ID\"", "7" );
|
||||
@{$objects[0][5]} = ( "CKA_APPLICATION", "\"NSS\"", "4" );
|
||||
@{$objects[0][6]} = ( "CKA_VALUE", $cvsid, "$size" );
|
||||
$objsize[0] = 7;
|
||||
next;
|
||||
}
|
||||
|
||||
# This was taken from the perl faq #4.
|
||||
my $text = $_;
|
||||
push(@fields, $+) while $text =~ m{
|
||||
@ -110,7 +93,7 @@ doprint();
|
||||
|
||||
sub dudump {
|
||||
my $i;
|
||||
for( $i = 0; $i <= $count; $i++ ) {
|
||||
for( $i = 1; $i <= $count; $i++ ) {
|
||||
print "\n";
|
||||
$o = $objects[$i];
|
||||
my @ob = @{$o};
|
||||
@ -133,9 +116,6 @@ print <<EOD
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = $cvsid;
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef BUILTINS_H
|
||||
#include "builtins.h"
|
||||
@ -148,11 +128,7 @@ foreach $b (sort values(%constants)) {
|
||||
print $b;
|
||||
}
|
||||
|
||||
for( $i = 0; $i <= $count; $i++ ) {
|
||||
if( 0 == $i ) {
|
||||
print "#ifdef DEBUG\n";
|
||||
}
|
||||
|
||||
for( $i = 1; $i <= $count; $i++ ) {
|
||||
print "static const CK_ATTRIBUTE_TYPE nss_builtins_types_$i [] = {\n";
|
||||
$o = $objects[$i];
|
||||
my @ob = @{$o};
|
||||
@ -166,17 +142,9 @@ for( $i = 0; $i <= $count; $i++ ) {
|
||||
}
|
||||
}
|
||||
print "\n};\n";
|
||||
|
||||
if( 0 == $i ) {
|
||||
print "#endif /* DEBUG */\n";
|
||||
}
|
||||
}
|
||||
|
||||
for( $i = 0; $i <= $count; $i++ ) {
|
||||
if( 0 == $i ) {
|
||||
print "#ifdef DEBUG\n";
|
||||
}
|
||||
|
||||
for( $i = 1; $i <= $count; $i++ ) {
|
||||
print "static const NSSItem nss_builtins_items_$i [] = {\n";
|
||||
$o = $objects[$i];
|
||||
my @ob = @{$o};
|
||||
@ -192,40 +160,22 @@ for( $i = 0; $i <= $count; $i++ ) {
|
||||
}
|
||||
}
|
||||
print "};\n";
|
||||
|
||||
if( 0 == $i ) {
|
||||
print "#endif /* DEBUG */\n";
|
||||
}
|
||||
}
|
||||
|
||||
print "\nbuiltinsInternalObject\n";
|
||||
print "nss_builtins_data[] = {\n";
|
||||
|
||||
for( $i = 0; $i <= $count; $i++ ) {
|
||||
|
||||
if( 0 == $i ) {
|
||||
print "#ifdef DEBUG\n";
|
||||
}
|
||||
|
||||
for( $i = 1; $i <= $count; $i++ ) {
|
||||
print " { $objsize[$i], nss_builtins_types_$i, nss_builtins_items_$i, {NULL} }";
|
||||
|
||||
if( $i == $count ) {
|
||||
print "\n";
|
||||
} else {
|
||||
print ",\n";
|
||||
}
|
||||
|
||||
if( 0 == $i ) {
|
||||
print "#endif /* DEBUG */\n";
|
||||
}
|
||||
}
|
||||
|
||||
print "};\n";
|
||||
|
||||
print "const PRUint32\n";
|
||||
print "#ifdef DEBUG\n";
|
||||
print " nss_builtins_nObjects = $count+1;\n";
|
||||
print "#else\n";
|
||||
print " nss_builtins_nObjects = $count;\n";
|
||||
print "#endif /* DEBUG */\n";
|
||||
print "nss_builtins_nObjects = $count;\n";
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
CVS_ID "@(#) $RCSfile$ $Revision$ $Date$"
|
||||
|
||||
#
|
||||
# certdata.txt
|
||||
|
@ -6,8 +6,6 @@
|
||||
# This file is in part derived from a file "pkcs11f.h" made available
|
||||
# by RSA Security at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/pkcs11f.h
|
||||
|
||||
CVS_ID "@(#) $RCSfile$ $Revision$ $Date$"
|
||||
|
||||
# Fields
|
||||
# FUNCTION introduces a Cryptoki function
|
||||
# CK_type specifies and introduces an argument
|
||||
|
@ -74,10 +74,6 @@ print <<EOD
|
||||
#ifndef NSSCKG_H
|
||||
#define NSSCKG_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char NSSCKG_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* nssckg.h
|
||||
*
|
||||
@ -118,10 +114,6 @@ print <<EOD
|
||||
#ifndef NSSCKFT_H
|
||||
#define NSSCKFT_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char NSSCKFT_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* nssckft.h
|
||||
*
|
||||
@ -162,10 +154,6 @@ print <<EOD
|
||||
#ifndef NSSCKEPV_H
|
||||
#define NSSCKEPV_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char NSSCKEPV_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* nssckepv.h
|
||||
*
|
||||
@ -206,10 +194,6 @@ select API;
|
||||
print $copyright;
|
||||
print <<EOD
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char NSSCKAPI_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* nssck.api
|
||||
*
|
||||
|
@ -1488,6 +1488,32 @@ PKIX_PL_Cert_VerifySignature(
|
||||
PKIX_PL_PublicKey *pubKey,
|
||||
void *plContext);
|
||||
|
||||
/* A set of flags to indicate how explicitly configured trust anchors should be
|
||||
* handled by PKIX_PL_Cert_IsCertTrusted
|
||||
*/
|
||||
typedef enum PKIX_PL_TrustAnchorModeEnum {
|
||||
/* Indicates trust anchors should be ignored; only the underlying
|
||||
* platform's trust settings should be used.
|
||||
*/
|
||||
PKIX_PL_TrustAnchorMode_Ignore,
|
||||
|
||||
/* Indicates that explicitly configured trust anchors may be considered
|
||||
* trustworthy, if present.
|
||||
* Note: If the underlying platform supports marking a certificate as
|
||||
* explicitly untrustworthy, explicitly configured trust anchors
|
||||
* MAY be ignored/rejected.
|
||||
*/
|
||||
PKIX_PL_TrustAnchorMode_Additive,
|
||||
|
||||
/* Indicates that ONLY trust anchors should be considered as
|
||||
* trustworthy.
|
||||
* Note: If the underlying platform supports marking a certificate as
|
||||
* explicitly untrustworthy, explicitly configured trust anchors
|
||||
* MAY be ignored/rejected.
|
||||
*/
|
||||
PKIX_PL_TrustAnchorMode_Exclusive,
|
||||
} PKIX_PL_TrustAnchorMode;
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_PL_Cert_IsCertTrusted
|
||||
* DESCRIPTION:
|
||||
@ -1509,8 +1535,9 @@ PKIX_PL_Cert_VerifySignature(
|
||||
* "cert"
|
||||
* Address of Cert whose trustworthiness is to be determined. Must be
|
||||
* non-NULL.
|
||||
* "trustOnlyUserAnchors"
|
||||
* States that we can only trust explicitly defined user trust anchors.
|
||||
* "trustAnchorMode"
|
||||
* A PKIX_PL_TrustAnchorMode that indicates how explicitly defined user
|
||||
* trust anchors should be handled.
|
||||
* "pTrusted"
|
||||
* Address where the Boolean value will be stored. Must be non-NULL.
|
||||
* "plContext"
|
||||
@ -1525,7 +1552,7 @@ PKIX_PL_Cert_VerifySignature(
|
||||
PKIX_Error *
|
||||
PKIX_PL_Cert_IsCertTrusted(
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_Boolean trustOnlyUserAnchors,
|
||||
PKIX_PL_TrustAnchorMode trustAnchorMode,
|
||||
PKIX_Boolean *pTrusted,
|
||||
void *plContext);
|
||||
|
||||
|
@ -836,7 +836,8 @@ pkix_Build_VerifyCertificate(
|
||||
PKIX_PL_PublicKey *candidatePubKey = NULL;
|
||||
PKIX_CertChainChecker *userChecker = NULL;
|
||||
PKIX_CertChainChecker_CheckCallback checkerCheck = NULL;
|
||||
PKIX_Boolean trustOnlyUserAnchors = PKIX_FALSE;
|
||||
PKIX_PL_TrustAnchorMode trustAnchorMode =
|
||||
PKIX_PL_TrustAnchorMode_Ignore;
|
||||
void *nbioContext = NULL;
|
||||
|
||||
PKIX_ENTER(BUILD, "pkix_Build_VerifyCertificate");
|
||||
@ -850,12 +851,17 @@ pkix_Build_VerifyCertificate(
|
||||
candidateCert = state->candidateCert;
|
||||
|
||||
if (state->buildConstants.numAnchors) {
|
||||
trustOnlyUserAnchors = state->buildConstants.trustOnlyUserAnchors;
|
||||
if (state->buildConstants.trustOnlyUserAnchors) {
|
||||
trustAnchorMode = PKIX_PL_TrustAnchorMode_Exclusive;
|
||||
} else {
|
||||
trustAnchorMode = PKIX_PL_TrustAnchorMode_Additive;
|
||||
}
|
||||
} else {
|
||||
trustAnchorMode = PKIX_PL_TrustAnchorMode_Ignore;
|
||||
}
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_PL_Cert_IsCertTrusted(candidateCert,
|
||||
trustOnlyUserAnchors,
|
||||
PKIX_PL_Cert_IsCertTrusted(candidateCert, trustAnchorMode,
|
||||
&trusted, plContext),
|
||||
PKIX_CERTISCERTTRUSTEDFAILED);
|
||||
|
||||
@ -3041,19 +3047,27 @@ pkix_Build_CheckInCache(
|
||||
(matchingAnchor, &trustedCert, plContext),
|
||||
PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
|
||||
|
||||
if (state->buildConstants.anchors &&
|
||||
state->buildConstants.anchors->length) {
|
||||
if (anchors && state->buildConstants.numAnchors) {
|
||||
/* Check if it is one of the trust anchors */
|
||||
PKIX_CHECK(
|
||||
pkix_List_Contains(state->buildConstants.anchors,
|
||||
pkix_List_Contains(anchors,
|
||||
(PKIX_PL_Object *)matchingAnchor,
|
||||
&trusted,
|
||||
plContext),
|
||||
PKIX_LISTCONTAINSFAILED);
|
||||
} else {
|
||||
PKIX_CHECK(PKIX_PL_Cert_IsCertTrusted
|
||||
(trustedCert, PKIX_FALSE, &trusted, plContext),
|
||||
PKIX_CERTISCERTTRUSTEDFAILED);
|
||||
}
|
||||
|
||||
if ((!trusted && !state->buildConstants.trustOnlyUserAnchors) ||
|
||||
!state->buildConstants.numAnchors) {
|
||||
/* If it is not one of the trust anchors and the trust anchors
|
||||
* are supplemental, or if there are no trust anchors, then check
|
||||
* if the cert is trusted directly.
|
||||
*/
|
||||
PKIX_CHECK(
|
||||
PKIX_PL_Cert_IsCertTrusted(trustedCert,
|
||||
PKIX_PL_TrustAnchorMode_Ignore,
|
||||
&trusted, plContext),
|
||||
PKIX_CERTISCERTTRUSTEDFAILED);
|
||||
}
|
||||
|
||||
if (!trusted) {
|
||||
|
@ -3294,7 +3294,7 @@ pkix_pl_Cert_GetTrusted(void *plContext,
|
||||
PKIX_Error *
|
||||
PKIX_PL_Cert_IsCertTrusted(
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_Boolean trustOnlyUserAnchors,
|
||||
PKIX_PL_TrustAnchorMode trustAnchorMode,
|
||||
PKIX_Boolean *pTrusted,
|
||||
void *plContext)
|
||||
{
|
||||
@ -3315,8 +3315,10 @@ PKIX_PL_Cert_IsCertTrusted(
|
||||
PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED);
|
||||
}
|
||||
|
||||
if (trustOnlyUserAnchors || cert->isUserTrustAnchor) {
|
||||
/* discard our |trusted| value since we are using the anchors */
|
||||
if (trustAnchorMode == PKIX_PL_TrustAnchorMode_Exclusive ||
|
||||
(trustAnchorMode == PKIX_PL_TrustAnchorMode_Additive &&
|
||||
cert->isUserTrustAnchor)) {
|
||||
/* Use the trust anchor's |trusted| value */
|
||||
*pTrusted = cert->isUserTrustAnchor;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -417,14 +417,13 @@ SSL_IMPORT const SECItemArray * SSL_PeerStapledOCSPResponses(PRFileDesc *fd);
|
||||
|
||||
/* SSL_SetStapledOCSPResponses stores an array of one or multiple OCSP responses
|
||||
* in the fd's data, which may be sent as part of a server side cert_status
|
||||
* handshake message.
|
||||
* If takeOwnership is false, the function will duplicate the responses.
|
||||
* If takeOwnership is true, the ownership of responses is transfered into the
|
||||
* SSL library, and the caller must stop using it.
|
||||
* handshake message. Parameter |responses| is for the server certificate of
|
||||
* the key exchange type |kea|.
|
||||
* The function will duplicate the responses array.
|
||||
*/
|
||||
SSL_IMPORT SECStatus
|
||||
SSL_SetStapledOCSPResponses(PRFileDesc *fd, SECItemArray *responses,
|
||||
PRBool takeOwnership);
|
||||
SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
|
||||
SSLKEAType kea);
|
||||
|
||||
/*
|
||||
** Authenticate certificate hook. Called when a certificate comes in
|
||||
|
@ -8444,23 +8444,36 @@ ssl3_SendCertificate(sslSocket *ss)
|
||||
static SECStatus
|
||||
ssl3_SendCertificateStatus(sslSocket *ss)
|
||||
{
|
||||
SECStatus rv;
|
||||
int len = 0;
|
||||
SECStatus rv;
|
||||
int len = 0;
|
||||
SECItemArray *statusToSend = NULL;
|
||||
SSL3KEAType certIndex;
|
||||
|
||||
SSL_TRC(3, ("%d: SSL3[%d]: send certificate status handshake",
|
||||
SSL_GETPID(), ss->fd));
|
||||
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
||||
PORT_Assert( ss->sec.isServer);
|
||||
|
||||
if (!ssl3_ExtensionNegotiated(ss, ssl_cert_status_xtn))
|
||||
return SECSuccess;
|
||||
|
||||
if (!ss->certStatusArray || !ss->certStatusArray->len)
|
||||
/* Use certStatus based on the cert being used. */
|
||||
if ((ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) ||
|
||||
(ss->ssl3.hs.kea_def->kea == kea_dhe_rsa)) {
|
||||
certIndex = kt_rsa;
|
||||
} else {
|
||||
certIndex = ss->ssl3.hs.kea_def->exchKeyType;
|
||||
}
|
||||
if (ss->certStatusArray[certIndex] && ss->certStatusArray[certIndex]->len) {
|
||||
statusToSend = ss->certStatusArray[certIndex];
|
||||
}
|
||||
if (!statusToSend)
|
||||
return SECSuccess;
|
||||
|
||||
/* Use the array's first item only (single stapling) */
|
||||
len = 1 + ss->certStatusArray->items[0].len + 3;
|
||||
len = 1 + statusToSend->items[0].len + 3;
|
||||
|
||||
rv = ssl3_AppendHandshakeHeader(ss, certificate_status, len);
|
||||
if (rv != SECSuccess) {
|
||||
@ -8471,8 +8484,8 @@ ssl3_SendCertificateStatus(sslSocket *ss)
|
||||
return rv; /* err set by AppendHandshake. */
|
||||
|
||||
rv = ssl3_AppendHandshakeVariable(ss,
|
||||
ss->certStatusArray->items[0].data,
|
||||
ss->certStatusArray->items[0].len,
|
||||
statusToSend->items[0].data,
|
||||
statusToSend->items[0].len,
|
||||
3);
|
||||
if (rv != SECSuccess)
|
||||
return rv; /* err set by AppendHandshake. */
|
||||
|
@ -681,8 +681,21 @@ ssl3_ServerSendStatusRequestXtn(
|
||||
{
|
||||
PRInt32 extension_length;
|
||||
SECStatus rv;
|
||||
int i;
|
||||
PRBool haveStatus = PR_FALSE;
|
||||
|
||||
if (!ss->certStatusArray || !ss->certStatusArray->len)
|
||||
for (i = kt_null; i < kt_kea_size; i++) {
|
||||
/* TODO: This is a temporary workaround.
|
||||
* The correct code needs to see if we have an OCSP response for
|
||||
* the server certificate being used, rather than if we have any
|
||||
* OCSP response. See also ssl3_SendCertificateStatus.
|
||||
*/
|
||||
if (ss->certStatusArray[i] && ss->certStatusArray[i]->len) {
|
||||
haveStatus = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!haveStatus)
|
||||
return 0;
|
||||
|
||||
extension_length = 2 + 2;
|
||||
|
@ -1175,7 +1175,8 @@ const unsigned char * preferredCipher;
|
||||
/* Configuration state for server sockets */
|
||||
/* server cert and key for each KEA type */
|
||||
sslServerCerts serverCerts[kt_kea_size];
|
||||
SECItemArray * certStatusArray;
|
||||
/* each cert needs its own status */
|
||||
SECItemArray * certStatusArray[kt_kea_size];
|
||||
|
||||
ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED];
|
||||
ssl3KeyPair * ephemeralECDHKeyPair; /* for ECDHE-* handshake */
|
||||
|
@ -321,13 +321,13 @@ ssl_DupSocket(sslSocket *os)
|
||||
if (oc->serverKeyPair && !sc->serverKeyPair)
|
||||
goto loser;
|
||||
sc->serverKeyBits = oc->serverKeyBits;
|
||||
ss->certStatusArray[i] = !os->certStatusArray[i] ? NULL :
|
||||
SECITEM_DupArray(NULL, os->certStatusArray[i]);
|
||||
}
|
||||
ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL :
|
||||
ssl3_GetKeyPairRef(os->stepDownKeyPair);
|
||||
ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL :
|
||||
ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair);
|
||||
ss->certStatusArray = !os->certStatusArray ? NULL :
|
||||
SECITEM_DupArray(NULL, os->certStatusArray);
|
||||
/*
|
||||
* XXX the preceding CERT_ and SECKEY_ functions can fail and return NULL.
|
||||
* XXX We should detect this, and not just march on with NULL pointers.
|
||||
@ -430,6 +430,10 @@ ssl_DestroySocketContents(sslSocket *ss)
|
||||
CERT_DestroyCertificateList(sc->serverCertChain);
|
||||
if (sc->serverKeyPair != NULL)
|
||||
ssl3_FreeKeyPair(sc->serverKeyPair);
|
||||
if (ss->certStatusArray[i] != NULL) {
|
||||
SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
|
||||
ss->certStatusArray[i] = NULL;
|
||||
}
|
||||
}
|
||||
if (ss->stepDownKeyPair) {
|
||||
ssl3_FreeKeyPair(ss->stepDownKeyPair);
|
||||
@ -439,10 +443,6 @@ ssl_DestroySocketContents(sslSocket *ss)
|
||||
ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
|
||||
ss->ephemeralECDHKeyPair = NULL;
|
||||
}
|
||||
if (ss->certStatusArray) {
|
||||
SECITEM_FreeArray(ss->certStatusArray, PR_TRUE);
|
||||
ss->certStatusArray = NULL;
|
||||
}
|
||||
SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
|
||||
PORT_Assert(!ss->xtnData.sniNameArr);
|
||||
if (ss->xtnData.sniNameArr) {
|
||||
@ -1668,6 +1668,15 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
|
||||
sc->serverCertChain = CERT_DupCertList(mc->serverCertChain);
|
||||
if (!sc->serverCertChain)
|
||||
goto loser;
|
||||
if (sm->certStatusArray[i]) {
|
||||
if (ss->certStatusArray[i]) {
|
||||
SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
|
||||
ss->certStatusArray[i] = NULL;
|
||||
}
|
||||
ss->certStatusArray[i] = SECITEM_DupArray(NULL, sm->certStatusArray[i]);
|
||||
if (!ss->certStatusArray[i])
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
if (mc->serverKeyPair) {
|
||||
if (sc->serverKeyPair) {
|
||||
@ -1690,13 +1699,6 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
|
||||
ss->ephemeralECDHKeyPair =
|
||||
ssl3_GetKeyPairRef(sm->ephemeralECDHKeyPair);
|
||||
}
|
||||
if (sm->certStatusArray) {
|
||||
if (ss->certStatusArray) {
|
||||
SECITEM_FreeArray(ss->certStatusArray, PR_TRUE);
|
||||
ss->certStatusArray = NULL;
|
||||
}
|
||||
ss->certStatusArray = SECITEM_DupArray(NULL, sm->certStatusArray);
|
||||
}
|
||||
/* copy trust anchor names */
|
||||
if (sm->ssl3.ca_list) {
|
||||
if (ss->ssl3.ca_list) {
|
||||
@ -2229,8 +2231,8 @@ ssl_GetSockName(PRFileDesc *fd, PRNetAddr *name)
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SSL_SetStapledOCSPResponses(PRFileDesc *fd, SECItemArray *responses,
|
||||
PRBool takeOwnership)
|
||||
SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
|
||||
SSLKEAType kea)
|
||||
{
|
||||
sslSocket *ss;
|
||||
|
||||
@ -2241,19 +2243,20 @@ SSL_SetStapledOCSPResponses(PRFileDesc *fd, SECItemArray *responses,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (ss->certStatusArray) {
|
||||
SECITEM_FreeArray(ss->certStatusArray, PR_TRUE);
|
||||
ss->certStatusArray = NULL;
|
||||
if ( kea <= 0 || kea >= kt_kea_size) {
|
||||
SSL_DBG(("%d: SSL[%d]: invalid key in SSL_SetStapledOCSPResponses",
|
||||
SSL_GETPID(), fd));
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (ss->certStatusArray[kea]) {
|
||||
SECITEM_FreeArray(ss->certStatusArray[kea], PR_TRUE);
|
||||
ss->certStatusArray[kea] = NULL;
|
||||
}
|
||||
if (responses) {
|
||||
if (takeOwnership) {
|
||||
ss->certStatusArray = responses;
|
||||
}
|
||||
else {
|
||||
ss->certStatusArray = SECITEM_DupArray(NULL, responses);
|
||||
}
|
||||
ss->certStatusArray[kea] = SECITEM_DupArray(NULL, responses);
|
||||
}
|
||||
return (ss->certStatusArray || !responses) ? SECSuccess : SECFailure;
|
||||
return (ss->certStatusArray[kea] || !responses) ? SECSuccess : SECFailure;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
@ -2953,10 +2956,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
|
||||
sc->serverCertChain = NULL;
|
||||
sc->serverKeyPair = NULL;
|
||||
sc->serverKeyBits = 0;
|
||||
ss->certStatusArray[i] = NULL;
|
||||
}
|
||||
ss->stepDownKeyPair = NULL;
|
||||
ss->dbHandle = CERT_GetDefaultCertDB();
|
||||
ss->certStatusArray = NULL;
|
||||
|
||||
/* Provide default implementation of hooks */
|
||||
ss->authCertificate = SSL_AuthCertificate;
|
||||
|
@ -266,6 +266,7 @@ NSSUTIL_QuoteSize;
|
||||
SECITEM_AllocArray;
|
||||
SECITEM_DupArray;
|
||||
SECITEM_FreeArray;
|
||||
SECITEM_ReallocItemV2;
|
||||
SECITEM_ZfreeArray;
|
||||
;+ local:
|
||||
;+ *;
|
||||
|
@ -115,6 +115,63 @@ SECITEM_ReallocItem(PLArenaPool *arena, SECItem *item, unsigned int oldlen,
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SECITEM_ReallocItemV2(PLArenaPool *arena, SECItem *item, unsigned int newlen)
|
||||
{
|
||||
unsigned char *newdata = NULL;
|
||||
|
||||
PORT_Assert(item);
|
||||
if (!item) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (item->len == newlen) {
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
if (!newlen) {
|
||||
SECITEM_FreeItem(item, PR_FALSE);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
if (!item->len) {
|
||||
/* allocate fresh block of memory */
|
||||
PORT_Assert(!item->data);
|
||||
if (arena) {
|
||||
newdata = PORT_ArenaAlloc(arena, newlen);
|
||||
} else {
|
||||
newdata = PORT_Alloc(newlen);
|
||||
}
|
||||
} else {
|
||||
/* reallocate or adjust existing block of memory */
|
||||
if (arena) {
|
||||
if (item->len > newlen) {
|
||||
/* There's no need to realloc a shorter block from the arena,
|
||||
* because it would result in using even more memory!
|
||||
* Therefore we'll continue to use the old block and
|
||||
* set the item to the shorter size.
|
||||
*/
|
||||
item->len = newlen;
|
||||
return SECSuccess;
|
||||
} else {
|
||||
newdata = PORT_ArenaGrow(arena, item->data, item->len, newlen);
|
||||
}
|
||||
} else {
|
||||
newdata = PORT_Realloc(item->data, newlen);
|
||||
}
|
||||
}
|
||||
|
||||
if (!newdata) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
item->len = newlen;
|
||||
item->data = newdata;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECComparison
|
||||
SECITEM_CompareItem(const SECItem *a, const SECItem *b)
|
||||
{
|
||||
|
@ -36,6 +36,11 @@ extern SECItem *SECITEM_AllocItem(PLArenaPool *arena, SECItem *item,
|
||||
unsigned int len);
|
||||
|
||||
/*
|
||||
** This is a legacy function containing bugs. It doesn't update item->len,
|
||||
** and it has other issues as described in bug 298649 and bug 298938.
|
||||
** However, the function is kept unchanged for consumers that might depend
|
||||
** on the broken behaviour. New code should call SECITEM_ReallocItemV2.
|
||||
**
|
||||
** Reallocate the data for the specified "item". If "arena" is not NULL,
|
||||
** then reallocate from there, otherwise reallocate from the heap.
|
||||
** In the case where oldlen is 0, the data is allocated (not reallocated).
|
||||
@ -43,9 +48,22 @@ extern SECItem *SECITEM_AllocItem(PLArenaPool *arena, SECItem *item,
|
||||
** SECFailure is returned if it is not. If the allocation succeeds,
|
||||
** SECSuccess is returned.
|
||||
*/
|
||||
extern SECStatus SECITEM_ReallocItem(PLArenaPool *arena, SECItem *item,
|
||||
extern SECStatus SECITEM_ReallocItem( /* deprecated function */
|
||||
PLArenaPool *arena, SECItem *item,
|
||||
unsigned int oldlen, unsigned int newlen);
|
||||
|
||||
/*
|
||||
** Reallocate the data for the specified "item". If "arena" is not NULL,
|
||||
** then reallocate from there, otherwise reallocate from the heap.
|
||||
** If the item already has at least the request new size,
|
||||
** then the item is kept unchanged and SECSuccess is returned.
|
||||
** In any case, "item" is expected to be a valid SECItem pointer;
|
||||
** SECFailure is returned if it is not, and the item will remain unchanged.
|
||||
** If the allocation succeeds, the item is updated and SECSuccess is returned.
|
||||
*/
|
||||
extern SECStatus SECITEM_ReallocItemV2(PLArenaPool *arena, SECItem *item,
|
||||
unsigned int newlen);
|
||||
|
||||
/*
|
||||
** Compare two items returning the difference between them.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user