Bug 811331 / Bug 360420, OCSP Stapling, TLS server side implementation; add ability to produce invalid OCSP responses for testing purposes, r=rrelyea

git-svn-id: svn://10.0.0.236/trunk@264736 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
kaie%kuix.de 2013-02-15 17:56:19 +00:00
parent 7d2a505113
commit 6fe835fb35
12 changed files with 295 additions and 60 deletions

View File

@ -6,7 +6,7 @@
* Implementation of OCSP services, for both client and server. * Implementation of OCSP services, for both client and server.
* (XXX, really, mostly just for client right now, but intended to do both.) * (XXX, really, mostly just for client right now, but intended to do both.)
* *
* $Id: ocsp.c,v 1.78 2013-02-15 17:53:24 kaie%kuix.de Exp $ * $Id: ocsp.c,v 1.79 2013-02-15 17:56:18 kaie%kuix.de Exp $
*/ */
#include "prerror.h" #include "prerror.h"
@ -1572,7 +1572,7 @@ CERT_DestroyOCSPCertID(CERTOCSPCertID* certID)
* results in a NULL being returned (and an appropriate error set). * results in a NULL being returned (and an appropriate error set).
*/ */
static SECItem * SECItem *
ocsp_DigestValue(PRArenaPool *arena, SECOidTag digestAlg, ocsp_DigestValue(PRArenaPool *arena, SECOidTag digestAlg,
SECItem *fill, const SECItem *src) SECItem *fill, const SECItem *src)
{ {

View File

@ -4,7 +4,7 @@
/* /*
* ocspi.h - NSS internal interfaces to OCSP code * ocspi.h - NSS internal interfaces to OCSP code
* *
* $Id: ocspi.h,v 1.13 2012-12-12 19:29:40 wtc%google.com Exp $ * $Id: ocspi.h,v 1.14 2013-02-15 17:56:18 kaie%kuix.de Exp $
*/ */
#ifndef _OCSPI_H_ #ifndef _OCSPI_H_
@ -19,6 +19,10 @@ ocsp_GetResponseData(CERTOCSPResponse *response, SECItem **tbsResponseDataDER);
ocspSignature * ocspSignature *
ocsp_GetResponseSignature(CERTOCSPResponse *response); ocsp_GetResponseSignature(CERTOCSPResponse *response);
SECItem *
ocsp_DigestValue(PRArenaPool *arena, SECOidTag digestAlg,
SECItem *fill, const SECItem *src);
PRBool PRBool
ocsp_CertIsOCSPDefaultResponder(CERTCertDBHandle *handle, CERTCertificate *cert); ocsp_CertIsOCSPDefaultResponder(CERTCertDBHandle *handle, CERTCertificate *cert);

View File

@ -355,6 +355,8 @@ CERT_CreateOCSPSingleResponseRevoked(
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate); return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
} }
/* responderCert == 0 means:
* create a response with an invalid signature (for testing purposes) */
SECItem* SECItem*
CERT_CreateEncodedOCSPSuccessResponse( CERT_CreateEncodedOCSPSuccessResponse(
PLArenaPool *arena, PLArenaPool *arena,
@ -377,7 +379,7 @@ CERT_CreateEncodedOCSPSuccessResponse(
SECKEYPrivateKey *privKey = NULL; SECKEYPrivateKey *privKey = NULL;
SECItem *result = NULL; SECItem *result = NULL;
if (!arena || !responderCert || !responses) { if (!arena || !responses) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL; return NULL;
} }
@ -414,6 +416,53 @@ CERT_CreateEncodedOCSPSuccessResponse(
if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt)
!= SECSuccess) != SECSuccess)
goto done; goto done;
if (!responderCert) {
/* use invalid signature for testing purposes */
char dummyChar = 'd';
SECItem dummy;
dummy.len = 1;
dummy.data = &dummyChar;
/* it's easier to produdce a keyHash out of nowhere,
* than to produce an encoded subject,
* so for our dummy response we always use byKey
*/
rid->responderIDType = ocspResponderID_byKey;
if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.keyHash,
&dummy))
goto done;
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
ocsp_ResponderIDByKeyTemplate))
goto done;
br->tbsResponseData = rd;
if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
ocsp_myResponseDataTemplate))
goto done;
br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1);
if (!br->responseSignature.derCerts)
goto done;
br->responseSignature.derCerts[0] = NULL;
algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1);
if (algID == SEC_OID_UNKNOWN)
goto done;
/* match the regular signature code, which doesn't use the arena */
if (!SECITEM_AllocItem(NULL, &br->responseSignature.signature, 1))
goto done;
PORT_Memcpy(br->responseSignature.signature.data, &dummyChar, 1);
/* convert len-in-bytes to len-in-bits */
br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
}
else {
rid->responderIDType = responderIDType; rid->responderIDType = responderIDType;
if (responderIDType == ocspResponderID_byName) { if (responderIDType == ocspResponderID_byName) {
responderIDTemplate = ocsp_ResponderIDByNameTemplate; responderIDTemplate = ocsp_ResponderIDByNameTemplate;
@ -462,6 +511,7 @@ CERT_CreateEncodedOCSPSuccessResponse(
/* br->responseSignature.signature wasn't allocated from arena, /* br->responseSignature.signature wasn't allocated from arena,
* we must free it when done. */ * we must free it when done. */
}
if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0) if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0)
!= SECSuccess) != SECSuccess)

