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:
parent
7d2a505113
commit
6fe835fb35
@ -6,7 +6,7 @@
|
||||
* Implementation of OCSP services, for both client and server.
|
||||
* (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"
|
||||
@ -1572,7 +1572,7 @@ CERT_DestroyOCSPCertID(CERTOCSPCertID* certID)
|
||||
* results in a NULL being returned (and an appropriate error set).
|
||||
*/
|
||||
|
||||
static SECItem *
|
||||
SECItem *
|
||||
ocsp_DigestValue(PRArenaPool *arena, SECOidTag digestAlg,
|
||||
SECItem *fill, const SECItem *src)
|
||||
{
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
/*
|
||||
* 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_
|
||||
@ -19,6 +19,10 @@ ocsp_GetResponseData(CERTOCSPResponse *response, SECItem **tbsResponseDataDER);
|
||||
ocspSignature *
|
||||
ocsp_GetResponseSignature(CERTOCSPResponse *response);
|
||||
|
||||
SECItem *
|
||||
ocsp_DigestValue(PRArenaPool *arena, SECOidTag digestAlg,
|
||||
SECItem *fill, const SECItem *src);
|
||||
|
||||
PRBool
|
||||
ocsp_CertIsOCSPDefaultResponder(CERTCertDBHandle *handle, CERTCertificate *cert);
|
||||
|
||||
|
||||
@ -355,6 +355,8 @@ CERT_CreateOCSPSingleResponseRevoked(
|
||||
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
|
||||
}
|
||||
|
||||
/* responderCert == 0 means:
|
||||
* create a response with an invalid signature (for testing purposes) */
|
||||
SECItem*
|
||||
CERT_CreateEncodedOCSPSuccessResponse(
|
||||
PLArenaPool *arena,
|
||||
@ -377,7 +379,7 @@ CERT_CreateEncodedOCSPSuccessResponse(
|
||||
SECKEYPrivateKey *privKey = NULL;
|
||||
SECItem *result = NULL;
|
||||
|
||||
if (!arena || !responderCert || !responses) {
|
||||
if (!arena || !responses) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
@ -414,58 +416,106 @@ CERT_CreateEncodedOCSPSuccessResponse(
|
||||
if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt)
|
||||
!= SECSuccess)
|
||||
goto done;
|
||||
rid->responderIDType = responderIDType;
|
||||
if (responderIDType == ocspResponderID_byName) {
|
||||
responderIDTemplate = ocsp_ResponderIDByNameTemplate;
|
||||
if (CERT_CopyName(tmpArena, &rid->responderIDValue.name,
|
||||
&responderCert->subject) != SECSuccess)
|
||||
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 {
|
||||
responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
|
||||
if (!CERT_GetSPKIDigest(tmpArena, responderCert, SEC_OID_SHA1,
|
||||
&rid->responderIDValue.keyHash))
|
||||
goto done;
|
||||
rid->responderIDType = responderIDType;
|
||||
if (responderIDType == ocspResponderID_byName) {
|
||||
responderIDTemplate = ocsp_ResponderIDByNameTemplate;
|
||||
if (CERT_CopyName(tmpArena, &rid->responderIDValue.name,
|
||||
&responderCert->subject) != SECSuccess)
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
|
||||
if (!CERT_GetSPKIDigest(tmpArena, responderCert, SEC_OID_SHA1,
|
||||
&rid->responderIDValue.keyHash))
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
|
||||
responderIDTemplate))
|
||||
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;
|
||||
|
||||
privKey = PK11_FindKeyByAnyCert(responderCert, wincx);
|
||||
if (!privKey)
|
||||
goto done;
|
||||
|
||||
algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
|
||||
if (algID == SEC_OID_UNKNOWN)
|
||||
goto done;
|
||||
|
||||
if (SEC_SignData(&br->responseSignature.signature,
|
||||
br->tbsResponseDataDER.data, br->tbsResponseDataDER.len,
|
||||
privKey, algID)
|
||||
!= SECSuccess)
|
||||
goto done;
|
||||
|
||||
/* convert len-in-bytes to len-in-bits */
|
||||
br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
|
||||
|
||||
/* br->responseSignature.signature wasn't allocated from arena,
|
||||
* we must free it when done. */
|
||||
}
|
||||
|
||||
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
|
||||
responderIDTemplate))
|
||||
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;
|
||||
|
||||
privKey = PK11_FindKeyByAnyCert(responderCert, wincx);
|
||||
if (!privKey)
|
||||
goto done;
|
||||
|
||||
algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
|
||||
if (algID == SEC_OID_UNKNOWN)
|
||||
goto done;
|
||||
|
||||
if (SEC_SignData(&br->responseSignature.signature,
|
||||
br->tbsResponseDataDER.data, br->tbsResponseDataDER.len,
|
||||
privKey, algID)
|
||||
!= SECSuccess)
|
||||
goto done;
|
||||
|
||||
/* convert len-in-bytes to len-in-bits */
|
||||
br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
|
||||
|
||||
/* br->responseSignature.signature wasn't allocated from arena,
|
||||
* we must free it when done. */
|
||||
|
||||
if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0)
|
||||
!= SECSuccess)
|
||||
goto done;
|
||||
!= SECSuccess)
|
||||
goto done;
|
||||
|
||||
if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br,
|
||||
ocsp_EncodeBasicOCSPResponseTemplate))
|
||||
|
||||
@ -159,6 +159,7 @@ SSL_SetSRTPCiphers;
|
||||
;+NSS_3.14.2 { # NSS 3.14.2 release
|
||||
;+ global:
|
||||
SSL_PeerStapledOCSPResponses;
|
||||
SSL_SetStapledOCSPResponses;
|
||||
;+ local:
|
||||
;+*;
|
||||
;+};
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
* 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/. */
|
||||
/* $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_
|
||||
#define __ssl_h_
|
||||
@ -416,6 +416,17 @@ SSL_IMPORT CERTCertificate *SSL_PeerCertificate(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
|
||||
** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* 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/. */
|
||||
/* $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. */
|
||||
|
||||
@ -49,6 +49,7 @@ static SECStatus ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss);
|
||||
static SECStatus ssl3_HandshakeFailure( sslSocket *ss);
|
||||
static SECStatus ssl3_InitState( sslSocket *ss);
|
||||
static SECStatus ssl3_SendCertificate( sslSocket *ss);
|
||||
static SECStatus ssl3_SendCertificateStatus( sslSocket *ss);
|
||||
static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss);
|
||||
static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
|
||||
static SECStatus ssl3_SendNextProto( sslSocket *ss);
|
||||
@ -6491,6 +6492,10 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
|
||||
if (rv != SECSuccess) {
|
||||
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,
|
||||
* because kea_def is set up by ssl3_SendServerHello().
|
||||
*/
|
||||
@ -8433,6 +8438,52 @@ ssl3_SendCertificate(sslSocket *ss)
|
||||
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
|
||||
* from the cert database after they've been validated.
|
||||
*/
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* 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 "nss.h"
|
||||
@ -61,6 +61,10 @@ static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
|
||||
PRUint32 maxBytes);
|
||||
static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
|
||||
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,
|
||||
PRUint16 ex_type,
|
||||
SECItem *data);
|
||||
@ -227,6 +231,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
|
||||
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
|
||||
{ ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
|
||||
{ ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
|
||||
{ ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
@ -669,6 +674,33 @@ ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
|
||||
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
|
||||
* client side. See RFC 4366 section 3.6. */
|
||||
static PRInt32
|
||||
@ -1705,6 +1737,22 @@ ssl3_SendRenegotiationInfoXtn(
|
||||
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. */
|
||||
static SECStatus
|
||||
ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* 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/. */
|
||||
/* $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_
|
||||
#define __sslimpl_h_
|
||||
@ -1178,6 +1178,7 @@ const unsigned char * preferredCipher;
|
||||
/* Configuration state for server sockets */
|
||||
/* server cert and key for each KEA type */
|
||||
sslServerCerts serverCerts[kt_kea_size];
|
||||
SECItemArray * certStatusArray;
|
||||
|
||||
ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED];
|
||||
ssl3KeyPair * ephemeralECDHKeyPair; /* for ECDHE-* handshake */
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
* 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/. */
|
||||
/* $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 "cert.h"
|
||||
#include "keyhi.h"
|
||||
@ -327,6 +327,8 @@ ssl_DupSocket(sslSocket *os)
|
||||
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.
|
||||
@ -438,6 +440,10 @@ 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) {
|
||||
@ -1688,6 +1694,13 @@ 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) {
|
||||
@ -1872,7 +1885,7 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
|
||||
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));
|
||||
return NULL;
|
||||
}
|
||||
@ -2222,6 +2235,34 @@ ssl_GetSockName(PRFileDesc *fd, PRNetAddr *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
|
||||
SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID)
|
||||
{
|
||||
@ -2229,7 +2270,7 @@ SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID)
|
||||
|
||||
ss = ssl_FindSocket(fd);
|
||||
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));
|
||||
return SECFailure;
|
||||
}
|
||||
@ -2922,6 +2963,7 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
|
||||
}
|
||||
ss->stepDownKeyPair = NULL;
|
||||
ss->dbHandle = CERT_GetDefaultCertDB();
|
||||
ss->certStatusArray = NULL;
|
||||
|
||||
/* Provide default implementation of hooks */
|
||||
ss->authCertificate = SSL_AuthCertificate;
|
||||
|
||||
@ -264,6 +264,7 @@ NSSUTIL_QuoteSize;
|
||||
;+NSSUTIL_3.14.2 { # NSS Utilities 3.14.2 release
|
||||
;+ global:
|
||||
SECITEM_AllocArray;
|
||||
SECITEM_DupArray;
|
||||
SECITEM_FreeArray;
|
||||
SECITEM_ZfreeArray;
|
||||
;+ local:
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
/*
|
||||
* 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"
|
||||
@ -392,3 +392,28 @@ void SECITEM_ZfreeArray(SECItemArray *array, PRBool 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;
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
* secitem.h - public data structures and prototypes for handling
|
||||
* 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"
|
||||
@ -93,6 +93,7 @@ PRIntn PR_CALLBACK SECITEM_HashCompare ( const void *k1, const void *k2);
|
||||
extern SECItemArray *SECITEM_AllocArray(PLArenaPool *arena,
|
||||
SECItemArray *array,
|
||||
unsigned int len);
|
||||
extern SECItemArray *SECITEM_DupArray(PLArenaPool *arena, const SECItemArray *from);
|
||||
extern void SECITEM_FreeArray(SECItemArray *array, PRBool freeit);
|
||||
extern void SECITEM_ZfreeArray(SECItemArray *array, PRBool freeit);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user