View File

@ -159,6 +159,7 @@ SSL_SetSRTPCiphers;
;+NSS_3.14.2 { # NSS 3.14.2 release ;+NSS_3.14.2 { # NSS 3.14.2 release
;+ global: ;+ global:
SSL_PeerStapledOCSPResponses; SSL_PeerStapledOCSPResponses;
SSL_SetStapledOCSPResponses;
;+ local: ;+ local:
;+*; ;+*;
;+}; ;+};

View File

@ -4,7 +4,7 @@
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* $Id: ssl.h,v 1.61 2013-02-15 17:55:41 kaie%kuix.de Exp $ */ /* $Id: ssl.h,v 1.62 2013-02-15 17:56:19 kaie%kuix.de Exp $ */
#ifndef __ssl_h_ #ifndef __ssl_h_
#define __ssl_h_ #define __ssl_h_
@ -416,6 +416,17 @@ SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
*/ */
SSL_IMPORT const SECItemArray * SSL_PeerStapledOCSPResponses(PRFileDesc *fd); 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.
*/
SSL_IMPORT SECStatus
SSL_SetStapledOCSPResponses(PRFileDesc *fd, SECItemArray *responses,
PRBool takeOwnership);
/* /*
** Authenticate certificate hook. Called when a certificate comes in ** Authenticate certificate hook. Called when a certificate comes in
** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the ** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the

View File

@ -5,7 +5,7 @@
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* $Id: ssl3con.c,v 1.203 2013-02-15 17:55:41 kaie%kuix.de Exp $ */ /* $Id: ssl3con.c,v 1.204 2013-02-15 17:56:19 kaie%kuix.de Exp $ */
/* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
@ -49,6 +49,7 @@ static SECStatus ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss);
static SECStatus ssl3_HandshakeFailure( sslSocket *ss); static SECStatus ssl3_HandshakeFailure( sslSocket *ss);
static SECStatus ssl3_InitState( sslSocket *ss); static SECStatus ssl3_InitState( sslSocket *ss);
static SECStatus ssl3_SendCertificate( sslSocket *ss); static SECStatus ssl3_SendCertificate( sslSocket *ss);
static SECStatus ssl3_SendCertificateStatus( sslSocket *ss);
static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss);
static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
static SECStatus ssl3_SendNextProto( sslSocket *ss); static SECStatus ssl3_SendNextProto( sslSocket *ss);
@ -6491,6 +6492,10 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
if (rv != SECSuccess) { if (rv != SECSuccess) {
return rv; /* error code is set. */ return rv; /* error code is set. */
} }
rv = ssl3_SendCertificateStatus(ss);
if (rv != SECSuccess) {
return rv; /* error code is set. */
}
/* We have to do this after the call to ssl3_SendServerHello, /* We have to do this after the call to ssl3_SendServerHello,
* because kea_def is set up by ssl3_SendServerHello(). * because kea_def is set up by ssl3_SendServerHello().
*/ */
@ -8433,6 +8438,52 @@ ssl3_SendCertificate(sslSocket *ss)
return SECSuccess; return SECSuccess;
} }
/*
* Used by server only.
* single-stapling, send only a single cert status
*/
static SECStatus
ssl3_SendCertificateStatus(sslSocket *ss)
{
SECStatus rv;
CERTCertificateList *certChain;
int len = 0;
int i;
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));
if (!ssl3_ExtensionNegotiated(ss, ssl_cert_status_xtn))
return SECSuccess;
if (!ss->certStatusArray)
return SECSuccess;
/* Use the array's first item only (single stapling) */
len = 1 + ss->certStatusArray->items[0].len + 3;
rv = ssl3_AppendHandshakeHeader(ss, certificate_status, len);
if (rv != SECSuccess) {
return rv; /* err set by AppendHandshake. */
}
rv = ssl3_AppendHandshakeNumber(ss, 1 /*ocsp*/, 1);
if (rv != SECSuccess)
return rv; /* err set by AppendHandshake. */
rv = ssl3_AppendHandshakeVariable(ss,
ss->certStatusArray->items[0].data,
ss->certStatusArray->items[0].len,
3);
if (rv != SECSuccess)
return rv; /* err set by AppendHandshake. */
return SECSuccess;
}
/* This is used to delete the CA certificates in the peer certificate chain /* This is used to delete the CA certificates in the peer certificate chain
* from the cert database after they've been validated. * from the cert database after they've been validated.
*/ */

View File

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* TLS extension code moved here from ssl3ecc.c */ /* TLS extension code moved here from ssl3ecc.c */
/* $Id: ssl3ext.c,v 1.31 2013-02-15 17:52:45 kaie%kuix.de Exp $ */ /* $Id: ssl3ext.c,v 1.32 2013-02-15 17:56:19 kaie%kuix.de Exp $ */
#include "nssrenam.h" #include "nssrenam.h"
#include "nss.h" #include "nss.h"
@ -61,6 +61,10 @@ static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
PRUint32 maxBytes); PRUint32 maxBytes);
static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
SECItem *data); SECItem *data);
static SECStatus ssl3_ServerSendStatusRequestXtn(sslSocket * ss,
PRBool append, PRUint32 maxBytes);
static SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss,
PRUint16 ex_type, SECItem *data);
static SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, static SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss,
PRUint16 ex_type, PRUint16 ex_type,
SECItem *data); SECItem *data);
@ -227,6 +231,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
{ ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
{ ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
{ ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
{ -1, NULL } { -1, NULL }
}; };
@ -669,6 +674,33 @@ ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
return SECSuccess; return SECSuccess;
} }
static PRInt32
ssl3_ServerSendStatusRequestXtn(
sslSocket * ss,
PRBool append,
PRUint32 maxBytes)
{
PRInt32 extension_length;
SECStatus rv;
if (!ss->certStatusArray)
return 0;
extension_length = 2 + 2;
if (append && maxBytes >= extension_length) {
/* extension_type */
rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
if (rv != SECSuccess)
return -1;
/* length of extension_data */
rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
if (rv != SECSuccess)
return -1;
}
return extension_length;
}
/* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the
* client side. See RFC 4366 section 3.6. */ * client side. See RFC 4366 section 3.6. */
static PRInt32 static PRInt32
@ -1705,6 +1737,22 @@ ssl3_SendRenegotiationInfoXtn(
return needed; return needed;
} }
static SECStatus
ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
SECItem *data)
{
SECStatus rv = SECSuccess;
PRUint32 len = 0;
/* remember that we got this extension. */
ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
PORT_Assert(ss->sec.isServer);
/* prepare to send back the appropriate response */
rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
ssl3_ServerSendStatusRequestXtn);
return rv;
}
/* This function runs in both the client and server. */ /* This function runs in both the client and server. */
static SECStatus static SECStatus
ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)

View File

@ -5,7 +5,7 @@
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* $Id: sslimpl.h,v 1.111 2013-02-15 17:55:41 kaie%kuix.de Exp $ */ /* $Id: sslimpl.h,v 1.112 2013-02-15 17:56:19 kaie%kuix.de Exp $ */
#ifndef __sslimpl_h_ #ifndef __sslimpl_h_
#define __sslimpl_h_ #define __sslimpl_h_
@ -1178,6 +1178,7 @@ const unsigned char * preferredCipher;
/* Configuration state for server sockets */ /* Configuration state for server sockets */
/* server cert and key for each KEA type */ /* server cert and key for each KEA type */
sslServerCerts serverCerts[kt_kea_size]; sslServerCerts serverCerts[kt_kea_size];
SECItemArray * certStatusArray;
ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED]; ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED];
ssl3KeyPair * ephemeralECDHKeyPair; /* for ECDHE-* handshake */ ssl3KeyPair * ephemeralECDHKeyPair; /* for ECDHE-* handshake */

View File

@ -6,7 +6,7 @@
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* $Id: sslsock.c,v 1.101 2013-02-15 17:55:41 kaie%kuix.de Exp $ */ /* $Id: sslsock.c,v 1.102 2013-02-15 17:56:19 kaie%kuix.de Exp $ */
#include "seccomon.h" #include "seccomon.h"
#include "cert.h" #include "cert.h"
#include "keyhi.h" #include "keyhi.h"
@ -327,6 +327,8 @@ ssl_DupSocket(sslSocket *os)
ssl3_GetKeyPairRef(os->stepDownKeyPair); ssl3_GetKeyPairRef(os->stepDownKeyPair);
ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL : ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL :
ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair); 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 the preceding CERT_ and SECKEY_ functions can fail and return NULL.
* XXX We should detect this, and not just march on with NULL pointers. * XXX We should detect this, and not just march on with NULL pointers.
@ -438,6 +440,10 @@ ssl_DestroySocketContents(sslSocket *ss)
ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair); ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
ss->ephemeralECDHKeyPair = NULL; ss->ephemeralECDHKeyPair = NULL;
} }
if (ss->certStatusArray) {
SECITEM_FreeArray(ss->certStatusArray, PR_TRUE);
ss->certStatusArray = NULL;
}
SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE); SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
PORT_Assert(!ss->xtnData.sniNameArr); PORT_Assert(!ss->xtnData.sniNameArr);
if (ss->xtnData.sniNameArr) { if (ss->xtnData.sniNameArr) {
@ -1688,6 +1694,13 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
ss->ephemeralECDHKeyPair = ss->ephemeralECDHKeyPair =
ssl3_GetKeyPairRef(sm->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 */ /* copy trust anchor names */
if (sm->ssl3.ca_list) { if (sm->ssl3.ca_list) {
if (ss->ssl3.ca_list) { if (ss->ssl3.ca_list) {
@ -1872,7 +1885,7 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
sslSocket *ss = ssl_FindSocket(fd); sslSocket *ss = ssl_FindSocket(fd);
if (!ss) { if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetStapledOCSPResponse", SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerStapledOCSPResponses",
SSL_GETPID(), fd)); SSL_GETPID(), fd));
return NULL; return NULL;
} }
@ -2222,6 +2235,34 @@ ssl_GetSockName(PRFileDesc *fd, PRNetAddr *name)
return (PRStatus)(*ss->ops->getsockname)(ss, name); return (PRStatus)(*ss->ops->getsockname)(ss, name);
} }
SECStatus
SSL_SetStapledOCSPResponses(PRFileDesc *fd, SECItemArray *responses,
PRBool takeOwnership)
{
sslSocket *ss;
ss = ssl_FindSocket(fd);
if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetStapledOCSPResponses",
SSL_GETPID(), fd));
return SECFailure;
}
if (ss->certStatusArray) {
SECITEM_FreeArray(ss->certStatusArray, PR_TRUE);
ss->certStatusArray = NULL;
}
if (responses) {
if (takeOwnership) {
ss->certStatusArray = responses;
}
else {
ss->certStatusArray = SECITEM_DupArray(NULL, responses);
}
}
return (ss->certStatusArray || !responses) ? SECSuccess : SECFailure;
}
SECStatus SECStatus
SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID) SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID)
{ {
@ -2229,7 +2270,7 @@ SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID)
ss = ssl_FindSocket(fd); ss = ssl_FindSocket(fd);
if (!ss) { if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCacheIndex", SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSockPeerID",
SSL_GETPID(), fd)); SSL_GETPID(), fd));
return SECFailure; return SECFailure;
} }
@ -2922,6 +2963,7 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
} }
ss->stepDownKeyPair = NULL; ss->stepDownKeyPair = NULL;
ss->dbHandle = CERT_GetDefaultCertDB(); ss->dbHandle = CERT_GetDefaultCertDB();
ss->certStatusArray = NULL;
/* Provide default implementation of hooks */ /* Provide default implementation of hooks */
ss->authCertificate = SSL_AuthCertificate; ss->authCertificate = SSL_AuthCertificate;

View File

@ -264,6 +264,7 @@ NSSUTIL_QuoteSize;
;+NSSUTIL_3.14.2 { # NSS Utilities 3.14.2 release ;+NSSUTIL_3.14.2 { # NSS Utilities 3.14.2 release
;+ global: ;+ global:
SECITEM_AllocArray; SECITEM_AllocArray;
SECITEM_DupArray;
SECITEM_FreeArray; SECITEM_FreeArray;
SECITEM_ZfreeArray; SECITEM_ZfreeArray;
;+ local: ;+ local:

View File

@ -5,7 +5,7 @@
/* /*
* Support routines for SECItem data structure. * Support routines for SECItem data structure.
* *
* $Id: secitem.c,v 1.19 2013-02-15 17:55:42 kaie%kuix.de Exp $ * $Id: secitem.c,v 1.20 2013-02-15 17:56:19 kaie%kuix.de Exp $
*/ */
#include "seccomon.h" #include "seccomon.h"
@ -392,3 +392,28 @@ void SECITEM_ZfreeArray(SECItemArray *array, PRBool freeit)
{ {
secitem_FreeArray(array, PR_TRUE, freeit); secitem_FreeArray(array, PR_TRUE, freeit);
} }
SECItemArray *
SECITEM_DupArray(PLArenaPool *arena, const SECItemArray *from)
{
SECItemArray *result;
unsigned int i;
if (!from || !from->items || !from->len)
return NULL;
result = SECITEM_AllocArray(arena, NULL, from->len);
if (!result)
return NULL;
for (i=0; i<from->len; ++i) {
SECStatus rv = SECITEM_CopyItem(arena,
&result->items[i], &from->items[i]);
if (rv != SECSuccess) {
SECITEM_ZfreeArray(result, PR_TRUE);
return NULL;
}
}
return result;
}

View File

@ -11,7 +11,7 @@
* secitem.h - public data structures and prototypes for handling * secitem.h - public data structures and prototypes for handling
* SECItems * SECItems
* *
* $Id: secitem.h,v 1.10 2013-02-15 17:55:42 kaie%kuix.de Exp $ * $Id: secitem.h,v 1.11 2013-02-15 17:56:19 kaie%kuix.de Exp $
*/ */
#include "plarena.h" #include "plarena.h"
@ -93,6 +93,7 @@ PRIntn PR_CALLBACK SECITEM_HashCompare ( const void *k1, const void *k2);
extern SECItemArray *SECITEM_AllocArray(PLArenaPool *arena, extern SECItemArray *SECITEM_AllocArray(PLArenaPool *arena,
SECItemArray *array, SECItemArray *array,
unsigned int len); unsigned int len);
extern SECItemArray *SECITEM_DupArray(PLArenaPool *arena, const SECItemArray *from);
extern void SECITEM_FreeArray(SECItemArray *array, PRBool freeit); extern void SECITEM_FreeArray(SECItemArray *array, PRBool freeit);
extern void SECITEM_ZfreeArray(SECItemArray *array, PRBool freeit); extern void SECITEM_ZfreeArray(SECItemArray *array, PRBool freeit);