summaryrefslogtreecommitdiff
path: root/security/nss/lib/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/ssl')
-rw-r--r--security/nss/lib/ssl/Makefile82
-rw-r--r--security/nss/lib/ssl/authcert.c115
-rw-r--r--security/nss/lib/ssl/cmpcert.c117
-rw-r--r--security/nss/lib/ssl/config.mk44
-rw-r--r--security/nss/lib/ssl/emulate.c626
-rw-r--r--security/nss/lib/ssl/manifest.mn77
-rw-r--r--security/nss/lib/ssl/notes.txt161
-rw-r--r--security/nss/lib/ssl/nsskea.c75
-rw-r--r--security/nss/lib/ssl/preenc.h161
-rw-r--r--security/nss/lib/ssl/prelib.c253
-rw-r--r--security/nss/lib/ssl/ssl.h423
-rw-r--r--security/nss/lib/ssl/ssl3con.c7521
-rw-r--r--security/nss/lib/ssl/ssl3gthr.c228
-rw-r--r--security/nss/lib/ssl/ssl3prot.h307
-rw-r--r--security/nss/lib/ssl/sslauth.c257
-rw-r--r--security/nss/lib/ssl/sslcon.c3683
-rw-r--r--security/nss/lib/ssl/ssldef.c228
-rw-r--r--security/nss/lib/ssl/sslenum.c76
-rw-r--r--security/nss/lib/ssl/sslerr.c69
-rw-r--r--security/nss/lib/ssl/sslerr.h188
-rw-r--r--security/nss/lib/ssl/sslgathr.c481
-rw-r--r--security/nss/lib/ssl/sslimpl.h1250
-rw-r--r--security/nss/lib/ssl/sslnonce.c345
-rw-r--r--security/nss/lib/ssl/sslproto.h158
-rw-r--r--security/nss/lib/ssl/sslreveal.c97
-rw-r--r--security/nss/lib/ssl/sslsecur.c1372
-rw-r--r--security/nss/lib/ssl/sslsnce.c1905
-rw-r--r--security/nss/lib/ssl/sslsock.c1816
-rw-r--r--security/nss/lib/ssl/sslsocks.c1147
-rw-r--r--security/nss/lib/ssl/ssltrace.c269
-rw-r--r--security/nss/lib/ssl/unix_err.c536
-rw-r--r--security/nss/lib/ssl/unix_err.h87
-rw-r--r--security/nss/lib/ssl/win32err.c373
-rw-r--r--security/nss/lib/ssl/win32err.h81
34 files changed, 0 insertions, 24608 deletions
diff --git a/security/nss/lib/ssl/Makefile b/security/nss/lib/ssl/Makefile
deleted file mode 100644
index 577dc8ac6..000000000
--- a/security/nss/lib/ssl/Makefile
+++ /dev/null
@@ -1,82 +0,0 @@
-#! gmake
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-#
-# The Original Code is the Netscape security libraries.
-#
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation. Portions created by Netscape are
-# Copyright (C) 1994-2000 Netscape Communications Corporation. All
-# Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable
-# instead of those above. If you wish to allow use of your
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL. If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-ifeq ($(OS_ARCH),WINNT)
-CSRCS += win32err.c
-else
-CSRCS += unix_err.c
-endif
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/ssl/authcert.c b/security/nss/lib/ssl/authcert.c
deleted file mode 100644
index 5a9c45e5a..000000000
--- a/security/nss/lib/ssl/authcert.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * NSS utility functions
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "prerror.h"
-#include "secitem.h"
-#include "prnetdb.h"
-#include "cert.h"
-#include "nspr.h"
-#include "secder.h"
-#include "key.h"
-#include "nss.h"
-#include "ssl.h"
-#include "pk11func.h" /* for PK11_ function calls */
-
-/*
- * This callback used by SSL to pull client sertificate upon
- * server request
- */
-SECStatus
-NSS_GetClientAuthData(void * arg,
- PRFileDesc * socket,
- struct CERTDistNamesStr * caNames,
- struct CERTCertificateStr ** pRetCert,
- struct SECKEYPrivateKeyStr **pRetKey)
-{
- CERTCertificate * cert;
- SECKEYPrivateKey * privkey;
- char * chosenNickName = (char *)arg; /* CONST */
- void * proto_win = NULL;
- SECStatus rv = SECFailure;
-
- proto_win = SSL_RevealPinArg(socket);
-
- if (chosenNickName) {
- cert = PK11_FindCertFromNickname(chosenNickName, proto_win);
- if ( cert ) {
- privkey = PK11_FindKeyByAnyCert(cert, proto_win);
- if ( privkey ) {
- rv = SECSuccess;
- } else {
- CERT_DestroyCertificate(cert);
- }
- }
- } else { /* no name given, automatically find the right cert. */
- CERTCertNicknames * names;
- int i;
-
- names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(),
- SEC_CERT_NICKNAMES_USER, proto_win);
- if (names != NULL) {
- for (i = 0; i < names->numnicknames; i++) {
- cert = PK11_FindCertFromNickname(names->nicknames[i],proto_win);
- if ( !cert )
- continue;
- /* Only check unexpired certs */
- if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) !=
- secCertTimeValid ) {
- CERT_DestroyCertificate(cert);
- continue;
- }
- rv = NSS_CmpCertChainWCANames(cert, caNames);
- if ( rv == SECSuccess ) {
- privkey = PK11_FindKeyByAnyCert(cert, proto_win);
- if ( privkey )
- break;
- }
- rv = SECFailure;
- CERT_DestroyCertificate(cert);
- }
- CERT_FreeNicknames(names);
- }
- }
- if (rv == SECSuccess) {
- *pRetCert = cert;
- *pRetKey = privkey;
- }
- return rv;
-}
-
diff --git a/security/nss/lib/ssl/cmpcert.c b/security/nss/lib/ssl/cmpcert.c
deleted file mode 100644
index 5e557828e..000000000
--- a/security/nss/lib/ssl/cmpcert.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * NSS utility functions
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "prerror.h"
-#include "secitem.h"
-#include "prnetdb.h"
-#include "cert.h"
-#include "nspr.h"
-#include "secder.h"
-#include "key.h"
-#include "nss.h"
-
-/*
- * Look to see if any of the signers in the cert chain for "cert" are found
- * in the list of caNames.
- * Returns SECSuccess if so, SECFailure if not.
- */
-SECStatus
-NSS_CmpCertChainWCANames(CERTCertificate *cert, CERTDistNames *caNames)
-{
- SECItem * caname;
- CERTCertificate * curcert;
- CERTCertificate * oldcert;
- PRInt32 contentlen;
- int j;
- int headerlen;
- int depth;
- SECStatus rv;
- SECItem issuerName;
- SECItem compatIssuerName;
-
- depth=0;
- curcert = CERT_DupCertificate(cert);
-
- while( curcert ) {
- issuerName = curcert->derIssuer;
-
- /* compute an alternate issuer name for compatibility with 2.0
- * enterprise server, which send the CA names without
- * the outer layer of DER hearder
- */
- rv = DER_Lengths(&issuerName, &headerlen, (uint32 *)&contentlen);
- if ( rv == SECSuccess ) {
- compatIssuerName.data = &issuerName.data[headerlen];
- compatIssuerName.len = issuerName.len - headerlen;
- } else {
- compatIssuerName.data = NULL;
- compatIssuerName.len = 0;
- }
-
- for (j = 0; j < caNames->nnames; j++) {
- caname = &caNames->names[j];
- if (SECITEM_CompareItem(&issuerName, caname) == SECEqual) {
- rv = SECSuccess;
- CERT_DestroyCertificate(curcert);
- goto done;
- } else if (SECITEM_CompareItem(&compatIssuerName, caname) == SECEqual) {
- rv = SECSuccess;
- CERT_DestroyCertificate(curcert);
- goto done;
- }
- }
- if ( ( depth <= 20 ) &&
- ( SECITEM_CompareItem(&curcert->derIssuer, &curcert->derSubject)
- != SECEqual ) ) {
- oldcert = curcert;
- curcert = CERT_FindCertByName(curcert->dbhandle,
- &curcert->derIssuer);
- CERT_DestroyCertificate(oldcert);
- depth++;
- } else {
- CERT_DestroyCertificate(curcert);
- curcert = NULL;
- }
- }
- rv = SECFailure;
-
-done:
- return rv;
-}
-
diff --git a/security/nss/lib/ssl/config.mk b/security/nss/lib/ssl/config.mk
deleted file mode 100644
index a73a1086e..000000000
--- a/security/nss/lib/ssl/config.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-#
-# The Original Code is the Netscape security libraries.
-#
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation. Portions created by Netscape are
-# Copyright (C) 1994-2000 Netscape Communications Corporation. All
-# Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable
-# instead of those above. If you wish to allow use of your
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL. If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PURE_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/ssl/emulate.c b/security/nss/lib/ssl/emulate.c
deleted file mode 100644
index bb6efc140..000000000
--- a/security/nss/lib/ssl/emulate.c
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Functions that emulate PR_AcceptRead and PR_TransmitFile for SSL sockets.
- * Each Layered NSPR protocol (like SSL) must unfortunately contain its
- * own implementation of these functions. This code was taken from NSPR.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "nspr.h"
-
-#if defined( XP_UNIX )
-#include <fcntl.h>
-#endif
-#if defined(WIN32)
-#include <windef.h>
-#include <winbase.h>
-#endif
-#include <string.h>
-
-#define AMASK 7 /* mask for alignment of PRNetAddr */
-
-/*
- * _PR_EmulateAcceptRead
- *
- * Accept an incoming connection on sd, set *nd to point to the
- * newly accepted socket, read 'amount' bytes from the accepted
- * socket.
- *
- * buf is a buffer of length = amount + (2 * sizeof(PRNetAddr)) + 32
- * *raddr points to the PRNetAddr of the accepted connection upon
- * return
- *
- * return number of bytes read or -1 on error
- *
- */
-PRInt32
-ssl_EmulateAcceptRead( PRFileDesc * sd,
- PRFileDesc ** nd,
- PRNetAddr ** raddr,
- void * buf,
- PRInt32 amount,
- PRIntervalTime timeout)
-{
- PRFileDesc * newsockfd;
- PRInt32 rv;
- PRNetAddr remote;
-
- if (!(newsockfd = PR_Accept(sd, &remote, PR_INTERVAL_NO_TIMEOUT))) {
- return -1;
- }
-
- rv = PR_Recv(newsockfd, buf, amount, 0, timeout);
- if (rv >= 0) {
- ptrdiff_t pNetAddr = (((ptrdiff_t)buf) + amount + AMASK) & ~AMASK;
-
- *nd = newsockfd;
- *raddr = (PRNetAddr *)pNetAddr;
- memcpy((void *)pNetAddr, &remote, sizeof(PRNetAddr));
- return rv;
- }
-
- PR_Close(newsockfd);
- return -1;
-}
-
-
-#if !defined( XP_UNIX ) && !defined( WIN32 )
-/*
- * _PR_EmulateTransmitFile
- *
- * Send file fd across socket sd. If headers is non-NULL, 'hlen'
- * bytes of headers is sent before sending the file.
- *
- * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
- *
- * return number of bytes sent or -1 on error
- *
- */
-#define _TRANSMITFILE_BUFSIZE (16 * 1024)
-
-PRInt32
-ssl_EmulateTransmitFile( PRFileDesc * sd,
- PRFileDesc * fd,
- const void * headers,
- PRInt32 hlen,
- PRTransmitFileFlags flags,
- PRIntervalTime timeout)
-{
- char * buf = NULL;
- PRInt32 count = 0;
- PRInt32 rlen;
- PRInt32 rv;
-
- buf = PR_MALLOC(_TRANSMITFILE_BUFSIZE);
- if (buf == NULL) {
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
- return -1;
- }
-
- /*
- * send headers, first
- */
- while (hlen) {
- rv = PR_Send(sd, headers, hlen, 0, timeout);
- if (rv < 0) {
- /* PR_Send() has invoked PR_SetError(). */
- rv = -1;
- goto done;
- }
- count += rv;
- headers = (const void*) ((const char*)headers + rv);
- hlen -= rv;
- }
- /*
- * send file, next
- */
- while ((rlen = PR_Read(fd, buf, _TRANSMITFILE_BUFSIZE)) > 0) {
- while (rlen) {
- char *bufptr = buf;
-
- rv = PR_Send(sd, bufptr, rlen,0,PR_INTERVAL_NO_TIMEOUT);
- if (rv < 0) {
- /* PR_Send() has invoked PR_SetError(). */
- rv = -1;
- goto done;
- }
- count += rv;
- bufptr = ((char*)bufptr + rv);
- rlen -= rv;
- }
- }
- if (rlen == 0) {
- /*
- * end-of-file
- */
- if (flags & PR_TRANSMITFILE_CLOSE_SOCKET)
- PR_Close(sd);
- rv = count;
- } else {
- PR_ASSERT(rlen < 0);
- /* PR_Read() has invoked PR_SetError(). */
- rv = -1;
- }
-
-done:
- if (buf)
- PR_DELETE(buf);
- return rv;
-}
-#else
-
-#define TRANSMITFILE_MMAP_CHUNK (256 * 1024)
-
-/*
- * _PR_UnixTransmitFile
- *
- * Send file fd across socket sd. If headers is non-NULL, 'hlen'
- * bytes of headers is sent before sending the file.
- *
- * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
- *
- * return number of bytes sent or -1 on error
- *
- */
-
-PRInt32
-ssl_EmulateTransmitFile( PRFileDesc * sd,
- PRFileDesc * fd,
- const void * headers,
- PRInt32 hlen,
- PRTransmitFileFlags flags,
- PRIntervalTime timeout)
-{
- void * addr;
- PRFileMap * mapHandle = NULL;
- PRInt32 count = 0;
- PRInt32 index = 0;
- PRInt32 len = 0;
- PRInt32 rv;
- struct PRFileInfo info;
- struct PRIOVec iov[2];
-
- /* Get file size */
- if (PR_SUCCESS != PR_GetOpenFileInfo(fd, &info)) {
- count = -1;
- goto done;
- }
- if (hlen) {
- iov[index].iov_base = (char *) headers;
- iov[index].iov_len = hlen;
- index++;
- }
- if (info.size > 0) {
- mapHandle = PR_CreateFileMap(fd, info.size, PR_PROT_READONLY);
- if (mapHandle == NULL) {
- count = -1;
- goto done;
- }
- /*
- * If the file is large, mmap and send the file in chunks so as
- * to not consume too much virtual address space
- */
- len = PR_MIN(info.size , TRANSMITFILE_MMAP_CHUNK );
- /*
- * Map in (part of) file. Take care of zero-length files.
- */
- if (len) {
- addr = PR_MemMap(mapHandle, 0, len);
- if (addr == NULL) {
- count = -1;
- goto done;
- }
- }
- iov[index].iov_base = (char*)addr;
- iov[index].iov_len = len;
- index++;
- }
- if (!index)
- goto done;
- rv = PR_Writev(sd, iov, index, timeout);
- if (len) {
- PR_MemUnmap(addr, len);
- }
- if (rv >= 0) {
- PR_ASSERT(rv == hlen + len);
- info.size -= len;
- count += rv;
- } else {
- count = -1;
- goto done;
- }
- /*
- * send remaining bytes of the file, if any
- */
- len = PR_MIN(info.size , TRANSMITFILE_MMAP_CHUNK );
- while (len > 0) {
- /*
- * Map in (part of) file
- */
- PR_ASSERT((count - hlen) % TRANSMITFILE_MMAP_CHUNK == 0);
- addr = PR_MemMap(mapHandle, count - hlen, len);
- if (addr == NULL) {
- count = -1;
- goto done;
- }
- rv = PR_Send(sd, addr, len, 0, timeout);
- PR_MemUnmap(addr, len);
- if (rv >= 0) {
- PR_ASSERT(rv == len);
- info.size -= rv;
- count += rv;
- len = PR_MIN(info.size , TRANSMITFILE_MMAP_CHUNK );
- } else {
- count = -1;
- goto done;
- }
- }
-done:
- if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET))
- PR_Close(sd);
- if (mapHandle != NULL)
- PR_CloseFileMap(mapHandle);
- return count;
-}
-#endif /* XP_UNIX */
-
-
-
-
-#if !defined( XP_UNIX ) && !defined( WIN32 )
-/*
- * _PR_EmulateSendFile
- *
- * Send file sfd->fd across socket sd. The header and trailer buffers
- * specified in the 'sfd' argument are sent before and after the file,
- * respectively.
- *
- * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
- *
- * return number of bytes sent or -1 on error
- *
- */
-
-PRInt32
-ssl_EmulateSendFile(PRFileDesc *sd, PRSendFileData *sfd,
- PRTransmitFileFlags flags, PRIntervalTime timeout)
-{
- char * buf = NULL;
- const void * buffer;
- PRInt32 rv;
- PRInt32 count = 0;
- PRInt32 rlen;
- PRInt32 buflen;
- PRInt32 sendbytes;
- PRInt32 readbytes;
-
-#define _SENDFILE_BUFSIZE (16 * 1024)
-
- buf = (char*)PR_MALLOC(_SENDFILE_BUFSIZE);
- if (buf == NULL) {
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
- return -1;
- }
-
- /*
- * send header, first
- */
- buflen = sfd->hlen;
- buffer = sfd->header;
- while (buflen) {
- rv = PR_Send(sd, buffer, buflen, 0, timeout);
- if (rv < 0) {
- /* PR_Send() has invoked PR_SetError(). */
- rv = -1;
- goto done;
- } else {
- count += rv;
- buffer = (const void*) ((const char*)buffer + rv);
- buflen -= rv;
- }
- }
- /*
- * send file, next
- */
-
- if (PR_Seek(sfd->fd, sfd->file_offset, PR_SEEK_SET) < 0) {
- rv = -1;
- goto done;
- }
- sendbytes = sfd->file_nbytes;
- if (sendbytes == 0) {
- /* send entire file */
- while ((rlen = PR_Read(sfd->fd, buf, _SENDFILE_BUFSIZE)) > 0) {
- while (rlen) {
- char *bufptr = buf;
-
- rv = PR_Send(sd, bufptr, rlen, 0, timeout);
- if (rv < 0) {
- /* PR_Send() has invoked PR_SetError(). */
- rv = -1;
- goto done;
- } else {
- count += rv;
- bufptr = ((char*)bufptr + rv);
- rlen -= rv;
- }
- }
- }
- if (rlen < 0) {
- /* PR_Read() has invoked PR_SetError(). */
- rv = -1;
- goto done;
- }
- } else {
- readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE);
- while (readbytes && ((rlen = PR_Read(sfd->fd, buf, readbytes)) > 0)) {
- while (rlen) {
- char *bufptr = buf;
-
- rv = PR_Send(sd, bufptr, rlen, 0, timeout);
- if (rv < 0) {
- /* PR_Send() has invoked PR_SetError(). */
- rv = -1;
- goto done;
- } else {
- count += rv;
- sendbytes -= rv;
- bufptr = ((char*)bufptr + rv);
- rlen -= rv;
- }
- }
- readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE);
- }
- if (rlen < 0) {
- /* PR_Read() has invoked PR_SetError(). */
- rv = -1;
- goto done;
- } else if (sendbytes != 0) {
- /*
- * there are fewer bytes in file to send than specified
- */
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- rv = -1;
- goto done;
- }
- }
- /*
- * send trailer, last
- */
- buflen = sfd->tlen;
- buffer = sfd->trailer;
- while (buflen) {
- rv = PR_Send(sd, buffer, buflen, 0, timeout);
- if (rv < 0) {
- /* PR_Send() has invoked PR_SetError(). */
- rv = -1;
- goto done;
- } else {
- count += rv;
- buffer = (const void*) ((const char*)buffer + rv);
- buflen -= rv;
- }
- }
- rv = count;
-
-done:
- if (buf)
- PR_DELETE(buf);
- if ((rv >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET))
- PR_Close(sd);
- return rv;
-}
-
-#else /* UNIX and NT handled below */
-
-/*
- * _PR_UnixSendFile
- *
- * Send file sfd->fd across socket sd. If header/trailer are specified
- * they are sent before and after the file, respectively.
- *
- * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
- *
- * return number of bytes sent or -1 on error
- *
- */
-#define SENDFILE_MMAP_CHUNK (256 * 1024)
-
-PRInt32
-ssl_EmulateSendFile(PRFileDesc *sd, PRSendFileData *sfd,
- PRTransmitFileFlags flags, PRIntervalTime timeout)
-{
- void * addr;
- PRFileMap * mapHandle = NULL;
- PRInt32 count = 0;
- PRInt32 file_bytes;
- PRInt32 index = 0;
- PRInt32 len;
- PRInt32 rv;
- PRUint32 addr_offset;
- PRUint32 file_mmap_offset;
- PRUint32 mmap_len;
- PRUint32 pagesize;
- struct PRFileInfo info;
- struct PRIOVec iov[3];
-
- /* Get file size */
- if (PR_SUCCESS != PR_GetOpenFileInfo(sfd->fd, &info)) {
- count = -1;
- goto done;
- }
- if (sfd->file_nbytes &&
- (info.size < (sfd->file_offset + sfd->file_nbytes))) {
- /*
- * there are fewer bytes in file to send than specified
- */
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- count = -1;
- goto done;
- }
- if (sfd->file_nbytes)
- file_bytes = sfd->file_nbytes;
- else
- file_bytes = info.size - sfd->file_offset;
-
-#if defined(WIN32)
- {
- SYSTEM_INFO sysinfo;
- GetSystemInfo(&sysinfo);
- pagesize = sysinfo.dwAllocationGranularity;
- }
-#else
- pagesize = PR_GetPageSize();
-#endif
- /*
- * If the file is large, mmap and send the file in chunks so as
- * to not consume too much virtual address space
- */
- if (!sfd->file_offset || !(sfd->file_offset & (pagesize - 1))) {
- /*
- * case 1: page-aligned file offset
- */
- mmap_len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK);
- len = mmap_len;
- file_mmap_offset = sfd->file_offset;
- addr_offset = 0;
- } else {
- /*
- * case 2: non page-aligned file offset
- */
- /* find previous page boundary */
- file_mmap_offset = (sfd->file_offset & ~(pagesize - 1));
-
- /* number of initial bytes to skip in mmap'd segment */
- addr_offset = sfd->file_offset - file_mmap_offset;
- PR_ASSERT(addr_offset > 0);
- mmap_len = PR_MIN(file_bytes + addr_offset, SENDFILE_MMAP_CHUNK);
- len = mmap_len - addr_offset;
- }
- /*
- * Map in (part of) file. Take care of zero-length files.
- */
- if (len > 0) {
- mapHandle = PR_CreateFileMap(sfd->fd, info.size, PR_PROT_READONLY);
- if (!mapHandle) {
- count = -1;
- goto done;
- }
- addr = PR_MemMap(mapHandle, file_mmap_offset, mmap_len);
- if (!addr) {
- count = -1;
- goto done;
- }
- }
- /*
- * send headers, first, followed by the file
- */
- if (sfd->hlen) {
- iov[index].iov_base = (char *) sfd->header;
- iov[index].iov_len = sfd->hlen;
- index++;
- }
- if (len) {
- iov[index].iov_base = (char*)addr + addr_offset;
- iov[index].iov_len = len;
- index++;
- }
- if ((file_bytes == len) && (sfd->tlen)) {
- /*
- * all file data is mapped in; send the trailer too
- */
- iov[index].iov_base = (char *) sfd->trailer;
- iov[index].iov_len = sfd->tlen;
- index++;
- }
- rv = PR_Writev(sd, iov, index, timeout);
- if (len)
- PR_MemUnmap(addr, mmap_len);
- if (rv < 0) {
- count = -1;
- goto done;
- }
-
- PR_ASSERT(rv == sfd->hlen + len + ((len == file_bytes) ? sfd->tlen : 0));
-
- file_bytes -= len;
- count += rv;
- if (!file_bytes) /* header, file and trailer are sent */
- goto done;
-
- /*
- * send remaining bytes of the file, if any
- */
- len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK);
- while (len > 0) {
- /*
- * Map in (part of) file
- */
- file_mmap_offset = sfd->file_offset + count - sfd->hlen;
- PR_ASSERT((file_mmap_offset % pagesize) == 0);
-
- addr = PR_MemMap(mapHandle, file_mmap_offset, len);
- if (!addr) {
- count = -1;
- goto done;
- }
- rv = PR_Send(sd, addr, len, 0, timeout);
- PR_MemUnmap(addr, len);
- if (rv < 0) {
- count = -1;
- goto done;
- }
-
- PR_ASSERT(rv == len);
- file_bytes -= rv;
- count += rv;
- len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK);
- }
- PR_ASSERT(0 == file_bytes);
- if (sfd->tlen) {
- rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout);
- if (rv >= 0) {
- PR_ASSERT(rv == sfd->tlen);
- count += rv;
- } else
- count = -1;
- }
-done:
- if (mapHandle)
- PR_CloseFileMap(mapHandle);
- if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET))
- PR_Close(sd);
- return count;
-}
-#endif /* UNIX and NT */
diff --git a/security/nss/lib/ssl/manifest.mn b/security/nss/lib/ssl/manifest.mn
deleted file mode 100644
index 5e1d50719..000000000
--- a/security/nss/lib/ssl/manifest.mn
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-#
-# The Original Code is the Netscape security libraries.
-#
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation. Portions created by Netscape are
-# Copyright (C) 1994-2000 Netscape Communications Corporation. All
-# Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable
-# instead of those above. If you wish to allow use of your
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL. If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-CORE_DEPTH = ../../..
-
-# DEFINES = -DTRACE
-
-
-PRIVATE_EXPORTS = \
- ssl3prot.h \
- sslimpl.h \
- $(NULL)
-
-EXPORTS = \
- ssl.h \
- sslerr.h \
- sslproto.h \
- preenc.h \
- $(NULL)
-
-MODULE = security
-
-CSRCS = \
- emulate.c \
- prelib.c \
- ssl3con.c \
- ssl3gthr.c \
- sslauth.c \
- sslcon.c \
- ssldef.c \
- sslenum.c \
- sslerr.c \
- sslgathr.c \
- sslnonce.c \
- sslreveal.c \
- sslsecur.c \
- sslsnce.c \
- sslsock.c \
- sslsocks.c \
- ssltrace.c \
- authcert.c \
- cmpcert.c \
- nsskea.c \
- $(NULL)
-
-REQUIRES = security dbm
-
-LIBRARY_NAME = ssl
diff --git a/security/nss/lib/ssl/notes.txt b/security/nss/lib/ssl/notes.txt
deleted file mode 100644
index a36f242ee..000000000
--- a/security/nss/lib/ssl/notes.txt
+++ /dev/null
@@ -1,161 +0,0 @@
-The contents of this file are subject to the Mozilla Public
-License Version 1.1 (the "License"); you may not use this file
-except in compliance with the License. You may obtain a copy of
-the License at http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS
-IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-implied. See the License for the specific language governing
-rights and limitations under the License.
-
-The Original Code is the Netscape security libraries.
-
-The Initial Developer of the Original Code is Netscape
-Communications Corporation. Portions created by Netscape are
-Copyright (C) 1994-2000 Netscape Communications Corporation. All
-Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the
-terms of the GNU General Public License Version 2 or later (the
-"GPL"), in which case the provisions of the GPL are applicable
-instead of those above. If you wish to allow use of your
-version of this file only under the terms of the GPL and not to
-allow others to use your version of this file under the MPL,
-indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by
-the GPL. If you do not delete the provisions above, a recipient
-may use your version of this file under either the MPL or the
-GPL.
-
-SSL's Buffers: enumerated and explained.
-
----------------------------------------------------------------------------
-incoming:
-
-gs = ss->gather
-hs = ss->ssl3->hs
-
-gs->inbuf SSL3 only: incoming (encrypted) ssl records are placed here,
- and then decrypted (or copied) to gs->buf.
-
-gs->buf SSL2: incoming SSL records are put here, and then decrypted
- in place.
- SSL3: ssl3_HandleHandshake puts decrypted ssl records here.
-
-hs.msg_body (SSL3 only) When an incoming handshake message spans more
- than one ssl record, the first part(s) of it are accumulated
- here until it all arrives.
-
-hs.msgState (SSL3 only) an alternative set of pointers/lengths for gs->buf.
- Used only when a handleHandshake function returns SECWouldBlock.
- ssl3_HandleHandshake remembers how far it previously got by
- using these pointers instead of gs->buf when it is called
- after a previous SECWouldBlock return.
-
----------------------------------------------------------------------------
-outgoing:
-
-sec = ss->sec
-ci = ss->sec->ci /* connect info */
-
-ci->sendBuf Outgoing handshake messages are appended to this buffer.
- This buffer will then be sent as a single SSL record.
-
-sec->writeBuf outgoing ssl records are constructed here and encrypted in
- place before being written or copied to pendingBuf.
-
-ss->pendingBuf contains outgoing ciphertext that was saved after a write
- attempt to the socket failed, e.g. EWouldBlock.
- Generally empty with blocking sockets (should be no incomplete
- writes).
-
-ss->saveBuf Used only by socks code. Intended to be used to buffer
- outgoing data until a socks handshake completes. However,
- this buffer is always empty. There is no code to put
- anything into it.
-
----------------------------------------------------------------------------
-
-SECWouldBlock means that the function cannot make progress because it is
-waiting for some event OTHER THAN socket I/O completion (e.g. waiting for
-user dialog to finish). It is not the same as EWOULDBLOCK.
-
----------------------------------------------------------------------------
-
-Rank (order) of locks
-
-[ReadLock ->]\ [firstHandshake ->] [ssl3Handshake ->] recvbuf \ -> "spec"
-[WriteLock->]/ xmitbuf /
-
-crypto and hash Data that must be protected while turning plaintext into
-ciphertext:
-
-SSL2: (in ssl2_Send*)
- sec->hash*
- sec->hashcx (ptr and data)
- sec->enc
- sec->writecx* (ptr and content)
- sec->sendSecret*(ptr and content)
- sec->sendSequence locked by xmitBufLock
- sec->blockSize
- sec->writeBuf* (ptr & content) locked by xmitBufLock
- "in" locked by xmitBufLock
-
-SSl3: (in ssl3_SendPlainText)
- ss->ssl3 (the pointer)
- ss->ssl3->current_write* (the pointer and the data in the spec
- and any data referenced by the spec.
-
- ss->sec->isServer
- ss->sec->writebuf* (ptr & content) locked by xmitBufLock
- "buf" locked by xmitBufLock
-
-crypto and hash data that must be protected while turning ciphertext into
-plaintext:
-
-SSL2: (in ssl2_GatherData)
- gs->* (locked by recvBufLock )
- sec->dec
- sec->readcx
- sec->hash* (ptr and data)
- sec->hashcx (ptr and data)
-
-SSL3: (in ssl3_HandleRecord )
- ssl3->current_read* (the pointer and all data refernced)
- ss->sec->isServer
-
-
-Data that must be protected while being used by a "writer":
-
-ss->pendingBuf.*
-ss->saveBuf.* (which is dead)
-
-in ssl3_sendPlainText
-
-ss->ssl3->current_write-> (spec)
-ss->sec->writeBuf.*
-ss->sec->isServer
-
-in SendBlock
-
-ss->sec->hash->length
-ss->sec->blockSize
-ss->sec->writeBuf.*
-ss->sec->sendSecret
-ss->sec->sendSequence
-ss->sec->writecx *
-ss->pendingBuf
-
---------------------------------------------------------------------------
-
-Data variables (not const) protected by the "sslGlobalDataLock".
-Note, this really should be a reader/writer lock.
-
-allowedByPolicy sslcon.c
-maybeAllowedByPolicy sslcon.c
-chosenPreference sslcon.c
-policyWasSet sslcon.c
-
-cipherSuites[] ssl3con.c
diff --git a/security/nss/lib/ssl/nsskea.c b/security/nss/lib/ssl/nsskea.c
deleted file mode 100644
index ec7be1735..000000000
--- a/security/nss/lib/ssl/nsskea.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Return SSLKEAType derived from cert's Public Key algorithm info.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- # $Id$
- */
-
-#include "cert.h"
-#include "ssl.h" /* for SSLKEAType */
-#include "secoid.h"
-
-SSLKEAType
-NSS_FindCertKEAType(CERTCertificate * cert)
-{
- SSLKEAType keaType = kt_null;
- int tag;
-
- if (!cert) goto loser;
-
- tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
-
- switch (tag) {
- case SEC_OID_X500_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- keaType = kt_rsa;
- break;
- case SEC_OID_MISSI_KEA_DSS_OLD:
- case SEC_OID_MISSI_KEA_DSS:
- case SEC_OID_MISSI_DSS_OLD:
- case SEC_OID_MISSI_DSS:
- keaType = kt_fortezza;
- break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- keaType = kt_dh;
- break;
- default:
- keaType = kt_null;
- }
-
- loser:
-
- return keaType;
-
-}
-
diff --git a/security/nss/lib/ssl/preenc.h b/security/nss/lib/ssl/preenc.h
deleted file mode 100644
index 3dfbe1e92..000000000
--- a/security/nss/lib/ssl/preenc.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-
-/*
- * Functions and types used by https servers to send (download) pre-encrypted
- * files over SSL connections that use Fortezza ciphersuites.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "seccomon.h"
-#include "prio.h"
-
-typedef struct PEHeaderStr PEHeader;
-
-#define PE_MIME_TYPE "application/pre-encrypted"
-
-
-/*
- * unencrypted header. The 'top' half of this header is generic. The union
- * is type specific, and may include bulk cipher type information
- * (Fortezza supports only Fortezza Bulk encryption). Only fortezza
- * pre-encrypted is defined.
- */
-typedef struct PEFortezzaHeaderStr PEFortezzaHeader;
-typedef struct PEFortezzaGeneratedHeaderStr PEFortezzaGeneratedHeader;
-typedef struct PEFixedKeyHeaderStr PEFixedKeyHeader;
-typedef struct PERSAKeyHeaderStr PERSAKeyHeader;
-
-struct PEFortezzaHeaderStr {
- unsigned char key[12]; /* Ks wrapped MEK */
- unsigned char iv[24]; /* iv for this MEK */
- unsigned char hash[20]; /* SHA hash of file */
- unsigned char serial[8]; /* serial number of the card that owns
- * Ks */
-};
-
-struct PEFortezzaGeneratedHeaderStr {
- unsigned char key[12]; /* TEK wrapped MEK */
- unsigned char iv[24]; /* iv for this MEK */
- unsigned char hash[20]; /* SHA hash of file */
- unsigned char Ra[128]; /* RA to generate TEK */
- unsigned char Y[128]; /* Y to generate TEK */
-};
-
-struct PEFixedKeyHeaderStr {
- unsigned char pkcs11Mech[4]; /* Symetric key operation */
- unsigned char labelLen[2]; /* length of the token label */
- unsigned char keyIDLen[2]; /* length of the token Key ID */
- unsigned char ivLen[2]; /* length of IV */
- unsigned char keyLen[2]; /* length of key (DES3_ECB encrypted) */
- unsigned char data[1]; /* start of data */
-};
-
-struct PERSAKeyHeaderStr {
- unsigned char pkcs11Mech[4]; /* Symetric key operation */
- unsigned char issuerLen[2]; /* length of cert issuer */
- unsigned char serialLen[2]; /* length of the cert serial */
- unsigned char ivLen[2]; /* length of IV */
- unsigned char keyLen[2]; /* length of key (RSA encrypted) */
- unsigned char data[1]; /* start of data */
-};
-
-/* macros to get at the variable length data fields */
-#define PEFIXED_Label(header) (header->data)
-#define PEFIXED_KeyID(header) (&header->data[GetInt2(header->labelLen)])
-#define PEFIXED_IV(header) (&header->data[GetInt2(header->labelLen)\
- +GetInt2(header->keyIDLen)])
-#define PEFIXED_Key(header) (&header->data[GetInt2(header->labelLen)\
- +GetInt2(header->keyIDLen)+GetInt2(header->keyLen)])
-#define PERSA_Issuer(header) (header->data)
-#define PERSA_Serial(header) (&header->data[GetInt2(header->issuerLen)])
-#define PERSA_IV(header) (&header->data[GetInt2(header->issuerLen)\
- +GetInt2(header->serialLen)])
-#define PERSA_Key(header) (&header->data[GetInt2(header->issuerLen)\
- +GetInt2(header->serialLen)+GetInt2(header->keyLen)])
-struct PEHeaderStr {
- unsigned char magic [2]; /* always 0xC0DE */
- unsigned char len [2]; /* length of PEHeader */
- unsigned char type [2]; /* FORTEZZA, DIFFIE-HELMAN, RSA */
- unsigned char version[2]; /* version number: 1.0 */
- union {
- PEFortezzaHeader fortezza;
- PEFortezzaGeneratedHeader g_fortezza;
- PEFixedKeyHeader fixed;
- PERSAKeyHeader rsa;
- } u;
-};
-
-#define PE_CRYPT_INTRO_LEN 8
-#define PE_INTRO_LEN 4
-#define PE_BASE_HEADER_LEN 8
-
-#define PRE_BLOCK_SIZE 8 /* for decryption blocks */
-
-
-/*
- * Platform neutral encode/decode macros.
- */
-#define GetInt2(c) ((c[0] << 8) | c[1])
-#define GetInt4(c) (((unsigned long)c[0] << 24)|((unsigned long)c[1] << 16)\
- |((unsigned long)c[2] << 8)| ((unsigned long)c[3]))
-#define PutInt2(c,i) ((c[1] = (i) & 0xff), (c[0] = ((i) >> 8) & 0xff))
-#define PutInt4(c,i) ((c[0]=((i) >> 24) & 0xff),(c[1]=((i) >> 16) & 0xff),\
- (c[2] = ((i) >> 8) & 0xff), (c[3] = (i) & 0xff))
-
-/*
- * magic numbers.
- */
-#define PRE_MAGIC 0xc0de
-#define PRE_VERSION 0x1010
-#define PRE_FORTEZZA_FILE 0x00ff /* pre-encrypted file on disk */
-#define PRE_FORTEZZA_STREAM 0x00f5 /* pre-encrypted file in stream */
-#define PRE_FORTEZZA_GEN_STREAM 0x00f6 /* Generated pre-encrypted file */
-#define PRE_FIXED_FILE 0x000f /* fixed key on disk */
-#define PRE_RSA_FILE 0x001f /* RSA in file */
-#define PRE_FIXED_STREAM 0x0005 /* fixed key in stream */
-
-/*
- * internal implementation info
- */
-
-
-/* convert an existing stream header to a version with local parameters */
-PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *,
- int *headerSize);
-
-/* convert an existing file header to one suitable for streaming out */
-PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *,
- int *headerSize);
-
diff --git a/security/nss/lib/ssl/prelib.c b/security/nss/lib/ssl/prelib.c
deleted file mode 100644
index b6ea428e2..000000000
--- a/security/nss/lib/ssl/prelib.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-
-/*
- * Functions used by https servers to send (download) pre-encrypted files
- * over SSL connections that use Fortezza ciphersuites.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "cert.h"
-#include "ssl.h"
-#include "keyhi.h"
-#include "secitem.h"
-#include "sslimpl.h"
-#include "pkcs11t.h"
-#include "preenc.h"
-#include "pk11func.h"
-
-static unsigned char fromHex(char x) {
- if ((x >= '0') && (x <= '9')) return x-'0';
- if ((x >= 'a') && (x <= 'f')) return x-'a'+10;
- return x-'A'+10;
-}
-
-PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *inHeader,
- int *headerSize)
-{
- PK11SymKey *key, *tek, *Ks;
- sslSocket *ss;
- PK11SlotInfo *slot;
- CK_TOKEN_INFO info;
- int oldHeaderSize;
- PEHeader *header;
- SECStatus rv;
- SECItem item;
- int i;
-
- if (fd == NULL) {
- /* XXX set an error */
- return NULL;
- }
-
- ss = ssl_FindSocket(fd);
- if (ss == NULL) {
- /* XXX set an error */
- return NULL;
- }
-
- PORT_Assert(ss->ssl3 != NULL);
- if (ss->ssl3 == NULL) {
- return NULL;
- }
-
- if (GetInt2(inHeader->magic) != PRE_MAGIC) {
- return NULL;
- }
-
- oldHeaderSize = GetInt2(inHeader->len);
- header = (PEHeader *) PORT_ZAlloc(oldHeaderSize);
- if (header == NULL) {
- return NULL;
- }
-
- switch (GetInt2(inHeader->type)) {
- case PRE_FORTEZZA_FILE:
- case PRE_FORTEZZA_GEN_STREAM:
- case PRE_FIXED_FILE:
- case PRE_RSA_FILE:
- default:
- *headerSize = oldHeaderSize;
- PORT_Memcpy(header,inHeader,oldHeaderSize);
- return header;
-
- case PRE_FORTEZZA_STREAM:
- *headerSize = PE_BASE_HEADER_LEN + sizeof(PEFortezzaHeader);
- PutInt2(header->magic,PRE_MAGIC);
- PutInt2(header->len,*headerSize);
- PutInt2(header->type, PRE_FORTEZZA_FILE);
- PORT_Memcpy(header->version,inHeader->version,sizeof(header->version));
- PORT_Memcpy(header->u.fortezza.hash,inHeader->u.fortezza.hash,
- sizeof(header->u.fortezza.hash));
- PORT_Memcpy(header->u.fortezza.iv,inHeader->u.fortezza.iv,
- sizeof(header->u.fortezza.iv));
-
- /* get the kea context from the session */
- tek = ss->ssl3->fortezza.tek;
- if (tek == NULL) {
- PORT_Free(header);
- return NULL;
- }
-
-
- /* get the slot and the serial number */
- slot = PK11_GetSlotFromKey(tek);
- if (slot == NULL) {
- PORT_Free(header);
- return NULL;
- }
- rv = PK11_GetTokenInfo(slot,&info);
- if (rv != SECSuccess) {
- PORT_Free(header);
- PK11_FreeSlot(slot);
- return NULL;
- }
-
- /* Look up the Token Fixed Key */
- Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL, ss->pkcs11PinArg);
- PK11_FreeSlot(slot);
- if (Ks == NULL) {
- PORT_Free(header);
- return NULL;
- }
-
- /* unwrap the key with the TEK */
- item.data = inHeader->u.fortezza.key;
- item.len = sizeof(inHeader->u.fortezza.key);
- key = PK11_UnwrapSymKey(tek,CKM_SKIPJACK_WRAP,
- NULL, &item, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
- if (key == NULL) {
- PORT_Free(header);
- PK11_FreeSymKey(Ks);
- return NULL;
- }
-
- /* rewrap with the local Ks */
- item.data = header->u.fortezza.key;
- item.len = sizeof(header->u.fortezza.key);
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, Ks, key, &item);
- PK11_FreeSymKey(Ks);
- PK11_FreeSymKey(key);
- if (rv != SECSuccess) {
- PORT_Free(header);
- return NULL;
- }
-
- /* copy our local serial number into header */
- for (i=0; i < sizeof(header->u.fortezza.serial); i++) {
- header->u.fortezza.serial[i] =
- (fromHex(info.serialNumber[i*2]) << 4) |
- fromHex(info.serialNumber[i*2 + 1]);
- }
- break;
- case PRE_FIXED_STREAM:
- /* not implemented yet */
- PORT_Free(header);
- return NULL;
- }
-
- return(header);
-}
-
-/*
- * this one needs to allocate space and work for RSA & FIXED key files as well
- */
-PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *header,
- int *headerSize)
-{
- PK11SymKey *key, *tek, *Ks;
- sslSocket *ss;
- PK11SlotInfo *slot;
- SECStatus rv;
- SECItem item;
-
- *headerSize = 0; /* hack */
-
- if (fd == NULL) {
- /* XXX set an error */
- return NULL;
- }
-
- ss = ssl_FindSocket(fd);
- if (ss == NULL) {
- /* XXX set an error */
- return NULL;
- }
-
- PORT_Assert(ss->ssl3 != NULL);
- if (ss->ssl3 == NULL) {
- return NULL;
- }
-
- /* get the kea context from the session */
- tek = ss->ssl3->fortezza.tek;
- if (tek == NULL) {
- return NULL;
- }
-
- slot = PK11_GetSlotFromKey(tek);
- if (slot == NULL) return NULL;
- Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL, PK11_GetWindow(tek));
- PK11_FreeSlot(slot);
- if (Ks == NULL) return NULL;
-
-
- /* unwrap with the local Ks */
- item.data = header->u.fortezza.key;
- item.len = sizeof(header->u.fortezza.key);
- /* rewrap the key with the TEK */
- key = PK11_UnwrapSymKey(Ks,CKM_SKIPJACK_WRAP,
- NULL, &item, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
- if (key == NULL) {
- PK11_FreeSymKey(Ks);
- return NULL;
- }
-
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, key, &item);
- PK11_FreeSymKey(Ks);
- PK11_FreeSymKey(key);
- if (rv != SECSuccess) {
- return NULL;
- }
-
- /* copy over our local serial number */
- PORT_Memset(header->u.fortezza.serial,0,sizeof(header->u.fortezza.serial));
-
- /* change type to stream */
- PutInt2(header->type, PRE_FORTEZZA_STREAM);
-
- return(header);
-}
-
-
diff --git a/security/nss/lib/ssl/ssl.h b/security/nss/lib/ssl/ssl.h
deleted file mode 100644
index 97a97759b..000000000
--- a/security/nss/lib/ssl/ssl.h
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * This file contains prototypes for the public SSL functions.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#ifndef __ssl_h_
-#define __ssl_h_
-
-#include "prtypes.h"
-#include "prerror.h"
-#include "prio.h"
-#include "seccomon.h"
-#include "cert.h"
-#include "keyt.h"
-
-/* constant table enumerating all implemented SSL 2 and 3 cipher suites. */
-extern const PRUint16 SSL_ImplementedCiphers[];
-
-/* number of entries in the above table. */
-extern const PRUint16 SSL_NumImplementedCiphers;
-
-/* Macro to tell which ciphers in table are SSL2 vs SSL3/TLS. */
-#define SSL_IS_SSL2_CIPHER(which) (((which) & 0xfff0) == 0xff00)
-
-SEC_BEGIN_PROTOS
-
-
-/*
-** Imports fd into SSL, returning a new socket. Copies SSL configuration
-** from model.
-*/
-extern PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd);
-
-/*
-** Enable/disable an ssl mode
-**
-** SSL_SECURITY:
-** enable/disable use of SSL security protocol before connect
-**
-** SSL_SOCKS:
-** enable/disable use of socks before connect
-** (No longer supported).
-**
-** SSL_REQUEST_CERTIFICATE:
-** require a certificate during secure connect
-*/
-/* options */
-#define SSL_SECURITY 1
-#define SSL_SOCKS 2
-#define SSL_REQUEST_CERTIFICATE 3
-#define SSL_HANDSHAKE_AS_CLIENT 5 /* force accept to hs as client */
-#define SSL_HANDSHAKE_AS_SERVER 6 /* force connect to hs as server */
-#define SSL_ENABLE_SSL2 7 /* enable ssl v2 (on by default) */
-#define SSL_ENABLE_SSL3 8 /* enable ssl v3 (on by default) */
-#define SSL_NO_CACHE 9 /* don't use the session cache */
-#define SSL_REQUIRE_CERTIFICATE 10
-#define SSL_ENABLE_FDX 11 /* permit simultaneous read/write */
-#define SSL_V2_COMPATIBLE_HELLO 12 /* send v3 client hello in v2 fmt */
-#define SSL_ENABLE_TLS 13 /* enable TLS (off by default) */
-#define SSL_ROLLBACK_DETECTION 14 /* for compatibility, default: on */
-
-/* Old deprecated function names */
-extern SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on);
-extern SECStatus SSL_EnableDefault(int option, PRBool on);
-
-/* New function names */
-extern SECStatus SSL_OptionSet(PRFileDesc *fd, PRInt32 option, PRBool on);
-extern SECStatus SSL_OptionGet(PRFileDesc *fd, PRInt32 option, PRBool *on);
-extern SECStatus SSL_OptionSetDefault(PRInt32 option, PRBool on);
-extern SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on);
-extern SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle);
-
-/*
-** Control ciphers that SSL uses. If on is non-zero then the named cipher
-** is enabled, otherwise it is disabled.
-** The "cipher" values are defined in sslproto.h (the SSL_EN_* values).
-** EnableCipher records user preferences.
-** SetPolicy sets the policy according to the policy module.
-*/
-/* Old deprecated function names */
-extern SECStatus SSL_EnableCipher(long which, PRBool enabled);
-extern SECStatus SSL_SetPolicy(long which, int policy);
-
-/* New function names */
-extern SECStatus SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 cipher, PRBool enabled);
-extern SECStatus SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 cipher, PRBool *enabled);
-extern SECStatus SSL_CipherPrefSetDefault(PRInt32 cipher, PRBool enabled);
-extern SECStatus SSL_CipherPrefGetDefault(PRInt32 cipher, PRBool *enabled);
-extern SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy);
-extern SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy);
-
-/* Values for "policy" argument to SSL_PolicySet */
-/* Values returned by SSL_CipherPolicyGet. */
-#define SSL_NOT_ALLOWED 0 /* or invalid or unimplemented */
-#define SSL_ALLOWED 1
-#define SSL_RESTRICTED 2 /* only with "Step-Up" certs. */
-
-/*
-** Reset the handshake state for fd. This will make the complete SSL
-** handshake protocol execute from the ground up on the next i/o
-** operation.
-*/
-extern SECStatus SSL_ResetHandshake(PRFileDesc *fd, PRBool asServer);
-
-/*
-** Force the handshake for fd to complete immediately. This blocks until
-** the complete SSL handshake protocol is finished.
-*/
-extern int SSL_ForceHandshake(PRFileDesc *fd);
-
-/*
-** Query security status of socket. *on is set to one if security is
-** enabled. *keySize will contain the stream key size used. *issuer will
-** contain the RFC1485 verison of the name of the issuer of the
-** certificate at the other end of the connection. For a client, this is
-** the issuer of the server's certificate; for a server, this is the
-** issuer of the client's certificate (if any). Subject is the subject of
-** the other end's certificate. The pointers can be zero if the desired
-** data is not needed. All strings returned by this function are owned
-** by SSL, and will be freed when the socket is closed.
-*/
-extern int SSL_SecurityStatus(PRFileDesc *fd, int *on, char **cipher,
- int *keySize, int *secretKeySize,
- char **issuer, char **subject);
-
-/* Values for "on" */
-#define SSL_SECURITY_STATUS_NOOPT -1
-#define SSL_SECURITY_STATUS_OFF 0
-#define SSL_SECURITY_STATUS_ON_HIGH 1
-#define SSL_SECURITY_STATUS_ON_LOW 2
-#define SSL_SECURITY_STATUS_FORTEZZA 3
-
-/*
-** Return the certificate for our SSL peer. If the client calls this
-** it will always return the server's certificate. If the server calls
-** this, it may return NULL if client authentication is not enabled or
-** if the client had no certificate when asked.
-** "fd" the socket "file" descriptor
-*/
-extern CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
-
-/*
-** Authenticate certificate hook. Called when a certificate comes in
-** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the
-** certificate.
-*/
-typedef int (*SSLAuthCertificate)(void *arg, PRFileDesc *fd, PRBool checkSig,
- PRBool isServer);
-extern int SSL_AuthCertificateHook(PRFileDesc *fd, SSLAuthCertificate f,
- void *arg);
-
-/* An implementation of the certificate authentication hook */
-extern int SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig,
- PRBool isServer);
-
-/*
- * Prototype for SSL callback to get client auth data from the application.
- * arg - application passed argument
- * caNames - pointer to distinguished names of CAs that the server likes
- * pRetCert - pointer to pointer to cert, for return of cert
- * pRetKey - pointer to key pointer, for return of key
- */
-typedef int (*SSLGetClientAuthData)(void *arg, PRFileDesc *fd,
- CERTDistNames *caNames,
- CERTCertificate **pRetCert,/*return */
- SECKEYPrivateKey **pRetKey);/* return */
-
-/*
- * Set the client side callback for SSL to retrieve user's private key
- * and certificate.
- * fd - the file descriptor for the connection in question
- * f - the application's callback that delivers the key and cert
- * a - application specific data
- */
-extern int SSL_GetClientAuthDataHook(PRFileDesc *fd, SSLGetClientAuthData f,
- void *a);
-
-
-/*
- * Set the client side argument for SSL to retrieve PKCS #11 pin.
- * fd - the file descriptor for the connection in question
- * a - pkcs11 application specific data
- */
-extern int SSL_SetPKCS11PinArg(PRFileDesc *fd, void *a);
-
-/*
-** This is a callback for dealing with server certs that are not authenticated
-** by the client. The client app can decide that it actually likes the
-** cert by some external means and restart the connection.
-*/
-typedef int (*SSLBadCertHandler)(void *arg, PRFileDesc *fd);
-extern int SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg);
-
-/*
-** Configure ssl for running a secure server. Needs the
-** certificate for the server and the servers private key. The arguments
-** are copied.
-*/
-/* Key Exchange values */
-typedef enum {
- kt_null = 0,
- kt_rsa,
- kt_dh,
- kt_fortezza,
- kt_kea_size
-} SSLKEAType;
-
-extern SECStatus SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert,
- SECKEYPrivateKey *key, SSLKEAType kea);
-
-/*
-** Configure a secure servers session-id cache. Define the maximum number
-** of entries in the cache, the longevity of the entires, and the directory
-** where the cache files will be placed. These values can be zero, and
-** if so, the implementation will choose defaults.
-** This version of the function is for use in applications that have only one
-** process that uses the cache (even if that process has multiple threads).
-*/
-extern int SSL_ConfigServerSessionIDCache(int maxCacheEntries,
- PRUint32 timeout,
- PRUint32 ssl3_timeout,
- const char * directory);
-/*
-** Like SSL_ConfigServerSessionIDCache, with one important difference.
-** If the application will run multiple processes (as opposed to, or in
-** addition to multiple threads), then it must call this function, instead
-** of calling SSL_ConfigServerSessionIDCache().
-** This has nothing to do with the number of processORs, only processEs.
-** This function sets up a Server Session ID (SID) cache that is safe for
-** access by multiple processes on the same system.
-*/
-extern int SSL_ConfigMPServerSIDCache(int maxCacheEntries,
- PRUint32 timeout,
- PRUint32 ssl3_timeout,
- const char * directory);
-
-/* environment variable set by SSL_ConfigMPServerSIDCache, and queried by
- * SSL_InheritMPServerSIDCache when envString is NULL.
- */
-#define SSL_ENV_VAR_NAME "SSL_INHERITANCE"
-
-/* called in child to inherit SID Cache variables.
- * If envString is NULL, this function will use the value of the environment
- * variable "SSL_INHERITANCE", otherwise the string value passed in will be
- * used.
- */
-extern SECStatus SSL_InheritMPServerSIDCache(const char * envString);
-
-/*
-** Set the callback on a particular socket that gets called when we finish
-** performing a handshake.
-*/
-typedef void (*SSLHandshakeCallback)(PRFileDesc *fd, void *client_data);
-extern int SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb,
- void *client_data);
-
-/*
-** For the server, request a new handshake. For the client, begin a new
-** handshake. If flushCache is non-zero, the SSL3 cache entry will be
-** flushed first, ensuring that a full SSL handshake will be done.
-** If flushCache is zero, and an SSL connection is established, it will
-** do the much faster session restart handshake. This will change the
-** session keys without doing another private key operation.
-*/
-extern int SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache);
-
-/*
-** For the server, request a new handshake. For the client, begin a new
-** handshake. Flushes SSL3 session cache entry first, ensuring that a
-** full handshake will be done.
-** This call is equivalent to SSL_ReHandshake(fd, PR_TRUE)
-*/
-extern int SSL_RedoHandshake(PRFileDesc *fd);
-
-/*
-** Return 1 if the socket is direct, 0 if not, -1 on error
-*/
-extern int SSL_CheckDirectSock(PRFileDesc *s);
-
-/*
-** A cousin to SSL_Bind, this takes an extra arg: dsthost, so we can
-** set up sockd connection. This should be used with socks enabled.
-*/
-extern int SSL_BindForSockd(PRFileDesc *s, PRNetAddr *sa, long dsthost);
-
-/*
-** Configure ssl for using socks.
-*/
-extern SECStatus SSL_ConfigSockd(PRFileDesc *fd, PRUint32 host, PRUint16 port);
-
-/*
- * Allow the application to pass a URL or hostname into the SSL library
- */
-extern int SSL_SetURL(PRFileDesc *fd, const char *url);
-
-/*
-** Return the number of bytes that SSL has waiting in internal buffers.
-** Return 0 if security is not enabled.
-*/
-extern int SSL_DataPending(PRFileDesc *fd);
-
-/*
-** Invalidate the SSL session associated with fd.
-*/
-extern int SSL_InvalidateSession(PRFileDesc *fd);
-
-/*
-** Return a SECItem containing the SSL session ID associated with the fd.
-*/
-extern SECItem *SSL_GetSessionID(PRFileDesc *fd);
-
-/*
-** Clear out the SSL session cache.
-*/
-extern void SSL_ClearSessionCache(void);
-
-/*
-** Set peer information so we can correctly look up SSL session later.
-** You only have to do this if you're tunneling through a proxy.
-*/
-extern int SSL_SetSockPeerID(PRFileDesc *fd, char *peerID);
-
-/*
-** Read the socks config file. You must do this before doing anything with
-** socks.
-*/
-extern int SSL_ReadSocksConfFile(PRFileDesc *fp);
-
-/*
-** Reveal the security information for the peer.
-*/
-extern CERTCertificate * SSL_RevealCert(PRFileDesc * socket);
-extern void * SSL_RevealPinArg(PRFileDesc * socket);
-extern char * SSL_RevealURL(PRFileDesc * socket);
-
-
-/* This callback may be passed to the SSL library via a call to
- * SSL_GetClientAuthDataHook() for each SSL client socket.
- * It will be invoked when SSL needs to know what certificate and private key
- * (if any) to use to respond to a request for client authentication.
- * If arg is non-NULL, it is a pointer to a NULL-terminated string containing
- * the nickname of the cert/key pair to use.
- * If arg is NULL, this function will search the cert and key databases for
- * a suitable match and send it if one is found.
- */
-extern SECStatus
-NSS_GetClientAuthData(void * arg,
- PRFileDesc * socket,
- struct CERTDistNamesStr * caNames,
- struct CERTCertificateStr ** pRetCert,
- struct SECKEYPrivateKeyStr **pRetKey);
-
-/*
- * Look to see if any of the signers in the cert chain for "cert" are found
- * in the list of caNames.
- * Returns SECSuccess if so, SECFailure if not.
- * Used by NSS_GetClientAuthData. May be used by other callback functions.
- */
-extern SECStatus NSS_CmpCertChainWCANames(CERTCertificate *cert,
- CERTDistNames *caNames);
-
-/*
- * Returns key exchange type of the keys in an SSL server certificate.
- */
-extern SSLKEAType NSS_FindCertKEAType(CERTCertificate * cert);
-
-/* Set cipher policies to a predefined Domestic (U.S.A.) policy.
- * This essentially enables all supported ciphers.
- */
-extern SECStatus NSS_SetDomesticPolicy(void);
-
-/* Set cipher policies to a predefined Policy that is exportable from the USA
- * according to present U.S. policies as we understand them.
- * See documentation for the list.
- * Note that your particular application program may be able to obtain
- * an export license with more or fewer capabilities than those allowed
- * by this function. In that case, you should use SSL_SetPolicy()
- * to explicitly allow those ciphers you may legally export.
- */
-extern SECStatus NSS_SetExportPolicy(void);
-
-/* Set cipher policies to a predefined Policy that is exportable from the USA
- * according to present U.S. policies as we understand them, and that the
- * nation of France will permit to be imported into their country.
- * See documentation for the list.
- */
-extern SECStatus NSS_SetFrancePolicy(void);
-
-SEC_END_PROTOS
-
-#endif /* __ssl_h_ */
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c
deleted file mode 100644
index 93d5b2773..000000000
--- a/security/nss/lib/ssl/ssl3con.c
+++ /dev/null
@@ -1,7521 +0,0 @@
-/*
- * SSL3 Protocol
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "cert.h"
-#include "ssl.h"
-#include "cryptohi.h" /* for DSAU_ stuff */
-#include "keyhi.h"
-#include "secder.h"
-#include "secitem.h"
-
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "sslerr.h"
-#include "prtime.h"
-#include "prinrval.h"
-#include "prerror.h"
-#include "pratom.h"
-#include "prthread.h"
-
-#include "pk11func.h"
-#include "secmod.h"
-#include "nsslocks.h"
-
-#include <stdio.h>
-
-#ifndef PK11_SETATTRS
-#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
- (x)->pValue=(v); (x)->ulValueLen = (l);
-#endif
-
-static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
- PK11SlotInfo * serverKeySlot);
-static SECStatus ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms);
-static SECStatus ssl3_HandshakeFailure( sslSocket *ss);
-static SECStatus ssl3_InitState( sslSocket *ss);
-static sslSessionID *ssl3_NewSessionID( sslSocket *ss, PRBool is_server);
-static SECStatus ssl3_SendCertificate( sslSocket *ss);
-static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss);
-static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
-static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags);
-static SECStatus ssl3_SendServerHello( sslSocket *ss);
-static SECStatus ssl3_SendServerHelloDone( sslSocket *ss);
-static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss);
-
-static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
- int maxOutputLen, const unsigned char *input,
- int inputLen);
-
-#define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */
-#define MIN_SEND_BUF_LENGTH 4000
-
-#define MAX_CIPHER_SUITES 20
-
-/* This list of SSL3 cipher suites is sorted in descending order of
- * precedence (desirability). It only includes cipher suites we implement.
- * This table is modified by SSL3_SetPolicy().
- */
-static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
- /* cipher_suite policy enabled is_present*/
- { SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_RSA_WITH_RC4_128_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_FORTEZZA_DMS_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_RSA_WITH_NULL_MD5, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}
-};
-
-static const /*SSL3CompressionMethod*/ uint8 compressions [] = {
- compression_null
-};
-
-static const int compressionMethodsCount =
- sizeof(compressions) / sizeof(compressions[0]);
-
-static const /*SSL3ClientCertificateType */ uint8 certificate_types [] = {
- ct_RSA_sign,
- ct_DSS_sign,
-};
-
-static const /*SSL3ClientCertificateType */ uint8 fortezza_certificate_types [] = {
- ct_Fortezza,
-};
-
-/*
- * make sure there is room in the write buffer for padding and
- * other compression and cryptographic expansions
- */
-#define SSL3_BUFFER_FUDGE 100
-
-#undef BPB
-#define BPB 8 /* Bits Per Byte */
-
-#define SET_ERROR_CODE /* reminder */
-#define SEND_ALERT /* reminder */
-#define TEST_FOR_FAILURE /* reminder */
-#define DEAL_WITH_FAILURE /* reminder */
-
-
-/* This is a hack to make sure we don't do double handshakes for US policy */
-PRBool ssl3_global_policy_some_restricted = PR_FALSE;
-
-/* This global item is used only in servers. It is is initialized by
-** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest().
-*/
-CERTDistNames *ssl3_server_ca_list = NULL;
-
-/* statistics from ssl3_SendClientHello (sch) */
-long ssl3_sch_sid_cache_hits;
-long ssl3_sch_sid_cache_misses;
-long ssl3_sch_sid_cache_not_ok;
-
-/* statistics from ssl3_HandleServerHello (hsh) */
-long ssl3_hsh_sid_cache_hits;
-long ssl3_hsh_sid_cache_misses;
-long ssl3_hsh_sid_cache_not_ok;
-
-/* statistics from ssl3_HandleClientHello (hch) */
-long ssl3_hch_sid_cache_hits;
-long ssl3_hch_sid_cache_misses;
-long ssl3_hch_sid_cache_not_ok;
-
-/* indexed by SSL3BulkCipher */
-static const ssl3BulkCipherDef bulk_cipher_defs[] = {
- /* cipher calg keySz secretSz type ivSz BlkSz keygen */
- {cipher_null, calg_null, 0, 0, type_stream, 0, 0, kg_null},
- {cipher_rc4, calg_rc4, 16, 16, type_stream, 0, 0, kg_strong},
- {cipher_rc4_40, calg_rc4, 16, 5, type_stream, 0, 0, kg_export},
- {cipher_rc4_56, calg_rc4, 16, 7, type_stream, 0, 0, kg_export},
- {cipher_rc2, calg_rc2, 16, 16, type_block, 8, 8, kg_strong},
- {cipher_rc2_40, calg_rc2, 16, 5, type_block, 8, 8, kg_export},
- {cipher_des, calg_des, 8, 8, type_block, 8, 8, kg_strong},
- {cipher_3des, calg_3des, 24, 24, type_block, 8, 8, kg_strong},
- {cipher_des40, calg_des, 8, 5, type_block, 8, 8, kg_export},
- {cipher_idea, calg_idea, 16, 16, type_block, 8, 8, kg_strong},
- {cipher_fortezza, calg_fortezza, 10, 10, type_block, 24, 8, kg_null},
- {cipher_missing, calg_null, 0, 0, type_stream, 0, 0, kg_null},
-};
-
-static const ssl3KEADef kea_defs[] = { /* indexed by SSL3KeyExchangeAlgorithm */
- /* kea exchKeyType signKeyType is_limited limit tls_keygen */
- {kea_null, kt_null, sign_null, PR_FALSE, 0, PR_FALSE},
- {kea_rsa, kt_rsa, sign_rsa, PR_FALSE, 0, PR_FALSE},
- {kea_rsa_export, kt_rsa, sign_rsa, PR_TRUE, 512, PR_FALSE},
- {kea_rsa_export_1024,kt_rsa, sign_rsa, PR_TRUE, 1024, PR_FALSE},
- {kea_dh_dss, kt_dh, sign_dsa, PR_FALSE, 0, PR_FALSE},
- {kea_dh_dss_export, kt_dh, sign_dsa, PR_TRUE, 512, PR_FALSE},
- {kea_dh_rsa, kt_dh, sign_rsa, PR_FALSE, 0, PR_FALSE},
- {kea_dh_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE},
- {kea_dhe_dss, kt_dh, sign_dsa, PR_FALSE, 0, PR_FALSE},
- {kea_dhe_dss_export, kt_dh, sign_dsa, PR_TRUE, 512, PR_FALSE},
- {kea_dhe_rsa, kt_dh, sign_rsa, PR_FALSE, 0, PR_FALSE},
- {kea_dhe_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE},
- {kea_dh_anon, kt_dh, sign_null, PR_FALSE, 0, PR_FALSE},
- {kea_dh_anon_export, kt_dh, sign_null, PR_TRUE, 512, PR_FALSE},
- {kea_fortezza, kt_fortezza, sign_dsa, PR_FALSE, 0, PR_FALSE},
- {kea_rsa_fips, kt_rsa, sign_rsa, PR_FALSE, 0, PR_TRUE },
-};
-
-static const CK_MECHANISM_TYPE kea_alg_defs[] = {
- 0x80000000L,
- CKM_RSA_PKCS,
- CKM_DH_PKCS_DERIVE,
- CKM_KEA_KEY_DERIVE
-};
-
-
-static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */
- /* mac malg pad_size mac_size */
- { mac_null, malg_null, 0, 0 },
- { mac_md5, malg_md5, 48, MD5_LENGTH },
- { mac_sha, malg_sha, 40, SHA1_LENGTH},
- {hmac_md5, malg_md5_hmac, 48, MD5_LENGTH },
- {hmac_sha, malg_sha_hmac, 40, SHA1_LENGTH},
-};
-
-/* must use ssl_LookupCipherSuiteDef to access */
-static const ssl3CipherSuiteDef cipher_suite_defs[] = {
-/* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg */
-
- {SSL_NULL_WITH_NULL_NULL, cipher_null, mac_null, kea_null},
- {SSL_RSA_WITH_NULL_MD5, cipher_null, mac_md5, kea_rsa},
- {SSL_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_rsa},
- {SSL_RSA_EXPORT_WITH_RC4_40_MD5,cipher_rc4_40, mac_md5, kea_rsa_export},
- {SSL_RSA_WITH_RC4_128_MD5, cipher_rc4, mac_md5, kea_rsa},
- {SSL_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_rsa},
- {SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- cipher_rc2_40, mac_md5, kea_rsa_export},
-#if 0 /* not implemented */
- {SSL_RSA_WITH_IDEA_CBC_SHA, cipher_idea, mac_sha, kea_rsa},
- {SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_rsa_export},
-#endif
- {SSL_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa},
- {SSL_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa},
-
-#if 0 /* not implemented */
- {SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_dss_export},
- {SSL_DH_DSS_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_dss},
- {SSL_DH_DSS_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_dss},
- {SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_rsa_export},
- {SSL_DH_RSA_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_rsa},
- {SSL_DH_RSA_3DES_CBC_SHA, cipher_des, mac_sha, kea_dh_rsa},
- {SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_dss_export},
- {SSL_DHE_DSS_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_dss},
- {SSL_DHE_DSS_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_dss},
- {SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_rsa_export},
- {SSL_DHE_RSA_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_rsa},
- {SSL_DHE_RSA_3DES_CBC_SHA, cipher_des, mac_sha, kea_dh_rsa},
- {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4_40, mac_md5, kea_dh_anon_export},
- {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4, mac_md5, kea_dh_anon_export},
- {SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_anon_export},
- {SSL_DH_ANON_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_anon},
- {SSL_DH_ANON_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_anon},
-#endif
-
- {SSL_FORTEZZA_DMS_WITH_NULL_SHA, cipher_null, mac_sha, kea_fortezza},
- {SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,
- cipher_fortezza, mac_sha, kea_fortezza},
- {SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_fortezza},
-
- {TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
- cipher_des, mac_sha,kea_rsa_export_1024},
- {TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
- cipher_rc4_56, mac_sha,kea_rsa_export_1024},
-
- {SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa_fips},
- {SSL_RSA_FIPS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa_fips},
-
-};
-
-/* indexed by SSL3BulkCipher */
-const char * const ssl3_cipherName[] = {
- "NULL",
- "RC4",
- "RC4-40",
- "RC4-56",
- "RC2-CBC",
- "RC2-CBC-40",
- "DES-CBC",
- "3DES-EDE-CBC",
- "DES-CBC-40",
- "IDEA-CBC",
- "FORTEZZA",
- "missing"
-};
-
-#if defined(TRACE)
-
-static char *
-ssl3_DecodeHandshakeType(int msgType)
-{
- char * rv;
- static char line[40];
-
- switch(msgType) {
- case hello_request: rv = "hello_request (0)"; break;
- case client_hello: rv = "client_hello (1)"; break;
- case server_hello: rv = "server_hello (2)"; break;
- case certificate: rv = "certificate (11)"; break;
- case server_key_exchange: rv = "server_key_exchange (12)"; break;
- case certificate_request: rv = "certificate_request (13)"; break;
- case server_hello_done: rv = "server_hello_done (14)"; break;
- case certificate_verify: rv = "certificate_verify (15)"; break;
- case client_key_exchange: rv = "client_key_exchange (16)"; break;
- case finished: rv = "finished (20)"; break;
- default:
- sprintf(line, "*UNKNOWN* handshake type! (%d)", msgType);
- rv = line;
- }
- return rv;
-}
-
-static char *
-ssl3_DecodeContentType(int msgType)
-{
- char * rv;
- static char line[40];
-
- switch(msgType) {
- case content_change_cipher_spec:
- rv = "change_cipher_spec (20)"; break;
- case content_alert: rv = "alert (21)"; break;
- case content_handshake: rv = "handshake (22)"; break;
- case content_application_data:
- rv = "application_data (23)"; break;
- default:
- sprintf(line, "*UNKNOWN* record type! (%d)", msgType);
- rv = line;
- }
- return rv;
-}
-
-#endif
-
-/* return pointer to ssl3CipherSuiteDef for suite, or NULL */
-/* XXX This does a linear search. A binary search would be better. */
-static const ssl3CipherSuiteDef *
-ssl_LookupCipherSuiteDef(ssl3CipherSuite suite)
-{
- int cipher_suite_def_len =
- sizeof(cipher_suite_defs) / sizeof(cipher_suite_defs[0]);
- int i;
-
- for (i = 0; i < cipher_suite_def_len; i++) {
- if (cipher_suite_defs[i].cipher_suite == suite)
- return &cipher_suite_defs[i];
- }
- PORT_Assert(PR_FALSE); /* We should never get here. */
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- return NULL;
-}
-
-/* Find the cipher configuration struct associate with suite */
-/* XXX This does a linear search. A binary search would be better. */
-static ssl3CipherSuiteCfg *
-ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite, ssl3CipherSuiteCfg *suites)
-{
- int i;
-
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- if (suites[i].cipher_suite == suite)
- return &suites[i];
- }
- /* return NULL and let the caller handle it. */
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- return NULL;
-}
-
-
-/* Initialize the suite->isPresent value for config_match
- * Returns count of enabled ciphers supported by extant tokens,
- * regardless of policy or user preference.
- * If this returns zero, the user cannot do SSL v3.
- */
-int
-ssl3_config_match_init(sslSocket *ss)
-{
- ssl3CipherSuiteCfg * suite;
- const ssl3CipherSuiteDef *cipher_def;
- CipherAlgorithm cipher_alg;
- SSL3KEAType exchKeyType;
- int i;
- int numPresent = 0;
- int numEnabled = 0;
- PRBool isServer;
-
- if (!ss->enableSSL3 && !ss->enableTLS) {
- return 0;
- }
- isServer = (PRBool)( ss && ss->sec && ss->sec->isServer );
-
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- suite = &ss->cipherSuites[i];
- if (suite->enabled) {
- ++numEnabled;
- /* We need the cipher defs to see if we have a token that can handle
- * this cipher. It isn't part of the static definition.
- */
- cipher_def = ssl_LookupCipherSuiteDef(suite->cipher_suite);
- if (!cipher_def) {
- suite->isPresent = PR_FALSE;
- continue;
- }
- cipher_alg=bulk_cipher_defs[cipher_def->bulk_cipher_alg ].calg;
- exchKeyType =
- kea_defs[cipher_def->key_exchange_alg].exchKeyType;
-
- /* Mark the suites that are backed by real tokens, certs and keys */
- suite->isPresent = (PRBool)
- (((exchKeyType == kt_null) ||
- (!isServer || (ss->serverKey[exchKeyType] &&
- ss->serverCertChain[exchKeyType])) &&
- PK11_TokenExists(kea_alg_defs[exchKeyType])) &&
- ((cipher_alg == calg_null) || PK11_TokenExists(cipher_alg)));
- if (suite->isPresent)
- ++numPresent;
- }
- }
- PORT_Assert(numPresent > 0 || numEnabled == 0);
- if (numPresent <= 0) {
- PORT_SetError(SSL_ERROR_NO_CIPHERS_SUPPORTED);
- }
- return numPresent;
-}
-
-
-/* return PR_TRUE if suite matches policy and enabled state */
-/* It would be a REALLY BAD THING (tm) if we ever permitted the use
-** of a cipher that was NOT_ALLOWED. So, if this is ever called with
-** policy == SSL_NOT_ALLOWED, report no match.
-*/
-/* adjust suite enabled to the availability of a token that can do the
- * cipher suite. */
-static PRBool
-config_match(ssl3CipherSuiteCfg *suite, int policy, PRBool enabled)
-{
- PORT_Assert(policy != SSL_NOT_ALLOWED && enabled != PR_FALSE);
- if (policy == SSL_NOT_ALLOWED || !enabled)
- return PR_FALSE;
- return (PRBool)(suite->enabled &&
- suite->isPresent &&
- suite->policy != SSL_NOT_ALLOWED &&
- suite->policy <= policy);
-}
-
-/* return number of cipher suites that match policy and enabled state */
-/* called from ssl3_SendClientHello and ssl3_ConstructV2CipherSpecsHack */
-static int
-count_cipher_suites(sslSocket *ss, int policy, PRBool enabled)
-{
- int i, count = 0;
-
- if (!ss->enableSSL3 && !ss->enableTLS) {
- return 0;
- }
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- if (config_match(&ss->cipherSuites[i], policy, enabled))
- count++;
- }
- if (count <= 0) {
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- }
- return count;
-}
-
-static PRBool
-anyRestrictedEnabled(sslSocket *ss)
-{
- int i;
-
- if (!ss->enableSSL3 && !ss->enableTLS) {
- return PR_FALSE;
- }
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if (suite->policy == SSL_RESTRICTED &&
- suite->enabled &&
- suite->isPresent)
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-/*
- * Null compression, mac and encryption functions
- */
-
-static SECStatus
-Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen,
- const unsigned char *input, int inputLen)
-{
- *outputLen = inputLen;
- if (input != output)
- PORT_Memcpy(output, input, inputLen);
- return SECSuccess;
-}
-
-
-/*
- * SSL3 Utility functions
- */
-
-SECStatus
-ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion)
-{
- SSL3ProtocolVersion version;
- SSL3ProtocolVersion maxVersion;
-
- if (ss->enableTLS) {
- maxVersion = SSL_LIBRARY_VERSION_3_1_TLS;
- } else if (ss->enableSSL3) {
- maxVersion = SSL_LIBRARY_VERSION_3_0;
- } else {
- /* what are we doing here? */
- PORT_Assert(ss->enableSSL3 || ss->enableTLS);
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- return SECFailure;
- }
-
- ss->version = version = PR_MIN(maxVersion, peerVersion);
-
- if ((version == SSL_LIBRARY_VERSION_3_1_TLS && ss->enableTLS) ||
- (version == SSL_LIBRARY_VERSION_3_0 && ss->enableSSL3)) {
- return SECSuccess;
- }
-
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
-
-}
-
-static SECStatus
-ssl3_GetNewRandom(SSL3Random *random)
-{
- PRIntervalTime gmt = PR_IntervalToSeconds(PR_IntervalNow());
- SECStatus rv;
-
- random->rand[0] = (unsigned char)(gmt >> 24);
- random->rand[1] = (unsigned char)(gmt >> 16);
- random->rand[2] = (unsigned char)(gmt >> 8);
- random->rand[3] = (unsigned char)(gmt);
-
- /* first 4 bytes are reserverd for time */
- rv = PK11_GenerateRandom(&random->rand[4], SSL3_RANDOM_LENGTH - 4);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
- }
- return rv;
-}
-
-static SECStatus
-ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf,
- PRBool isTLS)
-{
- SECStatus rv = SECFailure;
- PRBool doDerEncode = PR_FALSE;
- int signatureLen;
- SECItem hashItem;
-
- buf->data = NULL;
- signatureLen = PK11_SignatureLen(key);
- if (signatureLen <= 0) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- goto done;
- }
-
- buf->len = (unsigned)signatureLen;
- buf->data = (unsigned char *)PORT_Alloc(signatureLen + 1);
- if (!buf->data)
- goto done; /* error code was set. */
-
- switch (key->keyType) {
- case rsaKey:
- hashItem.data = hash->md5;
- hashItem.len = sizeof(SSL3Hashes);
- break;
- case dsaKey:
- case fortezzaKey:
- doDerEncode = isTLS;
- hashItem.data = hash->sha;
- hashItem.len = sizeof(hash->sha);
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- goto done;
- }
- PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len));
-
- rv = PK11_Sign(key, buf, &hashItem);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SIGN_HASHES_FAILURE);
- } else if (doDerEncode) {
- SECItem derSig = {siBuffer, NULL, 0};
-
- rv = DSAU_EncodeDerSig(&derSig, buf);
- if (rv == SECSuccess) {
- PORT_Free(buf->data); /* discard unencoded signature. */
- *buf = derSig; /* give caller encoded signature. */
- } else if (derSig.data) {
- PORT_Free(derSig.data);
- }
- }
-
- PRINT_BUF(60, (NULL, "signed hashes", (unsigned char*)buf->data, buf->len));
-done:
- if (rv != SECSuccess && buf->data) {
- PORT_Free(buf->data);
- buf->data = NULL;
- }
- return rv;
-}
-
-
-static SECStatus
-ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
- SECItem *buf, PRBool isTLS, void *pwArg)
-{
- SECKEYPublicKey * key;
- SECItem * signature = NULL;
- SECStatus rv;
- SECItem hashItem;
-
-
- PRINT_BUF(60, (NULL, "check signed hashes",
- buf->data, buf->len));
-
- key = CERT_ExtractPublicKey(cert);
- if (key == NULL) {
- /* CERT_ExtractPublicKey doesn't set error code */
- PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- return SECFailure;
- }
-
- switch (key->keyType) {
- case rsaKey:
- hashItem.data = hash->md5;
- hashItem.len = sizeof(SSL3Hashes);
- break;
- case dsaKey:
- case fortezzaKey:
- hashItem.data = hash->sha;
- hashItem.len = sizeof(hash->sha);
- if (isTLS) {
- signature = DSAU_DecodeDerSig(buf);
- if (!signature) {
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- return SECFailure;
- }
- buf = signature;
- }
- break;
- default:
- SECKEY_DestroyPublicKey(key);
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- return SECFailure;
- }
-
- PRINT_BUF(60, (NULL, "hash(es) to be verified",
- hashItem.data, hashItem.len));
-
- rv = PK11_Verify(key, buf, &hashItem, pwArg);
- SECKEY_DestroyPublicKey(key);
- if (signature) {
- SECITEM_FreeItem(signature, PR_TRUE);
- }
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- }
- return rv;
-}
-
-
-/* Caller must set hiLevel error code. */
-static SECStatus
-ssl3_ComputeExportRSAKeyHash(SECItem modulus, SECItem publicExponent,
- SSL3Random *client_rand, SSL3Random *server_rand,
- SSL3Hashes *hashes)
-{
- PK11Context * md5 = NULL;
- PK11Context * sha = NULL;
- PRUint8 * hashBuf;
- PRUint8 * pBuf;
- SECStatus rv = SECSuccess;
- unsigned int outLen;
- unsigned int bufLen;
- PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 4096/8 + 2 + 4096/8];
-
- bufLen = 2*SSL3_RANDOM_LENGTH + 2 + modulus.len + 2 + publicExponent.len;
- if (bufLen <= sizeof buf) {
- hashBuf = buf;
- } else {
- hashBuf = PORT_Alloc(bufLen);
- if (!hashBuf) {
- return SECFailure;
- }
- }
-
- md5 = PK11_CreateDigestContext(SEC_OID_MD5);
- if (md5 == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure; /* Caller must set hiLevel error code. */
- goto done;
- }
- sha = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (sha == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure; /* Caller must set hiLevel error code. */
- goto done;
- }
-
- memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
- pBuf = hashBuf + SSL3_RANDOM_LENGTH;
- memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
- pBuf += SSL3_RANDOM_LENGTH;
- pBuf[0] = (PRUint8)(modulus.len >> 8);
- pBuf[1] = (PRUint8)(modulus.len);
- pBuf += 2;
- memcpy(pBuf, modulus.data, modulus.len);
- pBuf += modulus.len;
- pBuf[0] = (PRUint8)(publicExponent.len >> 8);
- pBuf[1] = (PRUint8)(publicExponent.len);
- pBuf += 2;
- memcpy(pBuf, publicExponent.data, publicExponent.len);
- pBuf += publicExponent.len;
- PORT_Assert(pBuf - hashBuf == bufLen);
-
- rv = PK11_DigestBegin(md5);
- rv |= PK11_DigestOp(md5, hashBuf, bufLen);
- rv |= PK11_DigestFinal(md5, hashes->md5, &outLen, MD5_LENGTH);
- PORT_Assert(rv != SECSuccess || outLen == MD5_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto done;
- }
-
- rv = PK11_DigestBegin(sha);
- rv |= PK11_DigestOp(sha, hashBuf, bufLen);
- rv |= PK11_DigestFinal(sha, hashes->sha, &outLen, SHA1_LENGTH);
- PORT_Assert(rv != SECSuccess || outLen == SHA1_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- goto done;
- }
-
- PRINT_BUF(95, (NULL, "RSAkey hash: ", hashBuf, bufLen));
- PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result", hashes->md5, MD5_LENGTH));
- PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
-
-done:
- if (md5 != NULL) PK11_DestroyContext(md5, PR_TRUE);
- if (sha != NULL) PK11_DestroyContext(sha, PR_TRUE);
- if (hashBuf != buf && hashBuf != NULL)
- PORT_Free(hashBuf);
- return rv;
-}
-
-/* Caller must set hiLevel error code. */
-static SECStatus
-ssl3_ComputeFortezzaPublicKeyHash(SECItem publicValue, unsigned char * hash)
-{
- PK11Context *sha = NULL;
- SECStatus rv = SECFailure;
- unsigned int outLen;
-
- sha = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (sha == NULL) {
- return rv; /* Caller must set hiLevel error code. */
- }
-
- rv = PK11_DigestBegin(sha);
- rv |= PK11_DigestOp(sha, (unsigned char *)publicValue.data, publicValue.len);
- rv |= PK11_DigestFinal(sha, hash, &outLen, SHA1_LENGTH);
- PORT_Assert(rv != SECSuccess || outLen == SHA1_LENGTH);
- if (rv != SECSuccess)
- rv = SECFailure;
- PK11_DestroyContext(sha, PR_TRUE);
-
- return rv;
-}
-
-
-static void
-ssl3_BumpSequenceNumber(SSL3SequenceNumber *num)
-{
- num->low++;
- if (num->low == 0)
- num->high++;
-}
-
-/* Called only from ssl3_DestroyCipherSpec (immediately below). */
-static void
-ssl3_CleanupKeyMaterial(ssl3KeyMaterial *mat)
-{
- if (mat->write_key != NULL) {
- PK11_FreeSymKey(mat->write_key);
- mat->write_key = NULL;
- }
- if (mat->write_mac_key != NULL) {
- PK11_FreeSymKey(mat->write_mac_key);
- mat->write_mac_key = NULL;
- }
- if (mat->write_mac_context != NULL) {
- PK11_DestroyContext(mat->write_mac_context, PR_TRUE);
- mat->write_mac_context = NULL;
- }
-}
-
-/* Called from ssl3_SendChangeCipherSpecs() and ssl3_HandleChangeCipherSpecs()
-** Caller must hold SpecWriteLock.
-*/
-static void
-ssl3_DestroyCipherSpec(ssl3CipherSpec *spec)
-{
-
-/* PORT_Assert( ssl_HaveSpecWriteLock(ss)); Don't have ss! */
-
- if (spec->destroy) {
- spec->destroy(spec->encodeContext,PR_TRUE);
- spec->destroy(spec->decodeContext,PR_TRUE);
- spec->encodeContext = NULL; /* paranoia */
- spec->decodeContext = NULL;
- }
- if (spec->master_secret != NULL) {
- PK11_FreeSymKey(spec->master_secret);
- spec->master_secret = NULL;
- }
- ssl3_CleanupKeyMaterial(&spec->client);
- ssl3_CleanupKeyMaterial(&spec->server);
- spec->destroy=NULL;
-}
-
-/* Called from ssl3_HandleServerHello(), ssl3_SendServerHello()
-** Caller must hold the ssl3 handshake lock.
-** Acquires & releases SpecWriteLock.
-*/
-static SECStatus
-ssl3_SetupPendingCipherSpec(sslSocket *ss, ssl3State *ssl3)
-{
- ssl3CipherSpec * pwSpec;
- ssl3CipherSuite suite = ssl3->hs.cipher_suite;
- sslSecurityInfo * sec = ss->sec;
- SSL3MACAlgorithm mac;
- SSL3BulkCipher cipher;
- SSL3KeyExchangeAlgorithm kea;
- const ssl3CipherSuiteDef *suite_def;
- PRBool isTLS;
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- ssl_GetSpecWriteLock(ss); /*******************************/
-
- pwSpec = ssl3->pwSpec;
- PORT_Assert(pwSpec == ssl3->prSpec);
-
- pwSpec->version = ss->version;
- isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- SSL_TRC(3, ("%d: SSL3[%d]: Set XXX Pending Cipher Suite to 0x%04x",
- SSL_GETPID(), ss->fd, suite));
-
- suite_def = ssl_LookupCipherSuiteDef(suite);
- if (suite_def == NULL) {
- ssl_ReleaseSpecWriteLock(ss);
- return SECFailure; /* error code set by ssl_LookupCipherSuiteDef */
- }
-
-
- cipher = suite_def->bulk_cipher_alg;
- kea = suite_def->key_exchange_alg;
- mac = suite_def->mac_alg;
- if (isTLS)
- mac += 2;
-
- ssl3->hs.suite_def = suite_def;
- ssl3->hs.kea_def = &kea_defs[kea];
- PORT_Assert(ssl3->hs.kea_def->kea == kea);
-
- pwSpec->cipher_def = &bulk_cipher_defs[cipher];
- PORT_Assert(pwSpec->cipher_def->cipher == cipher);
-
- pwSpec->mac_def = &mac_defs[mac];
- PORT_Assert(pwSpec->mac_def->mac == mac);
-
-
- sec->keyBits = pwSpec->cipher_def->key_size * BPB;
- sec->secretKeyBits = pwSpec->cipher_def->secret_key_size * BPB;
- sec->cipherType = cipher;
-
- pwSpec->encodeContext = NULL;
- pwSpec->decodeContext = NULL;
-
- pwSpec->mac_size = pwSpec->mac_def->mac_size;
-
- ssl_ReleaseSpecWriteLock(ss); /*******************************/
- return SECSuccess;
-}
-
-/*
- * Called from: ssl3_SendClientKeyExchange (for Full handshake)
- * ssl3_HandleClientKeyExchange (for Full handshake)
- * ssl3_HandleServerHello (for session restart)
- * ssl3_HandleClientHello (for session restart)
- * Sets error code, but caller probably should override to disambiguate.
- * NULL pms means re-use old master_secret.
- */
-static SECStatus
-ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms)
-{
- ssl3CipherSpec * pwSpec;
- sslSecurityInfo * sec = ss->sec;
-const ssl3BulkCipherDef *cipher_def;
- PK11Context * serverContext = NULL;
- PK11Context * clientContext = NULL;
- SECItem * param;
- CK_ULONG macLength;
- SECStatus rv;
- CK_MECHANISM_TYPE mechanism;
- CK_MECHANISM_TYPE mac_mech;
- SECItem iv;
- SECItem mac_param;
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- ssl_GetSpecWriteLock(ss); /**************************************/
-
- PORT_Assert(ss->ssl3->prSpec == ss->ssl3->pwSpec);
-
- pwSpec = ss->ssl3->pwSpec;
- cipher_def = pwSpec->cipher_def;
- macLength = pwSpec->mac_size;
-
- /* generate session keys from pms (if pms is not NULL) or ms */
- rv = ssl3_GenerateSessionKeys(ss, pms);
- if (rv != SECSuccess) {
- goto bail_out; /* err code set by ssl3_GenerateSessionKeys */
- }
-
- pwSpec->client.write_mac_context = NULL;
- pwSpec->server.write_mac_context = NULL;
-
- mac_param.data = (unsigned char *)&macLength;
- mac_param.len = sizeof(macLength);
- mac_mech = (CK_MECHANISM_TYPE) pwSpec->mac_def->malg;
-
- if (cipher_def->calg == calg_null) {
- pwSpec->encode = Null_Cipher;
- pwSpec->decode = Null_Cipher;
- pwSpec->destroy = NULL;
- pwSpec->client.write_mac_context = PK11_CreateContextBySymKey(
- mac_mech, CKA_SIGN, pwSpec->client.write_mac_key, &mac_param);
- if (pwSpec->client.write_mac_context == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
- pwSpec->server.write_mac_context = PK11_CreateContextBySymKey(
- mac_mech, CKA_SIGN, pwSpec->server.write_mac_key, &mac_param);
- if (pwSpec->server.write_mac_context == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
- goto success;
- }
-
- mechanism = (CK_MECHANISM_TYPE) cipher_def->calg;
-
- /*
- * build the server context
- */
- iv.data = pwSpec->server.write_iv;
- iv.len = cipher_def->iv_size;
- param = PK11_ParamFromIV(mechanism, &iv);
- if (param == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
- goto fail;
- }
- serverContext = PK11_CreateContextBySymKey(mechanism,
- (sec->isServer ? CKA_ENCRYPT : CKA_DECRYPT),
- pwSpec->server.write_key, param);
- iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len);
- if (iv.data)
- PORT_Memcpy(pwSpec->server.write_iv, iv.data, iv.len);
- SECITEM_FreeItem(param, PR_TRUE);
- if (serverContext == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
-
- /*
- * build the client context
- */
- iv.data = pwSpec->client.write_iv;
- iv.len = cipher_def->iv_size;
- param = PK11_ParamFromIV(mechanism, &iv);
- if (param == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
- goto fail;
- }
- clientContext = PK11_CreateContextBySymKey(mechanism,
- (sec->isServer ? CKA_DECRYPT : CKA_ENCRYPT),
- pwSpec->client.write_key, param);
- iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len);
- if (iv.data)
- PORT_Memcpy(pwSpec->client.write_iv, iv.data, iv.len);
- SECITEM_FreeItem(param,PR_TRUE);
- if (clientContext == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
-
- pwSpec->encodeContext = (sec->isServer) ? serverContext : clientContext;
- pwSpec->decodeContext = (sec->isServer) ? clientContext : serverContext;
- pwSpec->encode = (SSLCipher) PK11_CipherOp;
- pwSpec->decode = (SSLCipher) PK11_CipherOp;
- pwSpec->destroy = (SSLDestroy) PK11_DestroyContext;
-
- serverContext = NULL;
- clientContext = NULL;
-
- pwSpec->client.write_mac_context = PK11_CreateContextBySymKey(
- mac_mech,CKA_SIGN, pwSpec->client.write_mac_key,&mac_param);
- if (pwSpec->client.write_mac_context == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
- pwSpec->server.write_mac_context = PK11_CreateContextBySymKey(
- mac_mech, CKA_SIGN, pwSpec->server.write_mac_key,&mac_param);
- if (pwSpec->server.write_mac_context == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
-success:
- ssl_ReleaseSpecWriteLock(ss); /******************************/
- return SECSuccess;
-
-fail:
- if (serverContext != NULL) PK11_DestroyContext(serverContext, PR_TRUE);
- if (clientContext != NULL) PK11_DestroyContext(clientContext, PR_TRUE);
- if (pwSpec->client.write_mac_context != NULL) {
- PK11_DestroyContext(pwSpec->client.write_mac_context,PR_TRUE);
- pwSpec->client.write_mac_context = NULL;
- }
- if (pwSpec->server.write_mac_context != NULL) {
- PK11_DestroyContext(pwSpec->server.write_mac_context,PR_TRUE);
- pwSpec->server.write_mac_context = NULL;
- }
-bail_out:
- ssl_ReleaseSpecWriteLock(ss);
- return SECFailure;
-}
-
-/*
- * 60 bytes is 3 times the maximum length MAC size that is supported.
- */
-static const unsigned char mac_pad_1 [60] = {
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36
-};
-static const unsigned char mac_pad_2 [60] = {
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c
-};
-
-/* Called from: ssl3_SendRecord()
-** ssl3_HandleRecord()
-** Caller must already hold the SpecReadLock. (wish we could assert that!)
-*/
-static SECStatus
-ssl3_ComputeRecordMAC(
- ssl3CipherSpec * spec,
- PK11Context * mac_context,
- SSL3ContentType type,
- SSL3ProtocolVersion version,
- SSL3SequenceNumber seq_num,
- SSL3Opaque * input,
- int inputLength,
- unsigned char * outbuf,
- unsigned int * outLength)
-{
- const ssl3MACDef * mac_def;
- SECStatus rv;
- unsigned int tempLen;
- unsigned char temp[MAX_MAC_LENGTH];
-
-/* ssl_GetSpecReadLock(ss); Don't have "ss"! */
-
- mac_def = spec->mac_def;
- if (mac_def->malg == malg_null) {
- *outLength = 0;
-/* ssl_ReleaseSpecReadLock(ss); */
- return SECSuccess;
- }
-
- temp[0] = (unsigned char)(seq_num.high >> 24);
- temp[1] = (unsigned char)(seq_num.high >> 16);
- temp[2] = (unsigned char)(seq_num.high >> 8);
- temp[3] = (unsigned char)(seq_num.high >> 0);
- temp[4] = (unsigned char)(seq_num.low >> 24);
- temp[5] = (unsigned char)(seq_num.low >> 16);
- temp[6] = (unsigned char)(seq_num.low >> 8);
- temp[7] = (unsigned char)(seq_num.low >> 0);
- temp[8] = type;
-
- /* TLS MAC includes the record's version field, SSL's doesn't.
- ** We decide which MAC defintion to use based on the version of
- ** the protocol that was negotiated when the spec became current,
- ** NOT based on the version value in the record itself.
- ** But, we use the record'v version value in the computation.
- */
- if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
- temp[9] = MSB(inputLength);
- temp[10] = LSB(inputLength);
- tempLen = 11;
- } else {
- /* New TLS hash includes version. */
- temp[9] = MSB(version);
- temp[10] = LSB(version);
- temp[11] = MSB(inputLength);
- temp[12] = LSB(inputLength);
- tempLen = 13;
- }
-
- PRINT_BUF(95, (NULL, "frag hash1: temp", temp, tempLen));
- PRINT_BUF(95, (NULL, "frag hash1: input", input, inputLength));
-
- rv = PK11_DigestBegin(mac_context);
- rv |= PK11_DigestOp(mac_context, temp, tempLen);
- rv |= PK11_DigestOp(mac_context, input, inputLength);
-
- rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size);
- PORT_Assert(rv != SECSuccess || *outLength == (unsigned)spec->mac_size);
-
-/* ssl_ReleaseSpecReadLock(ss); */
-
- PRINT_BUF(95, (NULL, "frag hash2: result", outbuf, *outLength));
-
- if (rv != SECSuccess) {
- rv = SECFailure;
- ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
- }
- return rv;
-}
-
-/* Process the plain text before sending it.
- * Returns the number of bytes of plaintext that were succesfully sent
- * plus the number of bytes of plaintext that were copied into the
- * output (write) buffer.
- * Returns SECFailure on a hard IO error, memory error, or crypto error.
- * Does NOT return SECWouldBlock.
- */
-static PRInt32
-ssl3_SendRecord( sslSocket * ss,
- SSL3ContentType type,
- const SSL3Opaque * buf,
- PRInt32 bytes,
- PRInt32 flags)
-{
- ssl3CipherSpec * cwSpec;
- sslBuffer * write = &ss->sec->writeBuf;
- const ssl3BulkCipherDef * cipher_def;
- SECStatus rv;
- PRUint32 bufSize = 0;
- PRInt32 sent = 0;
- PRInt32 cipherBytes = -1;
- PRBool isBlocking = ssl_SocketIsBlocking(ss);
- PRBool ssl3WasNull = PR_FALSE;
-
- SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s bytes=%d",
- SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
- bytes));
- PRINT_BUF(3, (ss, "Send record (plain text)", buf, bytes));
-
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
-
- if (ss->ssl3 == NULL) {
- /* This can happen on a server if the very first incoming record
- ** looks like a defective ssl3 record (e.g. too long), and we're
- ** trying to send an alert.
- */
- ssl3WasNull = PR_TRUE;
- PR_ASSERT(type == content_alert);
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- return SECFailure; /* ssl3_InitState has set the error code. */
- }
- }
-
- while (bytes > 0) {
- PRInt32 count;
- PRUint32 contentLen;
- PRUint32 fragLen;
- PRUint32 macLen;
-
- contentLen = PR_MIN(bytes, MAX_FRAGMENT_LENGTH);
- if (write->space < contentLen + SSL3_BUFFER_FUDGE) {
- rv = sslBuffer_Grow(write, contentLen + SSL3_BUFFER_FUDGE);
- if (rv != SECSuccess) {
- SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",
- SSL_GETPID(), ss->fd, contentLen + SSL3_BUFFER_FUDGE));
- return SECFailure; /* sslBuffer_Grow set a memory error code. */
- }
- }
-
- /* This variable records
- * the actual size of the buffer we allocated above. Some
- * algorithms (FORTEZZA) will expand the number of bytes it needs to
- * send data. If we only supply the output buffer with the same number
- * of bytes as the input buffer, we will fail.
- */
- bufSize = contentLen + SSL3_BUFFER_FUDGE;
-
- /*
- * null compression is easy to do
- */
- PORT_Memcpy(write->buf + SSL3_RECORD_HEADER_LENGTH, buf, contentLen);
- buf += contentLen;
- bytes -= contentLen;
- PORT_Assert( bytes >= 0 );
-
- ssl_GetSpecReadLock(ss); /********************************/
-
- cwSpec = ss->ssl3->cwSpec;
- cipher_def = cwSpec->cipher_def;
- /*
- * Add the MAC
- */
- rv = ssl3_ComputeRecordMAC(
- cwSpec, (ss->sec->isServer) ? cwSpec->server.write_mac_context
- : cwSpec->client.write_mac_context,
- type, cwSpec->version, cwSpec->write_seq_num,
- write->buf + SSL3_RECORD_HEADER_LENGTH, contentLen,
- write->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
- goto spec_locked_loser;
- }
- fragLen = contentLen + macLen; /* needs to be encrypted */
- PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024);
-
- /*
- * Pad the text (if we're doing a block cipher)
- * then Encrypt it
- */
- if (cipher_def->type == type_block) {
- int padding_length;
- int i;
- unsigned char * pBuf;
-
- /* Assume blockSize is a power of two */
- padding_length = cipher_def->block_size - 1 -
- ((fragLen) & (cipher_def->block_size - 1));
- fragLen += padding_length + 1;
- PORT_Assert((fragLen % cipher_def->block_size) == 0);
-
- /* Pad according to TLS rules (also acceptable to SSL3). */
- pBuf = &write->buf[fragLen + SSL3_RECORD_HEADER_LENGTH - 1];
- for (i = padding_length + 1; i > 0; --i) {
- *pBuf-- = padding_length;
- }
- }
- rv = cwSpec->encode(
- cwSpec->encodeContext, write->buf + SSL3_RECORD_HEADER_LENGTH,
- &cipherBytes, bufSize, write->buf + SSL3_RECORD_HEADER_LENGTH,
- fragLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_ENCRYPTION_FAILURE);
-spec_locked_loser:
- ssl_ReleaseSpecReadLock(ss);
- return SECFailure;
- }
- PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024);
-
- /*
- * XXX should we zero out our copy of the buffer after compressing
- * and encryption ??
- */
-
- ssl3_BumpSequenceNumber(&cwSpec->write_seq_num);
-
- ssl_ReleaseSpecReadLock(ss); /************************************/
-
- /* PORT_Assert(fragLen == cipherBytes); */
- write->len = cipherBytes + SSL3_RECORD_HEADER_LENGTH;
- write->buf[0] = type;
- write->buf[1] = MSB(cwSpec->version);
- write->buf[2] = LSB(cwSpec->version);
- write->buf[3] = MSB(cipherBytes);
- write->buf[4] = LSB(cipherBytes);
-
- PRINT_BUF(50, (ss, "send (encrypted) record data:", write->buf, write->len));
-
- /* If there's still some previously saved ciphertext,
- * or the caller doesn't want us to send the data yet,
- * then add all our new ciphertext to the amount previously saved.
- */
- if ((ss->pendingBuf.len > 0) ||
- (flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
-
- rv = ssl_SaveWriteData(ss, &ss->pendingBuf,
- write->buf, write->len);
- if (rv != SECSuccess) {
- /* presumably a memory error, SEC_ERROR_NO_MEMORY */
- return SECFailure;
- }
- write->len = 0; /* All cipher text is saved away. */
-
- if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
-
- count = ssl_SendSavedWriteData(ss, &ss->pendingBuf,
- &ssl_DefSend);
- if (count < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) {
- ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
- return SECFailure;
- }
- }
- } else if (write->len > 0) {
- count = ssl_DefSend(ss, write->buf, write->len,
- flags & ~ssl_SEND_FLAG_MASK);
- if (count < 0) {
- if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
- ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
- return (sent > 0) ? sent : SECFailure;
- }
- /* we got PR_WOULD_BLOCK_ERROR, which means none was sent. */
- count = 0;
- }
- /* now take all the remaining unsent newly-generated ciphertext and
- * append it to the buffer of previously unsent ciphertext.
- */
- if ((unsigned)count < write->len) {
- rv = ssl_SaveWriteData(ss, &ss->pendingBuf,
- write->buf + (unsigned)count,
- write->len - (unsigned)count);
- if (rv != SECSuccess) {
- /* presumably a memory error, SEC_ERROR_NO_MEMORY */
- return SECFailure;
- }
- }
- write->len = 0;
- }
- sent += contentLen;
- if ((flags & ssl_SEND_FLAG_NO_BUFFER) &&
- (isBlocking || (ss->pendingBuf.len > 0))) {
- break;
- }
- }
- return sent;
-}
-
-/* Attempt to send the content of "in" in an SSL application_data record.
- * Returns "len" or SECFailure, never SECWouldBlock, nor SECSuccess.
- */
-int
-ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
- PRInt32 len, PRInt32 flags)
-{
- PRInt32 sent = 0;
-
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
-
- while (len > 0) {
- PRInt32 count;
-
- if (sent > 0) {
- ssl_ReleaseXmitBufLock(ss);
- PR_Sleep(PR_INTERVAL_NO_WAIT); /* PR_Yield(); */
- ssl_GetXmitBufLock(ss);
- }
- count = ssl3_SendRecord(ss, content_application_data, in, len,
- flags | ssl_SEND_FLAG_NO_BUFFER);
- if (count < 0) {
- return (sent > 0) ? sent : count;
- /* error code set by ssl3_SendRecord */
- }
- sent += count;
- len -= count;
- in += count;
- }
- return sent;
-}
-
-/* Attempt to send the content of sendBuf buffer in an SSL handshake record.
- * This function returns SECSuccess or SECFailure, never SECWouldBlock.
- * It used to always set sendBuf.len to 0, even when returning SECFailure.
- * Now it does not.
- *
- * Called from SSL3_SendAlert(), ssl3_SendChangeCipherSpecs(),
- * ssl3_AppendHandshake(), ssl3_SendClientHello(),
- * ssl3_SendHelloRequest(), ssl3_SendServerHelloDone(),
- * ssl3_SendFinished(),
- */
-static SECStatus
-ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags)
-{
- PRInt32 rv;
- sslConnectInfo *ci;
-
- PORT_Assert(ss->sec != NULL);
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
-
- ci = &ss->sec->ci;
-
- if (!ci->sendBuf.buf || !ci->sendBuf.len)
- return SECSuccess;
-
- rv = ssl3_SendRecord(ss, content_handshake, ci->sendBuf.buf,
- ci->sendBuf.len, flags);
- if (rv < 0) {
- return (SECStatus)rv; /* error code set by ssl3_SendRecord */
- }
- ci->sendBuf.len = 0;
- return SECSuccess;
-}
-
-/*
- * Called from ssl3_HandleAlert and from ssl3_HandleCertificates when
- * the remote client sends a negative response to our certificate request.
- * Returns SECFailure if the application has required client auth.
- * SECSuccess otherwise.
- */
-static SECStatus
-ssl3_HandleNoCertificate(sslSocket *ss)
-{
- if (ss->sec->peerCert != NULL) {
- if (ss->sec->peerKey != NULL) {
- SECKEY_DestroyPublicKey(ss->sec->peerKey);
- ss->sec->peerKey = NULL;
- }
- CERT_DestroyCertificate(ss->sec->peerCert);
- ss->sec->peerCert = NULL;
- }
-
- /* If the server has required client-auth blindly but doesn't
- * actually look at the certificate it won't know that no
- * certificate was presented so we shutdown the socket to ensure
- * an error. We only do this if we aren't connected because
- * if we're redoing the handshake we know the server is paying
- * attention to the certificate.
- */
- if ((ss->requireCertificate == 1) ||
- (!ss->connected && (ss->requireCertificate > 1))) {
- PRFileDesc * lower;
-
- ss->sec->uncache(ss->sec->ci.sid);
- SSL3_SendAlert(ss, alert_fatal, bad_certificate);
-
- lower = ss->fd->lower;
- lower->methods->shutdown(lower, PR_SHUTDOWN_BOTH);
- PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/************************************************************************
- * Alerts
- */
-
-/*
-** Acquires both handshake and XmitBuf locks.
-** Called from: ssl3_IllegalParameter <-
-** ssl3_HandshakeFailure <-
-** ssl3_HandleAlert <- ssl3_HandleRecord.
-** ssl3_HandleChangeCipherSpecs <- ssl3_HandleRecord
-** ssl3_ConsumeHandshakeVariable <-
-** ssl3_HandleHelloRequest <-
-** ssl3_HandleServerHello <-
-** ssl3_HandleServerKeyExchange <-
-** ssl3_HandleCertificateRequest <-
-** ssl3_HandleServerHelloDone <-
-** ssl3_HandleClientHello <-
-** ssl3_HandleV2ClientHello <-
-** ssl3_HandleCertificateVerify <-
-** ssl3_HandleFortezzaClientKeyExchange <-
-** ssl3_HandleClientKeyExchange <-
-** ssl3_HandleCertificate <-
-** ssl3_HandleFinished <-
-** ssl3_HandleHandshakeMessage <-
-** ssl3_HandleRecord <-
-**
-*/
-SECStatus
-SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc)
-{
- uint8 bytes[2];
- SECStatus rv;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send alert record, level=%d desc=%d",
- SSL_GETPID(), ss->fd, level, desc));
-
- bytes[0] = level;
- bytes[1] = desc;
-
- ssl_GetSSL3HandshakeLock(ss);
- if (level == alert_fatal) {
- if (ss->sec->ci.sid) {
- ss->sec->uncache(ss->sec->ci.sid);
- }
- }
- ssl_GetXmitBufLock(ss);
- rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
- if (rv == SECSuccess) {
- PRInt32 sent;
- sent = ssl3_SendRecord(ss, content_alert, bytes, 2, 0);
- rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
- }
- ssl_ReleaseXmitBufLock(ss);
- ssl_ReleaseSSL3HandshakeLock(ss);
- return rv; /* error set by ssl3_FlushHandshake or ssl3_SendRecord */
-}
-
-/*
- * Send illegal_parameter alert. Set generic error number.
- */
-static SECStatus
-ssl3_IllegalParameter(sslSocket *ss)
-{
- PRBool isTLS;
-
- isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- PORT_SetError(ss->sec->isServer ? SSL_ERROR_BAD_CLIENT
- : SSL_ERROR_BAD_SERVER );
- return SECFailure;
-}
-
-/*
- * Send handshake_Failure alert. Set generic error number.
- */
-static SECStatus
-ssl3_HandshakeFailure(sslSocket *ss)
-{
- (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
- PORT_SetError( ss->sec->isServer ? SSL_ERROR_BAD_CLIENT
- : SSL_ERROR_BAD_SERVER );
- return SECFailure;
-}
-
-/*
- * Send handshake_Failure alert. Set generic error number.
- */
-static SECStatus
-ssl3_DecodeError(sslSocket *ss)
-{
- (void)SSL3_SendAlert(ss, alert_fatal,
- ss->version > SSL_LIBRARY_VERSION_3_0 ? decode_error
- : illegal_parameter);
- PORT_SetError( ss->sec->isServer ? SSL_ERROR_BAD_CLIENT
- : SSL_ERROR_BAD_SERVER );
- return SECFailure;
-}
-
-/* Called from ssl3_HandleRecord.
-** Caller must hold both RecvBuf and Handshake locks.
-*/
-static SECStatus
-ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
-{
- SSL3AlertLevel level;
- SSL3AlertDescription desc;
- int error;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle alert record", SSL_GETPID(), ss->fd));
-
- if (buf->len != 2) {
- (void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_ALERT);
- return SECFailure;
- }
- level = (SSL3AlertLevel)buf->buf[0];
- desc = (SSL3AlertDescription)buf->buf[1];
- buf->len = 0;
- SSL_TRC(5, ("%d: SSL3[%d] received alert, level = %d, description = %d",
- SSL_GETPID(), ss->fd, level, desc));
-
- switch (desc) {
- case close_notify: ss->recvdCloseNotify = 1;
- error = SSL_ERROR_CLOSE_NOTIFY_ALERT; break;
- case unexpected_message: error = SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT;
- break;
- case bad_record_mac: error = SSL_ERROR_BAD_MAC_ALERT; break;
- case decryption_failed: error = SSL_ERROR_DECRYPTION_FAILED_ALERT;
- break;
- case record_overflow: error = SSL_ERROR_RECORD_OVERFLOW_ALERT; break;
- case decompression_failure: error = SSL_ERROR_DECOMPRESSION_FAILURE_ALERT;
- break;
- case handshake_failure: error = SSL_ERROR_HANDSHAKE_FAILURE_ALERT;
- break;
- case no_certificate: error = SSL_ERROR_NO_CERTIFICATE; break;
- case bad_certificate: error = SSL_ERROR_BAD_CERT_ALERT; break;
- case unsupported_certificate:error = SSL_ERROR_UNSUPPORTED_CERT_ALERT;break;
- case certificate_revoked: error = SSL_ERROR_REVOKED_CERT_ALERT; break;
- case certificate_expired: error = SSL_ERROR_EXPIRED_CERT_ALERT; break;
- case certificate_unknown: error = SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT;
- break;
- case illegal_parameter: error = SSL_ERROR_ILLEGAL_PARAMETER_ALERT;break;
-
- /* All alerts below are TLS only. */
- case unknown_ca: error = SSL_ERROR_UNKNOWN_CA_ALERT; break;
- case access_denied: error = SSL_ERROR_ACCESS_DENIED_ALERT; break;
- case decode_error: error = SSL_ERROR_DECODE_ERROR_ALERT; break;
- case decrypt_error: error = SSL_ERROR_DECRYPT_ERROR_ALERT; break;
- case export_restriction: error = SSL_ERROR_EXPORT_RESTRICTION_ALERT;
- break;
- case protocol_version: error = SSL_ERROR_PROTOCOL_VERSION_ALERT; break;
- case insufficient_security: error = SSL_ERROR_INSUFFICIENT_SECURITY_ALERT;
- break;
- case internal_error: error = SSL_ERROR_INTERNAL_ERROR_ALERT; break;
- case user_canceled: error = SSL_ERROR_USER_CANCELED_ALERT; break;
- case no_renegotiation: error = SSL_ERROR_NO_RENEGOTIATION_ALERT; break;
- default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break;
- }
- if (level == alert_fatal) {
- ss->sec->uncache(ss->sec->ci.sid);
- if ((ss->ssl3->hs.ws == wait_server_hello) &&
- (desc == handshake_failure)) {
- /* XXX This is a hack. We're assuming that any handshake failure
- * XXX on the client hello is a failure to match ciphers.
- */
- error = SSL_ERROR_NO_CYPHER_OVERLAP;
- }
- PORT_SetError(error);
- return SECFailure;
- }
- if ((desc == no_certificate) && (ss->ssl3->hs.ws == wait_client_cert)) {
- /* I'm a server. I've requested a client cert. He hasn't got one. */
- SECStatus rv;
-
- PORT_Assert(ss->sec->isServer);
- ss->ssl3->hs.ws = wait_client_key;
- rv = ssl3_HandleNoCertificate(ss);
- return rv;
- }
- return SECSuccess;
-}
-
-/*
- * Change Cipher Specs
- * Called from ssl3_HandleServerHelloDone,
- * ssl3_HandleClientHello,
- * and ssl3_HandleFinished
- *
- * Acquires and releases spec write lock, to protect switching the current
- * and pending write spec pointers.
- */
-
-static SECStatus
-ssl3_SendChangeCipherSpecs(sslSocket *ss)
-{
- uint8 change = change_cipher_spec_choice;
- ssl3State * ssl3 = ss->ssl3;
- ssl3CipherSpec * pwSpec;
- SECStatus rv;
- PRInt32 sent;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send change_cipher_spec record",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
- sent = ssl3_SendRecord(ss, content_change_cipher_spec, &change, 1,
- ssl_SEND_FLAG_FORCE_INTO_BUFFER);
- if (sent < 0) {
- return (SECStatus)sent; /* error code set by ssl3_SendRecord */
- }
-
- /* swap the pending and current write specs. */
- ssl_GetSpecWriteLock(ss); /**************************************/
- pwSpec = ss->ssl3->pwSpec;
- pwSpec->write_seq_num.high = 0;
- pwSpec->write_seq_num.low = 0;
-
- ssl3->pwSpec = ssl3->cwSpec;
- ssl3->cwSpec = pwSpec;
-
- SSL_TRC(3, ("%d: SSL3[%d] Set Current Write Cipher Suite to Pending",
- SSL_GETPID(), ss->fd ));
-
- /* We need to free up the contexts, keys and certs ! */
- /* If we are really through with the old cipher spec
- * (Both the read and write sides have changed) destroy it.
- */
- if (ss->ssl3->prSpec == ss->ssl3->pwSpec) {
- ssl3_DestroyCipherSpec(ss->ssl3->pwSpec);
- }
- ssl_ReleaseSpecWriteLock(ss); /**************************************/
-
- return SECSuccess;
-}
-
-/* Called from ssl3_HandleRecord.
-** Caller must hold both RecvBuf and Handshake locks.
- *
- * Acquires and releases spec write lock, to protect switching the current
- * and pending write spec pointers.
-*/
-static SECStatus
-ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf)
-{
- ssl3CipherSpec * prSpec;
- SSL3WaitState ws = ss->ssl3->hs.ws;
- SSL3ChangeCipherSpecChoice change;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle change_cipher_spec record",
- SSL_GETPID(), ss->fd));
-
- if (ws != wait_change_cipher && ws != wait_cert_verify) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
- return SECFailure;
- }
-
- if(buf->len != 1) {
- (void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER);
- return SECFailure;
- }
- change = (SSL3ChangeCipherSpecChoice)buf->buf[0];
- if (change != change_cipher_spec_choice) {
- /* illegal_parameter is correct here for both SSL3 and TLS. */
- (void)ssl3_IllegalParameter(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER);
- return SECFailure;
- }
- buf->len = 0;
-
- /* Swap the pending and current read specs. */
- ssl_GetSpecWriteLock(ss); /*************************************/
- prSpec = ss->ssl3->prSpec;
- prSpec->read_seq_num.high = prSpec->read_seq_num.low = 0;
-
- ss->ssl3->prSpec = ss->ssl3->crSpec;
- ss->ssl3->crSpec = prSpec;
- ss->ssl3->hs.ws = wait_finished;
-
- SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending",
- SSL_GETPID(), ss->fd ));
-
- /* If we are really through with the old cipher prSpec
- * (Both the read and write sides have changed) destroy it.
- */
- if (ss->ssl3->prSpec == ss->ssl3->pwSpec) {
- ssl3_DestroyCipherSpec(ss->ssl3->prSpec);
- }
- ssl_ReleaseSpecWriteLock(ss); /*************************************/
- return SECSuccess;
-}
-
-/*
- * Key generation given pre master secret, or master secret (if !pms).
- * Sets a useful error code when returning SECFailure.
- *
- * Called only from ssl3_InitPendingCipherSpec(),
- *
- * which in turn is called from
- * ssl3_SendClientKeyExchange (for Full handshake)
- * ssl3_HandleClientKeyExchange (for Full handshake)
- * ssl3_HandleServerHello (for session restart)
- * ssl3_HandleClientHello (for session restart)
- * Caller MUST hold the specWriteLock, and SSL3HandshakeLock.
- * ssl3_InitPendingCipherSpec does that.
- */
-static SECStatus
-ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms)
-{
- ssl3CipherSpec * pwSpec = ss->ssl3->pwSpec;
- const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def;
- const ssl3KEADef * kea_def = ss->ssl3->hs.kea_def;
- unsigned char * cr = (unsigned char *)&ss->ssl3->hs.client_random;
- unsigned char * sr = (unsigned char *)&ss->ssl3->hs.server_random;
- PK11SymKey * symKey = NULL;
- PK11SlotInfo * slot = NULL;
- void * pwArg = ss->pkcs11PinArg;
- PRBool isTLS = (PRBool)(kea_def->tls_keygen ||
- (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
- PRBool skipKeysAndIVs = (PRBool)
- ((cipher_def->calg == calg_fortezza) ||
- (cipher_def->calg == calg_null));
- CK_MECHANISM_TYPE master_derive;
- CK_MECHANISM_TYPE key_derive;
- CK_MECHANISM_TYPE bulk_mechanism;
- SECItem params;
- int keySize;
- CK_FLAGS keyFlags;
- CK_VERSION pms_version;
- CK_SSL3_KEY_MAT_PARAMS key_material_params;
- CK_SSL3_KEY_MAT_OUT returnedKeys;
- CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ssl_HaveSpecWriteLock(ss));
- PORT_Assert(ss->ssl3->prSpec == ss->ssl3->pwSpec);
-
- if (isTLS) {
- master_derive = CKM_TLS_MASTER_KEY_DERIVE;
- key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
- keyFlags = CKF_SIGN | CKF_VERIFY;
- } else {
- master_derive = CKM_SSL3_MASTER_KEY_DERIVE;
- key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE;
- keyFlags = 0;
- }
-
- if (pms || !pwSpec->master_secret) {
- 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;
-
- params.data = (unsigned char *) &master_params;
- params.len = sizeof master_params;
- }
-
- if (pms != NULL) {
- pwSpec->master_secret = PK11_DeriveWithFlags((PK11SymKey *)pms,
- master_derive, &params, key_derive,
- CKA_DERIVE, 0, keyFlags);
- if (pwSpec->master_secret != NULL && ss->detectRollBack) {
- SSL3ProtocolVersion client_version;
- client_version = pms_version.major << 8 | pms_version.minor;
- 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);
- }
- }
- }
- 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);
- }
- }
- if (pwSpec->master_secret == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- return SECFailure;
- }
-
- /*
- * generate the key material
- */
- key_material_params.ulMacSizeInBits = pwSpec->mac_size * BPB;
- key_material_params.ulKeySizeInBits = cipher_def->secret_key_size* BPB;
- key_material_params.ulIVSizeInBits = cipher_def->iv_size * BPB;
-
- key_material_params.bIsExport = (CK_BBOOL)(kea_def->is_limited);
- /* was: (CK_BBOOL)(cipher_def->keygen_mode != kg_strong); */
-
- key_material_params.RandomInfo.pClientRandom = cr;
- key_material_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
- key_material_params.RandomInfo.pServerRandom = sr;
- key_material_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
- key_material_params.pReturnedKeyMaterial = &returnedKeys;
-
- returnedKeys.pIVClient = pwSpec->client.write_iv;
- returnedKeys.pIVServer = pwSpec->server.write_iv;
- keySize = cipher_def->key_size;
-
- if (skipKeysAndIVs) {
- keySize = 0;
- key_material_params.ulKeySizeInBits = 0;
- key_material_params.ulIVSizeInBits = 0;
- returnedKeys.pIVClient = NULL;
- returnedKeys.pIVServer = NULL;
- }
- bulk_mechanism = (CK_MECHANISM_TYPE) cipher_def->calg;
- params.data = (unsigned char *)&key_material_params;
- params.len = sizeof(key_material_params);
-
- /* CKM_SSL3_KEY_AND_MAC_DERIVE is defined to set ENCRYPT, DECRYPT, and
- * DERIVE by DEFAULT */
- symKey = PK11_Derive(pwSpec->master_secret, key_derive, &params,
- bulk_mechanism, CKA_ENCRYPT, keySize);
- if (!symKey) {
- ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- return SECFailure;
- }
- /* we really should use the actual mac'ing mechanism here, but we
- * don't because these types are used to map keytype anyway and both
- * mac's map to the same keytype.
- */
- slot = PK11_GetSlotFromKey(symKey);
-
- PK11_FreeSlot(slot); /* slot is held until the key is freed */
- pwSpec->client.write_mac_key =
- PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
- CKM_SSL3_SHA1_MAC, returnedKeys.hClientMacSecret, PR_TRUE, pwArg);
- if (pwSpec->client.write_mac_key == NULL ) {
- goto loser; /* loser sets err */
- }
- pwSpec->server.write_mac_key =
- PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
- CKM_SSL3_SHA1_MAC, returnedKeys.hServerMacSecret, PR_TRUE, pwArg);
- if (pwSpec->server.write_mac_key == NULL ) {
- goto loser; /* loser sets err */
- }
- if (!skipKeysAndIVs) {
- pwSpec->client.write_key =
- PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
- bulk_mechanism, returnedKeys.hClientKey, PR_TRUE, pwArg);
- if (pwSpec->client.write_key == NULL ) {
- goto loser; /* loser sets err */
- }
- pwSpec->server.write_key =
- PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
- bulk_mechanism, returnedKeys.hServerKey, PR_TRUE, pwArg);
- if (pwSpec->server.write_key == NULL ) {
- goto loser; /* loser sets err */
- }
- }
- PK11_FreeSymKey(symKey);
- return SECSuccess;
-
-
-loser:
- if (symKey) PK11_FreeSymKey(symKey);
- ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- return SECFailure;
-}
-
-/*
- * Handshake messages
- */
-/* Called from ssl3_AppendHandshake()
-** ssl3_StartHandshakeHash()
-** ssl3_HandleV2ClientHello()
-** ssl3_HandleHandshakeMessage()
-** Caller must hold the ssl3Handshake lock.
-*/
-static SECStatus
-ssl3_UpdateHandshakeHashes(sslSocket *ss, unsigned char *b, unsigned int l)
-{
- ssl3State *ssl3 = ss->ssl3;
- SECStatus rv;
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- PRINT_BUF(90, (NULL, "MD5 & SHA handshake hash input:", b, l));
-
- rv = PK11_DigestOp(ssl3->hs.md5, b, l);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return rv;
- }
- rv = PK11_DigestOp(ssl3->hs.sha, b, l);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return rv;
- }
- return rv;
-}
-
-/**************************************************************************
- * Append Handshake functions.
- * All these functions set appropriate error codes.
- * Most rely on ssl3_AppendHandshake to set the error code.
- **************************************************************************/
-static SECStatus
-ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes)
-{
- sslConnectInfo * ci = &ss->sec->ci;
- unsigned char * src = (unsigned char *)void_src;
- int room = ci->sendBuf.space - ci->sendBuf.len;
- SECStatus rv;
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) ); /* protects sendBuf. */
-
- if (ci->sendBuf.space < MAX_SEND_BUF_LENGTH && room < bytes) {
- rv = sslBuffer_Grow(&ci->sendBuf, PR_MAX(MIN_SEND_BUF_LENGTH,
- PR_MIN(MAX_SEND_BUF_LENGTH,
- ci->sendBuf.len + bytes)));
- if (rv != SECSuccess)
- return rv; /* sslBuffer_Grow has set a memory error code. */
- room = ci->sendBuf.space - ci->sendBuf.len;
- }
-
- PRINT_BUF(60, (ss, "Append to Handshake", (unsigned char*)void_src, bytes));
- rv = ssl3_UpdateHandshakeHashes(ss, src, bytes);
- if (rv != SECSuccess)
- return rv; /* error code set by ssl3_UpdateHandshakeHashes */
-
- while (bytes > room) {
- if (room > 0)
- PORT_Memcpy(ci->sendBuf.buf + ci->sendBuf.len, src, room);
- ci->sendBuf.len += room;
- rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
- bytes -= room;
- src += room;
- room = ci->sendBuf.space;
- PORT_Assert(ci->sendBuf.len == 0);
- }
- PORT_Memcpy(ci->sendBuf.buf + ci->sendBuf.len, src, bytes);
- ci->sendBuf.len += bytes;
- return SECSuccess;
-}
-
-static SECStatus
-ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize)
-{
- SECStatus rv;
- uint8 b[4];
- uint8 * p = b;
-
- switch (lenSize) {
- case 4:
- *p++ = (num >> 24) & 0xff;
- case 3:
- *p++ = (num >> 16) & 0xff;
- case 2:
- *p++ = (num >> 8) & 0xff;
- case 1:
- *p = num & 0xff;
- }
- SSL_TRC(60, ("%d: number:", SSL_GETPID()));
- rv = ssl3_AppendHandshake(ss, &b[0], lenSize);
- return rv; /* error code set by AppendHandshake, if applicable. */
-}
-
-static SECStatus
-ssl3_AppendHandshakeVariable(
- sslSocket *ss, const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize)
-{
- SECStatus rv;
-
- PORT_Assert((bytes < (1<<8) && lenSize == 1) ||
- (bytes < (1L<<16) && lenSize == 2) ||
- (bytes < (1L<<24) && lenSize == 3));
-
- SSL_TRC(60,("%d: append variable:", SSL_GETPID()));
- rv = ssl3_AppendHandshakeNumber(ss, bytes, lenSize);
- if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake, if applicable. */
- }
- SSL_TRC(60, ("data:"));
- rv = ssl3_AppendHandshake(ss, src, bytes);
- return rv; /* error code set by AppendHandshake, if applicable. */
-}
-
-static SECStatus
-ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length)
-{
- SECStatus rv;
-
- SSL_TRC(30,("%d: SSL3[%d]: append handshake header: type %s",
- SSL_GETPID(), ss->fd, ssl3_DecodeHandshakeType(t)));
- PRINT_BUF(60, (ss, "MD5 handshake hash:",
- (unsigned char*)ss->ssl3->hs.md5, MD5_LENGTH));
- PRINT_BUF(95, (ss, "SHA handshake hash:",
- (unsigned char*)ss->ssl3->hs.sha, SHA1_LENGTH));
-
- rv = ssl3_AppendHandshakeNumber(ss, t, 1);
- if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake, if applicable. */
- }
- rv = ssl3_AppendHandshakeNumber(ss, length, 3);
- return rv; /* error code set by AppendHandshake, if applicable. */
-}
-
-/**************************************************************************
- * Consume Handshake functions.
- *
- * All data used in these functions is protected by two locks,
- * the RecvBufLock and the SSL3HandshakeLock
- **************************************************************************/
-
-/* Read up the next "bytes" number of bytes from the (decrypted) input
- * stream "b" (which is *length bytes long). Copy them into buffer "v".
- * Reduces *length by bytes. Advances *b by bytes.
- *
- * If this function returns SECFailure, it has already sent an alert,
- * and has set a generic error code. The caller should probably
- * override the generic error code by setting another.
- */
-static SECStatus
-ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b,
- PRUint32 *length)
-{
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- if (bytes > *length) {
- return ssl3_DecodeError(ss);
- }
- PORT_Memcpy(v, *b, bytes);
- PRINT_BUF(60, (ss, "consume bytes:", *b, bytes));
- *b += bytes;
- *length -= bytes;
- return SECSuccess;
-}
-
-/* Read up the next "bytes" number of bytes from the (decrypted) input
- * stream "b" (which is *length bytes long), and interpret them as an
- * integer in network byte order. Returns the received value.
- * Reduces *length by bytes. Advances *b by bytes.
- *
- * Returns SECFailure (-1) on failure.
- * This value is indistinguishable from the equivalent received value.
- * Only positive numbers are to be received this way.
- * Thus, the largest value that may be sent this way is 0x7fffffff.
- * On error, an alert has been sent, and a generic error code has been set.
- */
-static PRInt32
-ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b,
- PRUint32 *length)
-{
- PRInt32 num = 0;
- int i;
- SECStatus status;
- uint8 buf[4];
-
- status = ssl3_ConsumeHandshake(ss, buf, bytes, b, length);
- if (status != SECSuccess) {
- /* ssl3_DecodeError has already been called */
- return SECFailure;
- }
- for (i = 0; i < bytes; i++)
- num = (num << 8) + buf[i];
- return num;
-}
-
-/* Read in two values from the incoming decrypted byte stream "b", which is
- * *length bytes long. The first value is a number whose size is "bytes"
- * bytes long. The second value is a byte-string whose size is the value
- * of the first number received. The latter byte-string, and its length,
- * is returned in the SECItem i.
- *
- * Returns SECFailure (-1) on failure.
- * On error, an alert has been sent, and a generic error code has been set.
- */
-static SECStatus
-ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
- SSL3Opaque **b, PRUint32 *length)
-{
- PRInt32 count;
- SECStatus rv;
-
- PORT_Assert(bytes <= 3);
- i->len = 0;
- i->data = NULL;
- count = ssl3_ConsumeHandshakeNumber(ss, bytes, b, length);
- if (count < 0) { /* Can't test for SECSuccess here. */
- return SECFailure;
- }
- if (count > 0) {
- i->data = (unsigned char*)PORT_Alloc(count);
- if (i->data == NULL) {
- /* XXX inconsistent. In other places, we don't send alerts for
- * our own memory failures. But here we do... */
- (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- i->len = count;
- rv = ssl3_ConsumeHandshake(ss, i->data, i->len, b, length);
- if (rv != SECSuccess) {
- PORT_Free(i->data);
- i->data = NULL;
- return rv; /* alert has already been sent. */
- }
- }
- return SECSuccess;
-}
-
-/**************************************************************************
- * end of Consume Handshake functions.
- **************************************************************************/
-
-/* Extract the hashes of handshake messages to this point.
- * Called from ssl3_SendCertificateVerify
- * ssl3_SendFinished
- * ssl3_HandleHandshakeMessage
- *
- * Caller must hold the SSL3HandshakeLock.
- * Caller must hold a read or write lock on the Spec R/W lock.
- * (There is presently no way to assert on a Read lock.)
- */
-static SECStatus
-ssl3_ComputeHandshakeHashes(sslSocket * ss,
- ssl3CipherSpec *spec, /* uses ->master_secret */
- SSL3Hashes * hashes, /* output goes here. */
- uint32 sender)
-{
- ssl3State * ssl3 = ss->ssl3;
- PK11Context * md5;
- PK11Context * sha = NULL;
- SECStatus rv = SECSuccess;
- unsigned int outLength;
- PRBool isTLS;
- SSL3Opaque md5_inner[MAX_MAC_LENGTH];
- SSL3Opaque sha_inner[MAX_MAC_LENGTH];
- unsigned char s[4];
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0);
-
- md5 = PK11_CloneContext(ssl3->hs.md5);
- if (md5 == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return SECFailure;
- }
-
- sha = PK11_CloneContext(ssl3->hs.sha);
- if (sha == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- goto loser;
- }
-
- if (!isTLS) {
- /* compute hashes for SSL3. */
-
- s[0] = (unsigned char)(sender >> 24);
- s[1] = (unsigned char)(sender >> 16);
- s[2] = (unsigned char)(sender >> 8);
- s[3] = (unsigned char)sender;
-
- if (sender != 0) {
- rv |= PK11_DigestOp(md5, s, 4);
- PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4));
- }
-
- PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1, mac_defs[mac_md5].pad_size));
-
- rv |= PK11_DigestKey(md5,spec->master_secret);
- rv |= PK11_DigestOp(md5, mac_pad_1, mac_defs[mac_md5].pad_size);
- rv |= PK11_DigestFinal(md5, md5_inner, &outLength, MD5_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
-
- PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength));
-
- if (sender != 0) {
- rv |= PK11_DigestOp(sha, s, 4);
- PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4));
- }
-
- PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1, mac_defs[mac_sha].pad_size));
-
-
- rv |= PK11_DigestKey(sha, spec->master_secret);
- rv |= PK11_DigestOp(sha, mac_pad_1, mac_defs[mac_sha].pad_size);
- rv |= PK11_DigestFinal(sha, sha_inner, &outLength, SHA1_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
-
- PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength));
-
- PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2, mac_defs[mac_md5].pad_size));
- PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH));
-
- rv |= PK11_DigestBegin(md5);
- rv |= PK11_DigestKey(md5, spec->master_secret);
- rv |= PK11_DigestOp(md5, mac_pad_2, mac_defs[mac_md5].pad_size);
- rv |= PK11_DigestOp(md5, md5_inner, MD5_LENGTH);
- }
- rv |= PK11_DigestFinal(md5, hashes->md5, &outLength, MD5_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
-
- PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->md5, MD5_LENGTH));
-
- if (!isTLS) {
- PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2, mac_defs[mac_sha].pad_size));
- PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH));
-
- rv |= PK11_DigestBegin(sha);
- rv |= PK11_DigestKey(sha,spec->master_secret);
- rv |= PK11_DigestOp(sha, mac_pad_2, mac_defs[mac_sha].pad_size);
- rv |= PK11_DigestOp(sha, sha_inner, SHA1_LENGTH);
- }
- rv |= PK11_DigestFinal(sha, hashes->sha, &outLength, SHA1_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
-
- PRINT_BUF(60, (NULL, "SHA outer: result", hashes->sha, SHA1_LENGTH));
-
- rv = SECSuccess;
-
-loser:
- if (md5) PK11_DestroyContext(md5, PR_TRUE);
- if (sha) PK11_DestroyContext(sha, PR_TRUE);
-
- return rv;
-}
-
-/*
- * SSL 2 based implementations pass in the initial outbound buffer
- * so that the handshake hash can contain the included information.
- *
- * Called from ssl2_BeginClientHandshake() in sslcon.c
- */
-SECStatus
-ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length)
-{
- SECStatus rv;
-
- ssl_GetSSL3HandshakeLock(ss); /**************************************/
-
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- goto done; /* ssl3_InitState has set the error code. */
- }
-
- PORT_Memset(&ss->ssl3->hs.client_random, 0, SSL3_RANDOM_LENGTH);
- PORT_Memcpy(
- &ss->ssl3->hs.client_random.rand[SSL3_RANDOM_LENGTH - SSL_CHALLENGE_BYTES],
- &ss->sec->ci.clientChallenge,
- SSL_CHALLENGE_BYTES);
-
- rv = ssl3_UpdateHandshakeHashes(ss, buf, length);
- /* if it failed, ssl3_UpdateHandshakeHashes has set the error code. */
-
-done:
- ssl_ReleaseSSL3HandshakeLock(ss); /**************************************/
- return rv;
-}
-
-/**************************************************************************
- * end of Handshake Hash functions.
- * Begin Send and Handle functions for handshakes.
- **************************************************************************/
-
-/* Called from ssl3_HandleHelloRequest(),
- * ssl3_HandleFinished() (for step-up)
- * ssl3_RedoHandshake()
- * ssl2_BeginClientHandshake (when resuming ssl3 session)
- */
-SECStatus
-ssl3_SendClientHello(sslSocket *ss)
-{
- sslSecurityInfo *sec = ss->sec;
- sslSessionID * sid;
- SECStatus rv;
- int i;
- int length;
- int num_suites;
- int actual_count = 0;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),
- ss->fd));
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
-
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- return rv; /* ssl3_InitState has set the error code. */
- }
-
- SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
- SSL_GETPID(), ss->fd ));
- rv = PK11_DigestBegin(ss->ssl3->hs.md5);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return rv;
- }
- rv = PK11_DigestBegin(ss->ssl3->hs.sha);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return rv;
- }
-
- PORT_Assert(sec);
-
- /* We ignore ss->sec->ci.sid here, and use ssl_Lookup because Lookup
- * handles expired entries and other details.
- * XXX If we've been called from ssl2_BeginClientHandshake, then
- * this lookup is duplicative and wasteful.
- */
- sid = (ss->noCache) ? NULL
- : ssl_LookupSID(sec->ci.peer, sec->ci.port, ss->peerID, ss->url);
-
- /* We can't resume based on a different token. If the sid exists,
- * make sure the token that holds the master secret still exists ...
- * If we previously did client-auth, make sure that the token that holds
- * the private key still exists, is logged in, hasn't been removed, etc.
- * Also for fortezza, make sure that the card that holds the session keys
- * exist as well... */
- if (sid) {
- PK11SlotInfo *slot;
- PRBool sidOK = PR_TRUE;
- slot = (!sid->u.ssl3.masterValid) ? NULL :
- SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
- sid->u.ssl3.masterSlotID);
- if (slot == NULL) {
- sidOK = PR_FALSE;
- } else {
- PK11SymKey *wrapKey = NULL;
- if (!PK11_IsPresent(slot) ||
- ((wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
- sid->u.ssl3.masterWrapMech,
- sid->u.ssl3.masterWrapSeries,
- ss->pkcs11PinArg)) == NULL) ) {
- sidOK = PR_FALSE;
- }
- if (wrapKey) PK11_FreeSymKey(wrapKey);
- PK11_FreeSlot(slot);
- slot = NULL;
- }
- /* do sid-has-FORTEZZA-slot check */
- if (sid->u.ssl3.hasFortezza) {
- /* do has fortezza check */
- if (!PK11_VerifyKeyOK(sid->u.ssl3.tek))
- sidOK = PR_FALSE;
- }
-
- /* If we previously did client-auth, make sure that the token that
- ** holds the private key still exists, is logged in, hasn't been
- ** removed, etc.
- */
- if (sidOK && sid->u.ssl3.clAuthValid) {
- slot = SECMOD_LookupSlot(sid->u.ssl3.clAuthModuleID,
- sid->u.ssl3.clAuthSlotID);
- if (slot == NULL ||
- !PK11_IsPresent(slot) ||
- sid->u.ssl3.clAuthSeries != PK11_GetSlotSeries(slot) ||
- sid->u.ssl3.clAuthSlotID != PK11_GetSlotID(slot) ||
- sid->u.ssl3.clAuthModuleID != PK11_GetModuleID(slot) ) {
- sidOK = PR_FALSE;
- }
- if (slot) {
- PK11_FreeSlot(slot);
- slot = NULL;
- }
- }
-
- if (!sidOK) {
- ++ssl3_sch_sid_cache_not_ok;
- (*ss->sec->uncache)(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- }
- }
-
- if (sid) {
- ++ssl3_sch_sid_cache_hits;
-
- rv = ssl3_NegotiateVersion(ss, sid->version);
- if (rv != SECSuccess)
- return rv; /* error code was set */
-
- PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
- sid->u.ssl3.sessionIDLength));
- ss->ssl3->policy = sid->u.ssl3.policy;
- } else {
- ++ssl3_sch_sid_cache_misses;
-
- rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_3_1_TLS);
- if (rv != SECSuccess)
- return rv; /* error code was set */
-
- sid = ssl3_NewSessionID(ss, PR_FALSE);
- if (!sid) {
- return SECFailure; /* memory error is set */
- }
- }
-
- if (sec->ci.sid != NULL) {
- ssl_FreeSID(sec->ci.sid); /* decrement ref count, free if zero */
- }
- sec->ci.sid = sid;
-
- sec->send = ssl3_SendApplicationData;
-
- /* shouldn't get here if SSL3 is disabled, but ... */
- PORT_Assert(ss->enableSSL3 || ss->enableTLS);
- if (!ss->enableSSL3 && !ss->enableTLS) {
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- return SECFailure;
- }
-
- /* how many suites does our PKCS11 support (regardless of policy)? */
- num_suites = ssl3_config_match_init(ss);
- if (!num_suites)
- return SECFailure; /* ssl3_config_match_init has set error code. */
-
- /* how many suites are permitted by policy and user preference? */
- num_suites = count_cipher_suites(ss, ss->ssl3->policy, PR_TRUE);
- if (!num_suites)
- return SECFailure; /* count_cipher_suites has set error code. */
-
- length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH +
- 1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength) +
- 2 + num_suites*sizeof(ssl3CipherSuite) +
- 1 + compressionMethodsCount;
-
- rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-
- ss->clientHelloVersion = ss->version;
- rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- rv = ssl3_GetNewRandom(&ss->ssl3->hs.client_random);
- if (rv != SECSuccess) {
- return rv; /* err set by GetNewRandom. */
- }
- rv = ssl3_AppendHandshake(ss, &ss->ssl3->hs.client_random,
- SSL3_RANDOM_LENGTH);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-
- if (sid)
- rv = ssl3_AppendHandshakeVariable(
- ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
- else
- rv = ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-
- rv = ssl3_AppendHandshakeNumber(ss, num_suites*sizeof(ssl3CipherSuite), 2);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-
-
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if (config_match(suite, ss->ssl3->policy, PR_TRUE)) {
- actual_count++;
- if (actual_count > num_suites) {
- /* set error card removal/insertion error */
- PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
- return SECFailure;
- }
- rv = ssl3_AppendHandshakeNumber(ss, suite->cipher_suite,
- sizeof(ssl3CipherSuite));
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- }
- }
-
- /* if cards were removed or inserted between count_cipher_suites and
- * generating our list, detect the error here rather than send it off to
- * the server.. */
- if (actual_count != num_suites) {
- /* Card removal/insertion error */
- PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
- return SECFailure;
- }
-
- rv = ssl3_AppendHandshakeNumber(ss, compressionMethodsCount, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- for (i = 0; i < compressionMethodsCount; i++) {
- rv = ssl3_AppendHandshakeNumber(ss, compressions[i], 1);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- }
-
- rv = ssl3_FlushHandshake(ss, 0);
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
-
- ss->ssl3->hs.ws = wait_server_hello;
- return rv;
-}
-
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Hello Request.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleHelloRequest(sslSocket *ss)
-{
- sslSessionID *sid = ss->sec->ci.sid;
- SECStatus rv;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle hello_request handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert(ss->ssl3);
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ss->ssl3->hs.ws == wait_server_hello)
- return SECSuccess;
- if (ss->ssl3->hs.ws != idle_handshake || ss->sec->isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST);
- return SECFailure;
- }
- if (sid) {
- ss->sec->uncache(sid);
- ssl_FreeSID(sid);
- ss->sec->ci.sid = NULL;
- }
-
- ssl_GetXmitBufLock(ss);
- rv = ssl3_SendClientHello(ss);
- ssl_ReleaseXmitBufLock(ss);
-
- return rv;
-}
-
-#define UNKNOWN_WRAP_MECHANISM 0x7fffffff
-
-static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = {
- CKM_DES3_ECB,
- CKM_CAST5_ECB,
- CKM_DES_ECB,
- CKM_KEY_WRAP_LYNKS,
- CKM_IDEA_ECB,
- CKM_CAST3_ECB,
- CKM_CAST_ECB,
- CKM_RC5_ECB,
- CKM_RC2_ECB,
- CKM_CDMF_ECB,
- CKM_SKIPJACK_WRAP,
- CKM_SKIPJACK_CBC64,
- UNKNOWN_WRAP_MECHANISM
-};
-
-static int
-ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech)
-{
- const CK_MECHANISM_TYPE *pMech = wrapMechanismList;
-
- while (mech != *pMech && *pMech != UNKNOWN_WRAP_MECHANISM) {
- ++pMech;
- }
- return (*pMech == UNKNOWN_WRAP_MECHANISM) ? -1
- : (pMech - wrapMechanismList);
-}
-
-static PK11SymKey *
-ssl_UnwrapSymWrappingKey(
- SSLWrappedSymWrappingKey *pWswk,
- SECKEYPrivateKey * svrPrivKey,
- SSL3KEAType exchKeyType,
- CK_MECHANISM_TYPE masterWrapMech,
- void * pwArg)
-{
- PK11SymKey * unwrappedWrappingKey = NULL;
- SECItem wrappedKey;
-
- /* found the wrapping key on disk. */
- PORT_Assert(pWswk->symWrapMechanism == masterWrapMech);
- PORT_Assert(pWswk->exchKeyType == exchKeyType);
- if (pWswk->symWrapMechanism != masterWrapMech ||
- pWswk->exchKeyType != exchKeyType) {
- goto loser;
- }
- wrappedKey.type = siBuffer;
- wrappedKey.data = pWswk->wrappedSymmetricWrappingkey;
- wrappedKey.len = pWswk->wrappedSymKeyLen;
- PORT_Assert(wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey);
-
- switch (exchKeyType) {
- PK11SymKey * Ks;
- PK11SlotInfo * slot;
- SECItem param;
-
- case kt_fortezza:
- /* get the slot that the fortezza server private key is in. */
- slot = PK11_GetSlotFromPrivateKey(svrPrivKey);
- if (slot == NULL) {
- SET_ERROR_CODE
- goto loser;
- }
-
- /* Look up the Token Fixed Key */
- Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_CBC64, NULL, pwArg);
- PK11_FreeSlot(slot);
- if (Ks == NULL) {
- SET_ERROR_CODE
- goto loser;
- }
-
- /* unwrap client write key with the local Ks and IV */
- param.type = siBuffer;
- param.data = pWswk->wrapIV;
- param.len = pWswk->wrapIVLen;
- unwrappedWrappingKey =
- PK11_UnwrapSymKey(Ks, CKM_SKIPJACK_CBC64, &param, &wrappedKey,
- masterWrapMech, CKA_UNWRAP, 0);
- PK11_FreeSymKey(Ks);
- break;
-
- case kt_rsa:
- unwrappedWrappingKey =
- PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
- masterWrapMech, CKA_UNWRAP, 0);
- break;
- }
-loser:
- return unwrappedWrappingKey;
-}
-
-/* Each process sharing the server session ID cache has its own array of
- * SymKey pointers for the symmetric wrapping keys that are used to wrap
- * the master secrets. There is one key for each KEA type. These Symkeys
- * correspond to the wrapped SymKeys kept in the server session cache.
- */
-
-typedef struct {
- PK11SymKey * symWrapKey[kt_kea_size];
-} ssl3SymWrapKey;
-
-/* Try to get wrapping key for mechanism from in-memory array.
- * If that fails, look for one on disk.
- * If that fails, generate a new one, put the new one on disk,
- * Put the new key in the in-memory array.
- */
-static PK11SymKey *
-getWrappingKey( sslSocket * ss,
- PK11SlotInfo * masterSecretSlot,
- SSL3KEAType exchKeyType,
- CK_MECHANISM_TYPE masterWrapMech,
- void * pwArg)
-{
- CERTCertificate * svrCert;
- SECKEYPrivateKey * svrPrivKey;
- SECKEYPublicKey * svrPubKey = NULL;
- PK11SymKey * unwrappedWrappingKey = NULL;
- PK11SymKey ** pSymWrapKey;
- CK_MECHANISM_TYPE asymWrapMechanism;
- int length;
- int symWrapMechIndex;
- SECStatus rv;
- SECItem wrappedKey;
- SSLWrappedSymWrappingKey wswk;
-
- static PRLock * symWrapKeysLock;
- static ssl3SymWrapKey symWrapKeys[SSL_NUM_WRAP_MECHS];
-
- svrPrivKey = ss->serverKey[exchKeyType];
- PORT_Assert(svrPrivKey != NULL);
- if (!svrPrivKey) {
- return NULL; /* why are we here?!? */
- }
-
- symWrapMechIndex = ssl_FindIndexByWrapMechanism(masterWrapMech);
- PORT_Assert(symWrapMechIndex >= 0);
- if (symWrapMechIndex < 0)
- return NULL; /* invalid masterWrapMech. */
-
- pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[exchKeyType];
-
- /* atomically initialize the lock */
- if (!symWrapKeysLock)
- nss_InitLock(&symWrapKeysLock);
-
- PR_Lock(symWrapKeysLock);
-
- unwrappedWrappingKey = *pSymWrapKey;
- if (unwrappedWrappingKey != NULL) {
- if (PK11_VerifyKeyOK(unwrappedWrappingKey)) {
- unwrappedWrappingKey = PK11_ReferenceSymKey(unwrappedWrappingKey);
- goto done;
- }
- /* slot series has changed, so this key is no good any more. */
- PK11_FreeSymKey(unwrappedWrappingKey);
- *pSymWrapKey = unwrappedWrappingKey = NULL;
- }
-
- /* Try to get wrapped SymWrapping key out of the (disk) cache. */
- /* Following call fills in wswk on success. */
- if (ssl_GetWrappingKey(symWrapMechIndex, exchKeyType, &wswk)) {
- /* found the wrapped sym wrapping key on disk. */
- unwrappedWrappingKey =
- ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, exchKeyType,
- masterWrapMech, pwArg);
- if (unwrappedWrappingKey) {
- goto install;
- }
- }
-
-no_wrapped_key:
-
- if (!masterSecretSlot) /* caller doesn't want to create a new one. */
- goto loser;
-
- length = PK11_GetBestKeyLength(masterSecretSlot, masterWrapMech);
- /* Zero length means fixed key length algorithm, or error.
- * It's ambiguous.
- */
- unwrappedWrappingKey = PK11_KeyGen(masterSecretSlot, masterWrapMech, NULL,
- length, pwArg);
- if (!unwrappedWrappingKey) {
- goto loser;
- }
-
- /* Prepare the buffer to receive the wrappedWrappingKey,
- * the symmetric wrapping key wrapped using the server's pub key.
- */
- PORT_Memset(&wswk, 0, sizeof wswk); /* eliminate UMRs. */
-
- svrCert = ss->serverCert[exchKeyType];
- svrPubKey = CERT_ExtractPublicKey(svrCert);
- if (svrPubKey == NULL) {
- /* CERT_ExtractPublicKey doesn't set error code */
- PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- goto loser;
- }
- wrappedKey.type = siBuffer;
- wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey);
- wrappedKey.data = wswk.wrappedSymmetricWrappingkey;
-
- PORT_Assert(wrappedKey.len <= sizeof wswk.wrappedSymmetricWrappingkey);
- if (wrappedKey.len > sizeof wswk.wrappedSymmetricWrappingkey)
- goto loser;
-
- /* wrap symmetric wrapping key in server's public key. */
- switch (exchKeyType) {
- PK11SymKey * Ks;
- PK11SlotInfo * fSlot;
- SECItem param;
-
- case kt_fortezza:
- /* get the slot that the fortezza server private key is in. */
- fSlot = PK11_GetSlotFromPrivateKey(svrPrivKey);
- if (fSlot == NULL) {
- SET_ERROR_CODE
- goto loser;
- }
-
- /* Look up the Token Fixed Key */
- Ks = PK11_FindFixedKey(fSlot, CKM_SKIPJACK_CBC64, NULL, pwArg);
- PK11_FreeSlot(fSlot);
- if (Ks == NULL) {
- SET_ERROR_CODE
- goto loser;
- }
-
- /* wrap symmetricWrapping key with the local Ks */
- param.type = siBuffer;
- param.data = wswk.wrapIV;
- param.len = sizeof wswk.wrapIV;
- rv = PK11_WrapSymKey(CKM_SKIPJACK_CBC64, &param, Ks,
- unwrappedWrappingKey, &wrappedKey);
- wswk.wrapIVLen = param.len;
- PK11_FreeSymKey(Ks);
- asymWrapMechanism = CKM_SKIPJACK_CBC64;
- break;
-
- case kt_rsa:
- asymWrapMechanism = CKM_RSA_PKCS;
- rv = PK11_PubWrapSymKey(asymWrapMechanism, svrPubKey,
- unwrappedWrappingKey, &wrappedKey);
- break;
-
- default:
- rv = SECFailure;
- break;
- }
-
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- wswk.symWrapMechanism = masterWrapMech;
- wswk.symWrapMechIndex = symWrapMechIndex;
- wswk.asymWrapMechanism = asymWrapMechanism;
- wswk.exchKeyType = exchKeyType;
- wswk.wrappedSymKeyLen = wrappedKey.len;
-
- /* put it on disk. */
- /* If the wrapping key for this KEA type has already been set,
- * then abandon the value we just computed and
- * use the one we got from the disk.
- */
- if (ssl_SetWrappingKey(&wswk)) {
- /* somebody beat us to it. The original contents of our wswk
- * has been replaced with the content on disk. Now, discard
- * the key we just created and unwrap this new one.
- */
- PK11_FreeSymKey(unwrappedWrappingKey);
-
- unwrappedWrappingKey =
- ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, exchKeyType,
- masterWrapMech, pwArg);
- }
-
-install:
- if (unwrappedWrappingKey) {
- *pSymWrapKey = PK11_ReferenceSymKey(unwrappedWrappingKey);
- }
-
-loser:
-done:
- if (svrPubKey) {
- SECKEY_DestroyPublicKey(svrPubKey);
- svrPubKey = NULL;
- }
- PR_Unlock(symWrapKeysLock);
- return unwrappedWrappingKey;
-}
-
-
-static SECStatus
-ssl3_FortezzaAppendHandshake(sslSocket *ss, unsigned char * data, int len)
-{
- SSL3FortezzaKeys *fortezza_CKE = NULL;
- SECStatus rv = SECFailure;
-
- rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
- (sizeof(*fortezza_CKE)-sizeof(fortezza_CKE->y_c)) + 1 + len);
- if (rv == SECSuccess) {
- rv = ssl3_AppendHandshakeVariable(ss, data, len, 1);
- }
- return rv; /* err set by ssl3_AppendHandshake* */
-}
-
-/* Called from ssl3_SendClientKeyExchange(). */
-static SECStatus
-sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
-{
- PK11SymKey * pms = NULL;
- SECStatus rv = SECFailure;
- SECItem enc_pms = {siBuffer, NULL, 0};
- PRBool isTLS;
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ssl_HaveXmitBufLock(ss));
-
- /* Generate the pre-master secret ... */
- ssl_GetSpecWriteLock(ss);
- isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- pms = ssl3_GenerateRSAPMS(ss, ss->ssl3->pwSpec, NULL);
- ssl_ReleaseSpecWriteLock(ss);
- if (pms == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* Get the wrapped (encrypted) pre-master secret, enc_pms */
- enc_pms.len = SECKEY_PublicKeyStrength(svrPubKey);
- enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len);
- if (enc_pms.data == NULL) {
- goto loser; /* err set by PORT_Alloc */
- }
-
- /* wrap pre-master secret in server's public key. */
- rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, pms, &enc_pms);
- if (rv != SECSuccess) {
- PORT_Free(enc_pms.data);
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- 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) {
- goto loser; /* err set by ssl3_AppendHandshake* */
- }
- if (isTLS) {
- rv = ssl3_AppendHandshakeVariable(ss, enc_pms.data, enc_pms.len, 2);
- } else {
- rv = ssl3_AppendHandshake(ss, enc_pms.data, enc_pms.len);
- }
- if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
- }
-
- rv = SECSuccess;
-
-loser:
- if (enc_pms.data != NULL) {
- PORT_Free(enc_pms.data);
- }
- if (pms != NULL) {
- PK11_FreeSymKey(pms);
- }
- return rv;
-}
-
-/* fortezza client-auth portion of ClientKeyExchange message
- * This function appends the KEA public key from the client's V3 cert
- * (empty for a V1 cert) to the outgoing ClientKeyExchange message.
- * For a V3 cert, it also computes the Fortezza public key hash of that key
- * and signs that hash with the client's signing private key.
- * It also finds and returns the client's KEA private key.
- *
- * Called from sendFortezzaClientKeyExchange <- ssl3_SendClientKeyExchange()
- */
-static SECKEYPrivateKey *
-sendFortezzaCKXClientAuth(sslSocket *ss, SSL3FortezzaKeys * fortezza_CKE)
-{
- SECKEYPublicKey * pubKey = NULL;
- SECKEYPrivateKey * privKeaKey = NULL;
- CERTCertificate * peerCert = ss->sec->peerCert;
- void * pwArg = ss->pkcs11PinArg;
- SECStatus rv = SECFailure;
- SECItem sigItem;
- SECItem hashItem;
-
- /* extract our own local public key. */
- pubKey = CERT_ExtractPublicKey(ss->ssl3->clientCertificate);
- if (!pubKey) {
- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- goto loser;
- }
-
- if (pubKey->keyType == fortezzaKey) {
- /* fortezza clientauth with fortezza V1 certificate */
- rv = ssl3_FortezzaAppendHandshake(ss, NULL, 0);
- if (rv != SECSuccess) {
- goto loser; /* err was set by AppendHandshake. */
- }
- privKeaKey = PK11_FindKeyByAnyCert(ss->ssl3->clientCertificate, pwArg);
- if (!privKeaKey) {
- ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
- }
-
- } else {
- /* fortezza clientauth w/ V3 certificate or non fortezza cert*/
- CERTCertificate * ccert = NULL;
- SECKEYPublicKey * foundPubKey = NULL;
- unsigned char hash[SHA1_LENGTH];
-
- ccert = PK11_FindBestKEAMatch(peerCert, pwArg);
- if (ccert == NULL) {
- PORT_SetError(SSL_ERROR_FORTEZZA_PQG);
- goto v3_loser;
- }
-
- foundPubKey = CERT_ExtractPublicKey(ccert);
- if (foundPubKey == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- goto v3_loser;
- }
-
- if (foundPubKey->keyType == keaKey) {
- rv = ssl3_FortezzaAppendHandshake(ss,
- foundPubKey->u.kea.publicValue.data,
- foundPubKey->u.kea.publicValue.len);
- if (rv != SECSuccess) {
- goto v3_loser; /* err was set by AppendHandshake. */
- }
-
- rv = ssl3_ComputeFortezzaPublicKeyHash(
- foundPubKey->u.kea.publicValue, hash);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto v3_loser;
- }
- } else {
- rv = ssl3_FortezzaAppendHandshake(ss,
- foundPubKey->u.fortezza.KEAKey.data,
- foundPubKey->u.fortezza.KEAKey.len);
- if (rv != SECSuccess) {
- goto v3_loser; /* err was set by AppendHandshake. */
- }
-
- rv = ssl3_ComputeFortezzaPublicKeyHash(
- foundPubKey->u.fortezza.KEAKey, hash);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto v3_loser;
- }
- }
-
- hashItem.data = (unsigned char *) hash;
- hashItem.len = SHA1_LENGTH;
-
- sigItem.data = fortezza_CKE->y_signature;
- sigItem.len = sizeof fortezza_CKE->y_signature;
-
- rv = PK11_Sign(ss->ssl3->clientPrivateKey, &sigItem, &hashItem);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto v3_loser;
- }
-
- privKeaKey = PK11_FindKeyByAnyCert(ccert, pwArg);
- if (!privKeaKey) {
- ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
- }
-
-v3_loser:
- if (foundPubKey)
- SECKEY_DestroyPublicKey(foundPubKey);
- if (ccert)
- CERT_DestroyCertificate(ccert);
- } /* fortezza clientauth w/ V3 certificate or non fortezza cert*/
-
-loser:
-
- if (pubKey)
- SECKEY_DestroyPublicKey(pubKey);
- return privKeaKey;
-} /* End of fortezza client-auth. */
-
-
-/* fortezza without client-auth */
-/* fortezza client-auth portion of ClientKeyExchange message
- * This function appends the public KEA key from the client's cert
- * to the outgoing ClientKeyExchange message.
- * It also finds and returns the client's KEA private key.
- *
- * Called from sendFortezzaClientKeyExchange <- ssl3_SendClientKeyExchange()
- */
-static SECKEYPrivateKey *
-sendFortezzaCKXNoClientAuth(sslSocket *ss)
-{
- SECKEYPublicKey * foundPubKey = NULL;
- SECKEYPrivateKey * privKeaKey = NULL;
- CERTCertificate * ccert = NULL;
- CERTCertificate * peerCert = ss->sec->peerCert;
- void * pwArg = ss->pkcs11PinArg;
- SECStatus rv = SECFailure;
-
- ccert = PK11_FindBestKEAMatch(peerCert, pwArg);
- if (ccert == NULL) {
- PORT_SetError(SSL_ERROR_FORTEZZA_PQG);
- goto loser;
- }
-
- foundPubKey = CERT_ExtractPublicKey(ccert);
- if (foundPubKey == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- goto loser;
- }
-
- if (foundPubKey->keyType == fortezzaKey) {
- /* fortezza V1 cert */
- rv = ssl3_FortezzaAppendHandshake(ss,
- foundPubKey->u.fortezza.KEAKey.data,
- foundPubKey->u.fortezza.KEAKey.len);
- if (rv != SECSuccess) {
- goto loser; /* err was set by AppendHandshake. */
- }
- privKeaKey = PK11_FindKeyByAnyCert(ccert, pwArg);
- if (!privKeaKey) {
- ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
- }
- } else {
- /* fortezza V3 cert */
- rv = ssl3_FortezzaAppendHandshake(ss,
- foundPubKey->u.kea.publicValue.data,
- foundPubKey->u.kea.publicValue.len);
- if (rv != SECSuccess) {
- goto loser; /* err was set by AppendHandshake. */
- }
- privKeaKey = PK11_FindKeyByAnyCert(ccert, pwArg);
- if (!privKeaKey) {
- ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
- }
- }
-
-loser:
- if (foundPubKey)
- SECKEY_DestroyPublicKey(foundPubKey);
- if (ccert)
- CERT_DestroyCertificate(ccert);
- return privKeaKey;
-}
-
-/* Called from ssl3_SendClientKeyExchange(). */
-static SECStatus
-sendFortezzaClientKeyExchange(sslSocket * ss, SECKEYPublicKey * serverKey)
-{
- ssl3CipherSpec * pwSpec;
- sslSessionID * sid = ss->sec->ci.sid;
- PK11SlotInfo * slot = NULL;
- PK11SymKey * pms = NULL;
- PK11SymKey * tek = NULL;
- PK11SymKey * client_write_key = NULL;
- PK11SymKey * server_write_key = NULL;
- SECKEYPrivateKey * privKeaKey = NULL;
- void * pwArg = ss->pkcs11PinArg;
- SECStatus rv = SECFailure;
- CK_VERSION version;
- SECItem param;
- SECItem raItem;
- SECItem rbItem;
- SECItem enc_pms;
- SECItem item;
- SSL3FortezzaKeys fortezza_CKE;
- PRBool releaseSpecWriteLock = PR_FALSE;
-
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- /* first get an appropriate slot for doing MACing.
- * Note: This slot will NOT be a Fortezza slot because Fortezza
- * cannot generate an SSL3 pre-master-secret.
- */
- slot = PK11_GetBestSlot(CKM_SSL3_PRE_MASTER_KEY_GEN, pwArg);
- if (slot == NULL) {
- PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND);
- goto loser;
- }
-
- /* create a pre-Master secret */
- version.major = MSB(ss->version);
- version.minor = LSB(ss->version);
-
- param.data = (unsigned char *)&version;
- param.len = sizeof version;
-
- pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN,
- &param, 0, pwArg);
- PK11_FreeSlot(slot);
- slot = NULL;
- if (pms == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* If we don't have a certificate, we need to read out your public key.
- * This changes a bit when we need to deal with the PQG stuff
- */
- PORT_Memset(fortezza_CKE.y_signature, 0, sizeof fortezza_CKE.y_signature);
-
- /* Send the KEA public key and get the KEA private key. */
- if (ss->ssl3->clientCertificate != NULL) {
- /* with client-auth */
- privKeaKey = sendFortezzaCKXClientAuth(ss, &fortezza_CKE);
- } else {
- /* without client-auth */
- privKeaKey = sendFortezzaCKXNoClientAuth(ss);
- }
- if (privKeaKey == NULL) {
- rv = SECFailure;
- goto loser; /* error was already set. */
- }
-
- /* Now we derive the TEK, and generate r_c the client's "random" public key.
- * r_c is generated and filled in by the PubDerive call below.
- */
- raItem.data = fortezza_CKE.r_c;
- raItem.len = sizeof fortezza_CKE.r_c;
-
- /* R_s == server's "random" public key, sent in the Server Key Exchange */
- rbItem.data = ss->ssl3->fortezza.R_s;
- rbItem.len = sizeof ss->ssl3->fortezza.R_s;
-
- tek = PK11_PubDerive(privKeaKey, serverKey, PR_TRUE, /* generate r_c */
- &raItem, &rbItem, CKM_KEA_KEY_DERIVE,
- CKM_SKIPJACK_WRAP, CKA_WRAP, 0, pwArg);
- SECKEY_DestroyPrivateKey(privKeaKey);
- privKeaKey = NULL;
- if (tek == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- ss->ssl3->fortezza.tek = PK11_ReferenceSymKey(tek); /* can't fail. */
-
- /* encrypt the pms with the TEK.
- * NB: PK11_WrapSymKey will generate and output the encrypted PMS
- * AND the IV for decrypting the PMS.
- */
- param.data = fortezza_CKE.master_secret_iv;
- param.len = sizeof fortezza_CKE.master_secret_iv;
-
- enc_pms.data = fortezza_CKE.encrypted_preMasterSecret;
- enc_pms.len = sizeof fortezza_CKE.encrypted_preMasterSecret;
-
- rv = PK11_WrapSymKey(CKM_SKIPJACK_CBC64, &param, tek, pms, &enc_pms);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- rv = SECFailure; /* not there yet. */
-
- slot = PK11_GetSlotFromKey(tek);
-
- ssl_GetSpecWriteLock(ss); releaseSpecWriteLock = PR_TRUE;
-
- pwSpec = ss->ssl3->pwSpec;
- pwSpec->client.write_key = client_write_key =
- PK11_KeyGen(slot, CKM_SKIPJACK_CBC64, NULL, 0, pwArg);
- if (client_write_key == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- /* the -1 is a hack. It's supposed to be key size, but we use it
- * to tell the wrapper that we're doing a weird PKCS #11 key gen.
- * Usually the result of key gen is an encrypt key. This is not
- * the case with SSL, where this key is a decrypt key.
- */
- pwSpec->server.write_key = server_write_key =
- PK11_KeyGen(slot, CKM_SKIPJACK_CBC64, NULL, -1, pwArg);
- if (server_write_key == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* copy the keys and IVs out now */
- item.data = fortezza_CKE.wrapped_client_write_key;
- item.len = sizeof fortezza_CKE.wrapped_client_write_key;
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, client_write_key, &item);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- item.data = fortezza_CKE.wrapped_server_write_key;
- item.len = sizeof fortezza_CKE.wrapped_server_write_key;
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, server_write_key, &item);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* we only get the generated IV's if we're doing skipjack. */
- if (pwSpec->cipher_def->calg == calg_fortezza) {
- PORT_Memcpy(fortezza_CKE.client_write_iv, pwSpec->client.write_iv,
- sizeof fortezza_CKE.client_write_iv);
- PORT_Memcpy(fortezza_CKE.server_write_iv, pwSpec->server.write_iv,
- sizeof fortezza_CKE.server_write_iv);
- } else {
- /* generate IVs to make old servers happy */
- rv = PK11_GenerateFortezzaIV(client_write_key,
- fortezza_CKE.client_write_iv,
- sizeof fortezza_CKE.client_write_iv);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- rv = PK11_GenerateFortezzaIV(server_write_key,
- fortezza_CKE.server_write_iv,
- sizeof fortezza_CKE.server_write_iv);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- }
-
- /* NOTE: This technique of writing out the struct, rather than writing
- * out the individual members works only because all the rest of the
- * values are fixed-length strings of well-defined byte order.
- * Add one SECItem or one Number and we will need to break the elements out.
- */
- rv = ssl3_AppendHandshake(ss, &fortezza_CKE.r_c,
- (sizeof fortezza_CKE - sizeof fortezza_CKE.y_c));
- if (rv != SECSuccess) {
- goto loser; /* err was set by AppendHandshake. */
- }
-
- /* now we initialize our contexts */
- sid->u.ssl3.hasFortezza = PR_TRUE;
- sid->u.ssl3.tek = tek; tek = NULL; /* adopt.. */
-
- if (pwSpec->cipher_def->calg == calg_fortezza) {
- sid->u.ssl3.clientWriteKey =
- PK11_ReferenceSymKey(pwSpec->client.write_key);
- sid->u.ssl3.serverWriteKey=
- PK11_ReferenceSymKey(pwSpec->server.write_key);
-
- PORT_Memcpy(sid->u.ssl3.keys.client_write_iv,
- pwSpec->client.write_iv,
- sizeof sid->u.ssl3.keys.client_write_iv);
- PORT_Memcpy(sid->u.ssl3.keys.server_write_iv,
- pwSpec->server.write_iv,
- sizeof sid->u.ssl3.keys.server_write_iv);
-
- rv = PK11_SaveContext((PK11Context *)pwSpec->encodeContext,
- sid->u.ssl3.clientWriteSave,
- &sid->u.ssl3.clientWriteSaveLen,
- sizeof sid->u.ssl3.clientWriteSave);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- } else {
- PK11_FreeSymKey(client_write_key);
- pwSpec->client.write_key = client_write_key = NULL;
-
- PK11_FreeSymKey(server_write_key);
- pwSpec->server.write_key = server_write_key = NULL;
-
- rv = SECSuccess;
- }
- /* FALL THROUGH */
-
-loser:
- if (tek) PK11_FreeSymKey(tek);
- if (slot) PK11_FreeSlot(slot);
- if (pms) PK11_FreeSymKey(pms);
- if (rv != SECSuccess) {
- if (client_write_key) {
- PK11_FreeSymKey(client_write_key);
- pwSpec->client.write_key = client_write_key = NULL;
- }
- if (server_write_key) {
- PK11_FreeSymKey(server_write_key);
- pwSpec->server.write_key = server_write_key = NULL;
- }
- }
- if (releaseSpecWriteLock)
- ssl_GetSpecWriteLock(ss);
- return rv;
-}
-
-/* Called from ssl3_HandleServerHelloDone(). */
-static SECStatus
-ssl3_SendClientKeyExchange(sslSocket *ss)
-{
- SECKEYPublicKey * serverKey = NULL;
- SECStatus rv = SECFailure;
- PRBool isTLS;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send client_key_exchange handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- if (ss->sec->peerKey == NULL) {
- serverKey = CERT_ExtractPublicKey(ss->sec->peerCert);
- if (serverKey == NULL) {
- PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- return SECFailure;
- }
- } else {
- serverKey = ss->sec->peerKey;
- ss->sec->peerKey = NULL; /* we're done with it now */
- }
-
- isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- /* enforce limits on kea key sizes. */
- if (ss->ssl3->hs.kea_def->is_limited) {
- int keyLen = SECKEY_PublicKeyStrength(serverKey); /* bytes */
-
- if (keyLen * BPB > ss->ssl3->hs.kea_def->key_size_limit) {
- if (isTLS)
- (void)SSL3_SendAlert(ss, alert_fatal, export_restriction);
- else
- (void)ssl3_HandshakeFailure(ss);
- PORT_SetError(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED);
- goto loser;
- }
- }
-
- switch (ss->ssl3->hs.kea_def->exchKeyType) {
- case kt_rsa:
- rv = sendRSAClientKeyExchange(ss, serverKey);
- break;
-
- case kt_fortezza:
- rv = sendFortezzaClientKeyExchange(ss, serverKey);
- break;
-
- default:
- /* got an unknown or unsupported Key Exchange Algorithm. */
- SEND_ALERT
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- break;
- }
-
- SSL_TRC(3, ("%d: SSL3[%d]: DONE sending client_key_exchange",
- SSL_GETPID(), ss->fd));
-
-loser:
- if (serverKey) SECKEY_DestroyPublicKey(serverKey);
- return rv; /* err code already set. */
-}
-
-/* Called from ssl3_HandleServerHelloDone(). */
-static SECStatus
-ssl3_SendCertificateVerify(sslSocket *ss)
-{
- ssl3State * ssl3 = ss->ssl3;
- SECStatus rv = SECFailure;
- PRBool isTLS;
- SECItem buf = {siBuffer, NULL, 0};
- SSL3Hashes hashes;
-
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake",
- SSL_GETPID(), ss->fd));
-
- ssl_GetSpecReadLock(ss);
- rv = ssl3_ComputeHandshakeHashes(ss, ssl3->pwSpec, &hashes, 0);
- ssl_ReleaseSpecReadLock(ss);
- if (rv != SECSuccess) {
- goto done; /* err code was set by ssl3_ComputeHandshakeHashes */
- }
-
- isTLS = (PRBool)(ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_SignHashes(&hashes, ssl3->clientPrivateKey, &buf, isTLS);
- if (rv == SECSuccess) {
- PK11SlotInfo * slot;
- sslSessionID * sid = ss->sec->ci.sid;
-
- /* Remember the info about the slot that did the signing.
- ** Later, when doing an SSL restart handshake, verify this.
- ** These calls are mere accessors, and can't fail.
- */
- slot = PK11_GetSlotFromPrivateKey(ss->ssl3->clientPrivateKey);
- sid->u.ssl3.clAuthSeries = PK11_GetSlotSeries(slot);
- sid->u.ssl3.clAuthSlotID = PK11_GetSlotID(slot);
- sid->u.ssl3.clAuthModuleID = PK11_GetModuleID(slot);
- sid->u.ssl3.clAuthValid = PR_TRUE;
- PK11_FreeSlot(slot);
- }
- /* If we're doing RSA key exchange, we're all done with the private key
- * here. Diffie-Hellman & Fortezza key exchanges need the client's
- * private key for the key exchange.
- */
- if (ssl3->hs.kea_def->exchKeyType == kt_rsa) {
- SECKEY_DestroyPrivateKey(ssl3->clientPrivateKey);
- ssl3->clientPrivateKey = NULL;
- }
- if (rv != SECSuccess) {
- goto done; /* err code was set by ssl3_SignHashes */
- }
-
- rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, buf.len + 2);
- if (rv != SECSuccess) {
- goto done; /* error code set by AppendHandshake */
- }
- rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2);
- if (rv != SECSuccess) {
- goto done; /* error code set by AppendHandshake */
- }
-
-done:
- if (buf.data)
- PORT_Free(buf.data);
- return rv;
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 ServerHello message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- sslSessionID *sid = ss->sec->ci.sid;
- PRInt32 temp; /* allow for consume number failure */
- PRBool suite_found = PR_FALSE;
- int i;
- int errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
- SECStatus rv;
- SECItem sidBytes = {siBuffer, NULL, 0};
- PRBool sid_match;
- PRBool isTLS = PR_FALSE;
- SSL3AlertDescription desc = illegal_parameter;
- SSL3ProtocolVersion version;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError(); /* ssl3_InitState has set the error code. */
- goto alert_loser;
- }
- if (ss->ssl3->hs.ws != wait_server_hello) {
- errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO;
- desc = unexpected_message;
- goto alert_loser;
- }
-
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (temp < 0) {
- goto loser; /* alert has been sent */
- }
- version = (SSL3ProtocolVersion)temp;
-
- /* this is appropriate since the negotiation is complete, and we only
- ** know SSL 3.x.
- */
- if (MSB(version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
- desc = handshake_failure;
- goto alert_loser;
- }
-
- rv = ssl3_NegotiateVersion(ss, version);
- if (rv != SECSuccess) {
- desc = handshake_failure;
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
- }
- isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
-
- rv = ssl3_ConsumeHandshake(
- ss, &ss->ssl3->hs.server_random, SSL3_RANDOM_LENGTH, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* alert has been sent */
- }
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* alert has been sent */
- }
- if (sidBytes.len > SSL3_SESSIONID_BYTES) {
- if (isTLS)
- desc = decode_error;
- goto alert_loser; /* malformed. */
- }
-
- /* find selected cipher suite in our list. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (temp < 0) {
- goto loser; /* alert has been sent */
- }
- ssl3_config_match_init(ss);
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if ((temp == suite->cipher_suite) &&
- (config_match(suite, ss->ssl3->policy, PR_TRUE))) {
- suite_found = PR_TRUE;
- break; /* success */
- }
- }
- if (!suite_found) {
- desc = handshake_failure;
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
- }
- ss->ssl3->hs.cipher_suite = (ssl3CipherSuite)temp;
- ss->ssl3->hs.suite_def = ssl_LookupCipherSuiteDef((ssl3CipherSuite)temp);
- PORT_Assert(ss->ssl3->hs.suite_def);
- if (!ss->ssl3->hs.suite_def) {
- PORT_SetError(errCode = SEC_ERROR_LIBRARY_FAILURE);
- goto loser; /* we don't send alerts for our screw-ups. */
- }
-
- /* find selected compression method in our list. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length);
- if (temp < 0) {
- goto loser; /* alert has been sent */
- }
- suite_found = PR_FALSE;
- for (i = 0; i < compressionMethodsCount; i++) {
- if (temp == compressions[i]) {
- suite_found = PR_TRUE;
- break; /* success */
- }
- }
- if (!suite_found) {
- desc = handshake_failure;
- errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
- goto alert_loser;
- }
- ss->ssl3->hs.compression = (SSL3CompressionMethod)temp;
-
- if (length != 0) { /* malformed */
- goto alert_loser;
- }
-
- /* Any errors after this point are not "malformed" errors. */
- desc = handshake_failure;
-
- /* we need to call ssl3_SetupPendingCipherSpec here so we can check the
- * key exchange algorithm. */
- rv = ssl3_SetupPendingCipherSpec(ss, ss->ssl3);
- if (rv != SECSuccess) {
- goto alert_loser; /* error code is set. */
- }
-
- /* We may or may not have sent a session id, we may get one back or
- * not and if so it may match the one we sent.
- * Attempt to restore the master secret to see if this is so...
- * Don't consider failure to find a matching SID an error.
- */
- sid_match = (PRBool)(sidBytes.len > 0 &&
- sidBytes.len == sid->u.ssl3.sessionIDLength &&
- !PORT_Memcmp(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len));
-
- if (sid_match &&
- sid->version == ss->version &&
- sid->u.ssl3.cipherSuite == ss->ssl3->hs.cipher_suite) do {
- PK11SlotInfo *slot;
- PK11SymKey * wrapKey; /* wrapping key */
- SECItem wrappedMS; /* wrapped master secret. */
- CK_FLAGS keyFlags = 0;
-
- slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
- sid->u.ssl3.masterSlotID);
- if (slot == NULL) {
- break; /* not considered an error. */
- }
- if (!PK11_IsPresent(slot)) {
- PK11_FreeSlot(slot);
- break; /* not considered an error. */
- }
- wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
- sid->u.ssl3.masterWrapMech,
- sid->u.ssl3.masterWrapSeries,
- ss->pkcs11PinArg);
- PK11_FreeSlot(slot);
- if (wrapKey == NULL) {
- break; /* not considered an error. */
- }
-
- if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
- keyFlags = CKF_SIGN | CKF_VERIFY;
- }
-
- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
- ss->ssl3->pwSpec->master_secret =
- PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
- NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
- CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
- errCode = PORT_GetError();
- PK11_FreeSymKey(wrapKey);
- if (ss->ssl3->pwSpec->master_secret == NULL) {
- break; /* errorCode set just after call to UnwrapSymKey. */
- }
-
- /* Got a Match */
- ++ssl3_hsh_sid_cache_hits;
- ss->ssl3->hs.ws = wait_change_cipher;
- ss->ssl3->hs.isResuming = PR_TRUE;
-
- /* copy the peer cert from the SID */
- if (sid->peerCert != NULL) {
- ss->sec->peerCert = CERT_DupCertificate(sid->peerCert);
- }
-
- /* reload the FORTEZZA key material. These keys aren't generated
- * by the master secret, but by the key exchange. We restart by
- * reusing these keys. */
- if (sid->u.ssl3.hasFortezza) {
- ss->ssl3->fortezza.tek = PK11_ReferenceSymKey(sid->u.ssl3.tek);
- }
- if (ss->ssl3->hs.suite_def->bulk_cipher_alg == cipher_fortezza) {
- ss->ssl3->pwSpec->client.write_key =
- PK11_ReferenceSymKey(sid->u.ssl3.clientWriteKey);
- ss->ssl3->pwSpec->server.write_key =
- PK11_ReferenceSymKey(sid->u.ssl3.serverWriteKey);
- /* add the tek later for pre-encrypted files */
- PORT_Memcpy(ss->ssl3->pwSpec->client.write_iv,
- sid->u.ssl3.keys.client_write_iv,
- sizeof sid->u.ssl3.keys.client_write_iv);
- PORT_Memcpy(ss->ssl3->pwSpec->server.write_iv,
- sid->u.ssl3.keys.server_write_iv,
- sizeof sid->u.ssl3.keys.server_write_iv);
- }
-
- /* NULL value for PMS signifies re-use of the old MS */
- rv = ssl3_InitPendingCipherSpec(ss, NULL);
- if (rv != SECSuccess) {
- goto alert_loser; /* err code was set by ssl3_InitPendingCipherSpec */
- }
- if (ss->ssl3->hs.suite_def->bulk_cipher_alg == cipher_fortezza) {
- rv = PK11_RestoreContext(
- (PK11Context *)ss->ssl3->pwSpec->encodeContext,
- sid->u.ssl3.clientWriteSave,
- sid->u.ssl3.clientWriteSaveLen);
- if (rv != SECSuccess) {
- goto alert_loser; /* err is set. */
- }
- }
- SECITEM_ZfreeItem(&sidBytes, PR_FALSE);
- return SECSuccess;
- } while (0);
-
- if (sid_match)
- ++ssl3_hsh_sid_cache_not_ok;
- else
- ++ssl3_hsh_sid_cache_misses;
-
- /* throw the old one away */
- sid->u.ssl3.resumable = PR_FALSE;
- (*ss->sec->uncache)(sid);
- ssl_FreeSID(sid);
-
- /* get a new sid */
- ss->sec->ci.sid = sid = ssl3_NewSessionID(ss, PR_FALSE);
- if (sid == NULL) {
- goto alert_loser; /* memory error is set. */
- }
-
- sid->version = ss->version;
- sid->u.ssl3.sessionIDLength = sidBytes.len;
- PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len);
- SECITEM_ZfreeItem(&sidBytes, PR_FALSE);
-
- ss->ssl3->hs.isResuming = PR_FALSE;
- ss->ssl3->hs.ws = wait_server_cert;
- return SECSuccess;
-
-alert_loser:
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
-
-loser:
- if (sidBytes.data != NULL)
- SECITEM_ZfreeItem(&sidBytes, PR_FALSE);
- errCode = ssl_MapLowLevelError(errCode);
- return SECFailure;
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 ServerKeyExchange message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- PRArenaPool * arena;
- SECKEYPublicKey *peerKey;
- PRBool isTLS;
- SECStatus rv;
- int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
- SSL3AlertDescription desc = illegal_parameter;
- SECItem modulus = {siBuffer, NULL, 0};
- SECItem exponent = {siBuffer, NULL, 0};
- SECItem signature = {siBuffer, NULL, 0};
- SSL3Hashes hashes;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle server_key_exchange handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ss->ssl3->hs.ws != wait_server_key &&
- ss->ssl3->hs.ws != wait_server_cert) {
- errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
- desc = unexpected_message;
- goto alert_loser;
- }
- if (ss->sec->peerCert == NULL) {
- errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
- desc = unexpected_message;
- goto alert_loser;
- }
-
- isTLS = (PRBool)(ss->ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- switch (ss->ssl3->hs.kea_def->exchKeyType) {
- case kt_rsa:
- rv = ssl3_ConsumeHandshakeVariable(ss, &modulus, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- rv = ssl3_ConsumeHandshakeVariable(ss, &exponent, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- if (length != 0) {
- if (isTLS)
- desc = decode_error;
- goto alert_loser; /* malformed. */
- }
-
- /* failures after this point are not malformed handshakes. */
- /* TLS: send decrypt_error if signature failed. */
- desc = isTLS ? decrypt_error : handshake_failure;
-
- /*
- * check to make sure the hash is signed by right guy
- */
- rv = ssl3_ComputeExportRSAKeyHash(modulus, exponent,
- &ss->ssl3->hs.client_random,
- &ss->ssl3->hs.server_random, &hashes);
- if (rv != SECSuccess) {
- errCode =
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto alert_loser;
- }
- rv = ssl3_VerifySignedHashes(&hashes, ss->sec->peerCert, &signature,
- isTLS, ss->pkcs11PinArg);
- if (rv != SECSuccess) {
- errCode =
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto alert_loser;
- }
-
- /*
- * we really need to build a new key here because we can no longer
- * ignore calling SECKEY_DestroyPublicKey. Using the key may allocate
- * pkcs11 slots and ID's.
- */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto no_memory;
- }
-
- ss->sec->peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
- if (peerKey == NULL) {
- goto no_memory;
- }
-
- peerKey->arena = arena;
- peerKey->keyType = rsaKey;
- peerKey->pkcs11Slot = NULL;
- peerKey->pkcs11ID = CK_INVALID_KEY;
- peerKey->u.rsa.modulus.data =
- (unsigned char*)PORT_ArenaAlloc(arena, modulus.len);
- if (peerKey->u.rsa.modulus.data == NULL)
- goto no_memory;
-
- PORT_Memcpy(peerKey->u.rsa.modulus.data, modulus.data, modulus.len);
- peerKey->u.rsa.modulus.len = modulus.len;
-
- peerKey->u.rsa.publicExponent.data =
- (unsigned char*)PORT_ArenaAlloc(arena, exponent.len);
- if (peerKey->u.rsa.publicExponent.data == NULL)
- goto no_memory;
-
- PORT_Memcpy(peerKey->u.rsa.publicExponent.data,
- exponent.data, exponent.len);
- peerKey->u.rsa.publicExponent.len = exponent.len;
-
- PORT_Free(modulus.data);
- PORT_Free(exponent.data);
- PORT_Free(signature.data);
- ss->ssl3->hs.ws = wait_cert_request;
- return SECSuccess;
-
- case kt_fortezza:
-
- /* Fortezza needs *BOTH* a server cert message
- * and a server key exchange message.
- */
- if (ss->ssl3->hs.ws == wait_server_cert) {
- errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
- desc = unexpected_message;
- goto alert_loser;
- }
- /* Get the server's "random" public key. */
- rv = ssl3_ConsumeHandshake(ss, ss->ssl3->fortezza.R_s,
- sizeof ss->ssl3->fortezza.R_s, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
-
- ss->ssl3->hs.ws = wait_cert_request;
- return SECSuccess;
-
- default:
- desc = handshake_failure;
- errCode = SEC_ERROR_UNSUPPORTED_KEYALG;
- break; /* goto alert_loser; */
- }
-
-alert_loser:
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
-loser:
- if (modulus.data != NULL) SECITEM_FreeItem(&modulus, PR_FALSE);
- if (exponent.data != NULL) SECITEM_FreeItem(&exponent, PR_FALSE);
- if (signature.data != NULL) SECITEM_FreeItem(&signature, PR_FALSE);
- PORT_SetError( errCode );
- return SECFailure;
-
-no_memory: /* no-memory error has already been set. */
- if (modulus.data != NULL) SECITEM_FreeItem(&modulus, PR_FALSE);
- if (exponent.data != NULL) SECITEM_FreeItem(&exponent, PR_FALSE);
- if (signature.data != NULL) SECITEM_FreeItem(&signature, PR_FALSE);
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- return SECFailure;
-}
-
-
-typedef struct dnameNode {
- struct dnameNode *next;
- SECItem name;
-} dnameNode;
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Certificate Request message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- ssl3State * ssl3 = ss->ssl3;
- PRArenaPool * arena = NULL;
- dnameNode * node;
- unsigned char * data;
- PRInt32 remaining;
- PRInt32 len;
- PRBool isTLS = PR_FALSE;
- int i;
- int errCode = SSL_ERROR_RX_MALFORMED_CERT_REQUEST;
- int nnames = 0;
- SECStatus rv;
- SSL3AlertDescription desc = illegal_parameter;
- SECItem cert_types = {siBuffer, NULL, 0};
- CERTDistNames ca_list;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ssl3->hs.ws != wait_cert_request &&
- ssl3->hs.ws != wait_server_key) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST;
- goto alert_loser;
- }
- isTLS = (PRBool)(ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length);
- if (rv != SECSuccess)
- goto loser; /* malformed, alert has been sent */
-
- arena = ca_list.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- goto no_mem;
-
- remaining = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (remaining < 0)
- goto loser; /* malformed, alert has been sent */
-
- ca_list.head = node = PORT_ArenaZNew(arena, dnameNode);
- if (node == NULL)
- goto no_mem;
-
- while (remaining != 0) {
- if (remaining < 2)
- goto alert_loser; /* malformed */
-
- node->name.len = len = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (len < 0)
- goto loser; /* malformed, alert has been sent */
-
- remaining -= 2;
- if (remaining < len)
- goto alert_loser; /* malformed */
-
- data = node->name.data = (unsigned char*)PORT_ArenaAlloc(arena, len);
- if (data == NULL)
- goto no_mem;
-
- rv = ssl3_ConsumeHandshake(ss, data, len, &b, &length);
- if (rv != SECSuccess)
- goto loser; /* malformed, alert has been sent */
-
- remaining -= len;
- nnames++;
- if (remaining == 0)
- break; /* success */
-
- node->next = PORT_ArenaZNew(arena, dnameNode);
- node = node->next;
- if (node == NULL)
- goto no_mem;
- }
-
- ca_list.nnames = nnames;
- ca_list.names = (SECItem*)PORT_ArenaAlloc(arena, nnames * sizeof(SECItem));
- if (ca_list.names == NULL)
- goto no_mem;
-
- for(i = 0, node = (dnameNode*)ca_list.head;
- i < nnames;
- i++, node = node->next) {
- ca_list.names[i] = node->name;
- }
-
- if (length != 0)
- goto alert_loser; /* malformed */
-
- desc = no_certificate;
- ssl3->hs.ws = wait_hello_done;
-
- if (ss->getClientAuthData == NULL) {
- rv = SECFailure; /* force it to send a no_certificate alert */
- } else {
- /* XXX Should pass cert_types in this call!! */
- rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg,
- ss->fd, &ca_list,
- &ssl3->clientCertificate,
- &ssl3->clientPrivateKey);
- }
- switch (rv) {
- case SECWouldBlock: /* getClientAuthData has put up a dialog box. */
- ssl_SetAlwaysBlock(ss);
- break; /* not an error */
-
- case SECSuccess:
- /* Setting ssl3->clientCertChain non-NULL will cause
- * ssl3_HandleServerHelloDone to call SendCertificate.
- */
- ssl3->clientCertChain = CERT_CertChainFromCert(ssl3->clientCertificate,
- certUsageSSLClient, PR_FALSE);
- if (ssl3->clientCertChain == NULL) {
- if (ssl3->clientCertificate != NULL) {
- CERT_DestroyCertificate(ssl3->clientCertificate);
- ssl3->clientCertificate = NULL;
- }
- if (ssl3->clientPrivateKey != NULL) {
- SECKEY_DestroyPrivateKey(ssl3->clientPrivateKey);
- ssl3->clientPrivateKey = NULL;
- }
- goto send_no_certificate;
- }
- break; /* not an error */
-
- case SECFailure:
- default:
-send_no_certificate:
- if (isTLS) {
- ssl3->sendEmptyCert = PR_TRUE;
- } else {
- (void)SSL3_SendAlert(ss, alert_warning, no_certificate);
- }
- rv = SECSuccess;
- break;
- }
- goto done;
-
-no_mem:
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto done;
-
-alert_loser:
- if (isTLS && desc == illegal_parameter)
- desc = decode_error;
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
-loser:
- PORT_SetError(errCode);
- rv = SECFailure;
-done:
- if (arena != NULL)
- PORT_FreeArena(arena, PR_FALSE);
- if (cert_types.data != NULL)
- SECITEM_FreeItem(&cert_types, PR_FALSE);
- return rv;
-}
-
-/*
- * attempt to restart the handshake after asynchronously handling
- * a request for the client's certificate.
- *
- * inputs:
- * cert Client cert chosen by application.
- * Note: ssl takes this reference, and does not bump the
- * reference count. The caller should drop its reference
- * without calling CERT_DestroyCert after calling this function.
- *
- * key Private key associated with cert. This function makes a
- * copy of the private key, so the caller remains responsible
- * for destroying its copy after this function returns.
- *
- * certChain Chain of signers for cert.
- * Note: ssl takes this reference, and does not copy the chain.
- * The caller should drop its reference without destroying the
- * chain. SSL will free the chain when it is done with it.
- *
- * Return value: XXX
- *
- * XXX This code only works on the initial handshake on a connection, XXX
- * It does not work on a subsequent handshake (redo).
- *
- * Caller holds 1stHandshakeLock.
- */
-SECStatus
-ssl3_RestartHandshakeAfterCertReq(sslSocket * ss,
- CERTCertificate * cert,
- SECKEYPrivateKey * key,
- CERTCertificateList *certChain)
-{
- SECStatus rv = SECSuccess;
-
- if (MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0)) {
- /* XXX This code only works on the initial handshake on a connection,
- ** XXX It does not work on a subsequent handshake (redo).
- */
- if (ss->handshake != 0) {
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->ssl3->clientCertificate = cert;
- ss->ssl3->clientCertChain = certChain;
- if (key == NULL) {
- (void)SSL3_SendAlert(ss, alert_warning, no_certificate);
- ss->ssl3->clientPrivateKey = NULL;
- } else {
- ss->ssl3->clientPrivateKey = SECKEY_CopyPrivateKey(key);
- }
- ssl_GetRecvBufLock(ss);
- if (ss->ssl3->hs.msgState.buf != NULL) {
- rv = ssl3_HandleRecord(ss, NULL, &ss->gather->buf);
- }
- ssl_ReleaseRecvBufLock(ss);
- }
- }
- return rv;
-}
-
-
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Server Hello Done message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleServerHelloDone(sslSocket *ss)
-{
- SECStatus rv;
- SSL3WaitState ws = ss->ssl3->hs.ws;
- PRBool send_verify = PR_FALSE;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello_done handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ws != wait_hello_done &&
- ws != wait_server_cert &&
- ws != wait_server_key &&
- ws != wait_cert_request) {
- SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
- return SECFailure;
- }
-
- ssl_GetXmitBufLock(ss); /*******************************/
-
- if (ss->ssl3->sendEmptyCert) {
- ss->ssl3->sendEmptyCert = PR_FALSE;
- rv = ssl3_SendEmptyCertificate(ss);
- /* Don't send verify */
- if (rv != SECSuccess) {
- goto loser; /* error code is set. */
- }
- } else
- if (ss->ssl3->clientCertChain != NULL &&
- ss->ssl3->clientPrivateKey != NULL) {
- send_verify = PR_TRUE;
- rv = ssl3_SendCertificate(ss);
- if (rv != SECSuccess) {
- goto loser; /* error code is set. */
- }
- }
-
- rv = ssl3_SendClientKeyExchange(ss);
- if (rv != SECSuccess) {
- goto loser; /* err is set. */
- }
-
- if (send_verify) {
- rv = ssl3_SendCertificateVerify(ss);
- if (rv != SECSuccess) {
- goto loser; /* err is set. */
- }
- }
- rv = ssl3_SendChangeCipherSpecs(ss);
- if (rv != SECSuccess) {
- goto loser; /* err code was set. */
- }
- rv = ssl3_SendFinished(ss, 0);
- if (rv != SECSuccess) {
- goto loser; /* err code was set. */
- }
-
- ssl_ReleaseXmitBufLock(ss); /*******************************/
-
- ss->ssl3->hs.ws = wait_change_cipher;
- return SECSuccess;
-
-loser:
- ssl_ReleaseXmitBufLock(ss);
- return rv;
-}
-
-/*
- * Routines used by servers
- */
-static SECStatus
-ssl3_SendHelloRequest(sslSocket *ss)
-{
- SECStatus rv;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send hello_request handshake", SSL_GETPID(),
- ss->fd));
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
-
- rv = ssl3_AppendHandshakeHeader(ss, hello_request, 0);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake */
- }
- rv = ssl3_FlushHandshake(ss, 0);
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
- ss->ssl3->hs.ws = wait_client_hello;
- return SECSuccess;
-}
-
-/* Sets memory error when returning NULL.
- * Called from:
- * ssl3_SendClientHello()
- * ssl3_HandleServerHello()
- * ssl3_HandleClientHello()
- * ssl3_HandleV2ClientHello()
- */
-static sslSessionID *
-ssl3_NewSessionID(sslSocket *ss, PRBool is_server)
-{
- sslSessionID *sid;
-
- sid = PORT_ZNew(sslSessionID);
- if (sid == NULL)
- return sid;
-
- sid->peerID = (ss->peerID == NULL) ? NULL : PORT_Strdup(ss->peerID);
- sid->urlSvrName = (ss->url == NULL) ? NULL : PORT_Strdup(ss->url);
- sid->addr = ss->sec->ci.peer;
- sid->port = ss->sec->ci.port;
- sid->references = 1;
- sid->cached = never_cached;
- sid->version = ss->version;
-
- sid->u.ssl3.resumable = PR_TRUE;
- sid->u.ssl3.policy = SSL_ALLOWED;
- sid->u.ssl3.hasFortezza = PR_FALSE;
- sid->u.ssl3.clientWriteKey = NULL;
- sid->u.ssl3.serverWriteKey = NULL;
- sid->u.ssl3.tek = NULL;
-
- if (is_server) {
- SECStatus rv;
- int pid = SSL_GETPID();
-
- sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
- sid->u.ssl3.sessionID[0] = (pid >> 8) & 0xff;
- sid->u.ssl3.sessionID[1] = pid & 0xff;
- rv = PK11_GenerateRandom(sid->u.ssl3.sessionID + 2,
- SSL3_SESSIONID_BYTES -2);
- if (rv != SECSuccess) {
- ssl_FreeSID(sid);
- ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
- return NULL;
- }
- }
- return sid;
-}
-
-/* Called from: ssl3_HandleClientHello, ssl3_HandleV2ClientHello */
-static SECStatus
-ssl3_SendServerHelloSequence(sslSocket *ss)
-{
- const ssl3KEADef *kea_def;
- SECStatus rv;
-
- SSL_TRC(3, ("%d: SSL3[%d]: begin send server_hello sequence",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
-
- rv = ssl3_SendServerHello(ss);
- if (rv != SECSuccess) {
- return rv; /* err code is set. */
- }
- rv = ssl3_SendCertificate(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().
- */
- kea_def = ss->ssl3->hs.kea_def;
- ss->ssl3->hs.usedStepDownKey = PR_FALSE;
- if (kea_def->kea == kea_fortezza) {
- rv = ssl3_SendServerKeyExchange(ss);
- if (rv != SECSuccess) {
- return rv; /* err code was set. */
- }
- } else if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) {
- /* see if we can legally use the key in the cert. */
- int keyLen; /* bytes */
-
- keyLen = PK11_GetPrivateModulusLen(
- ss->serverKey[kea_def->exchKeyType]);
-
- if (keyLen > 0 &&
- keyLen * BPB <= kea_def->key_size_limit ) {
- /* XXX AND cert is not signing only!! */
- /* just fall through and use it. */
- } else if (ss->stepDownKeyPair != NULL) {
- ss->ssl3->hs.usedStepDownKey = PR_TRUE;
- rv = ssl3_SendServerKeyExchange(ss);
- if (rv != SECSuccess) {
- return rv; /* err code was set. */
- }
- } else {
-#ifndef HACKED_EXPORT_SERVER
- PORT_SetError(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED);
- return rv;
-#endif
- }
- }
-
- if (ss->requestCertificate) {
- rv = ssl3_SendCertificateRequest(ss);
- if (rv != SECSuccess) {
- return rv; /* err code is set. */
- }
- }
- rv = ssl3_SendServerHelloDone(ss);
- if (rv != SECSuccess) {
- return rv; /* err code is set. */
- }
-
- ss->ssl3->hs.ws = (ss->requestCertificate) ? wait_client_cert
- : wait_client_key;
- return SECSuccess;
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Client Hello message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- sslSessionID * sid = NULL;
- ssl3State * ssl3;
- sslConnectInfo * ci;
- PRInt32 tmp;
- unsigned int i;
- int j;
- SECStatus rv;
- int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
- SSL3AlertDescription desc = illegal_parameter;
- SSL3ProtocolVersion version;
- SECItem sidBytes = {siBuffer, NULL, 0};
- SECItem suites = {siBuffer, NULL, 0};
- SECItem comps = {siBuffer, NULL, 0};
- PRBool haveSpecWriteLock = PR_FALSE;
- PRBool haveXmitBufLock = PR_FALSE;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle client_hello handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- /* Get peer name of client */
- rv = ssl_GetPeerInfo(ss);
- if (rv != SECSuccess) {
- return rv; /* error code is set. */
- }
-
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- return rv; /* ssl3_InitState has set the error code. */
- }
- ssl3 = ss->ssl3;
-
- if ((ssl3->hs.ws != wait_client_hello) &&
- (ssl3->hs.ws != idle_handshake)) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
- goto alert_loser;
- }
- ci = &ss->sec->ci;
-
- tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (tmp < 0)
- goto loser; /* malformed, alert already sent */
- ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp;
- rv = ssl3_NegotiateVersion(ss, version);
- if (rv != SECSuccess) {
- /* We can't do the usual isTLS test here, because the negotiated
- ** version is definitely not 3.1. So the question is, are we
- ** willing/able to do TLS here on our side?
- */
- desc = ss->enableTLS ? protocol_version : handshake_failure;
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
- }
-
- /* grab the client random data. */
- rv = ssl3_ConsumeHandshake(
- ss, &ssl3->hs.client_random, SSL3_RANDOM_LENGTH, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
-
- /* grab the client's SID, if present. */
- rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
-
- if (sidBytes.len > 0) {
- SSL_TRC(7, ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x",
- SSL_GETPID(), ss->fd, ci->peer));
- sid = (*ssl_sid_lookup)(ci->peer, sidBytes.data, sidBytes.len,
- ss->dbHandle);
- }
- SECITEM_FreeItem(&sidBytes, PR_FALSE);
-
- /* grab the list of cipher suites. */
- rv = ssl3_ConsumeHandshakeVariable(ss, &suites, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
-
- /* grab the list of compression methods. */
- rv = ssl3_ConsumeHandshakeVariable(ss, &comps, 1, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
-
- /* It's OK for length to be non-zero here.
- * Non-zero length means that some new protocol revision has extended
- * the client hello message.
- */
-
- desc = handshake_failure;
-
- if (sid != NULL) {
- /* We've found a session cache entry for this client.
- * Now, if we're going to require a client-auth cert,
- * and we don't already have this client's cert in the session cache,
- * and this is the first handshake on this connection (not a redo),
- * then drop this old cache entry and start a new session.
- */
- if ((sid->peerCert == NULL) && ss->requestCertificate &&
- ((ss->requireCertificate == 1) ||
- ((ss->requireCertificate == 2) && !ss->connected))) {
-
- ++ssl3_hch_sid_cache_not_ok;
- ss->sec->uncache(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- }
- }
-
- /* Look for a matching cipher suite. */
- j = ssl3_config_match_init(ss);
- if (j <= 0) { /* no ciphers are working/supported by PK11 */
- errCode = PORT_GetError(); /* error code is already set. */
- goto alert_loser;
- }
- /* If we already have a session for this client, be sure to pick the
- ** same cipher suite we picked before.
- ** This is not a loop, despite appearances.
- */
- if (sid) do {
- ssl3CipherSuiteCfg *suite = ss->cipherSuites;
- for (j = ssl_V3_SUITES_IMPLEMENTED; j > 0; --j, ++suite) {
- if (suite->cipher_suite == sid->u.ssl3.cipherSuite)
- break;
- }
- if (!j)
- break;
- if (!config_match(suite, ssl3->policy, PR_TRUE))
- break;
- for (i = 0; i < suites.len; i += 2) {
- if ((suites.data[i] == MSB(suite->cipher_suite)) &&
- (suites.data[i + 1] == LSB(suite->cipher_suite))) {
-
- ssl3->hs.cipher_suite = suite->cipher_suite;
- ssl3->hs.suite_def =
- ssl_LookupCipherSuiteDef(ssl3->hs.cipher_suite);
- goto suite_found;
- }
- }
- } while (0);
-
- /* Select a cipher suite.
- ** NOTE: This suite selection algorithm should be the same as the one in
- ** ssl3_HandleV2ClientHello().
- */
- for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
- if (!config_match(suite, ssl3->policy, PR_TRUE))
- continue;
- for (i = 0; i < suites.len; i += 2) {
- if ((suites.data[i] == MSB(suite->cipher_suite)) &&
- (suites.data[i + 1] == LSB(suite->cipher_suite))) {
-
- ssl3->hs.cipher_suite = suite->cipher_suite;
- ssl3->hs.suite_def =
- ssl_LookupCipherSuiteDef(ssl3->hs.cipher_suite);
- goto suite_found;
- }
- }
- }
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
-
-suite_found:
- /* Look for a matching compression algorithm. */
- for (i = 0; i < comps.len; i++) {
- for (j = 0; j < compressionMethodsCount; j++) {
- if (comps.data[i] == compressions[j]) {
- ssl3->hs.compression = (SSL3CompressionMethod)compressions[j];
- goto compression_found;
- }
- }
- }
- errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
- /* null compression must be supported */
- goto alert_loser;
-
-compression_found:
- PORT_Free(suites.data);
- suites.data = NULL;
- PORT_Free(comps.data);
- comps.data = NULL;
-
- ss->sec->send = ssl3_SendApplicationData;
-
- /* 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.
- */
- if (sid != NULL) do {
- PK11SlotInfo * slot;
- PK11SymKey * wrapKey; /* wrapping key */
- SECItem wrappedKey; /* wrapped key */
- ssl3CipherSpec *pwSpec;
- CK_FLAGS keyFlags = 0;
-
- if (sid->version != ss->version ||
- sid->u.ssl3.cipherSuite != ssl3->hs.cipher_suite) {
- break; /* not an error */
- }
-
- if (ci->sid) {
- ss->sec->uncache(ci->sid);
- PORT_Assert(ci->sid != sid); /* should be impossible, but ... */
- if (ci->sid != sid) {
- ssl_FreeSID(ci->sid);
- }
- ci->sid = NULL;
- }
- /* we need to resurrect the master secret.... */
-
- ssl_GetSpecWriteLock(ss); haveSpecWriteLock = PR_TRUE;
- pwSpec = ssl3->pwSpec;
-
- wrapKey = getWrappingKey(ss, NULL, sid->u.ssl3.exchKeyType,
- sid->u.ssl3.masterWrapMech, ss->pkcs11PinArg);
- if (!wrapKey) {
- /* we have a SID cache entry, but no wrapping key for it??? */
- break;
- }
-
- if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
- keyFlags = CKF_SIGN | CKF_VERIFY;
- }
-
- wrappedKey.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedKey.len = sid->u.ssl3.keys.wrapped_master_secret_len;
-
- /* unwrap the master secret. */
- pwSpec->master_secret =
- PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
- NULL, &wrappedKey, CKM_SSL3_MASTER_KEY_DERIVE,
- CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
- PK11_FreeSymKey(wrapKey);
- if (pwSpec->master_secret == NULL) {
- break; /* not an error */
- }
- ci->sid = sid;
- if (sid->peerCert != NULL) {
- ss->sec->peerCert = CERT_DupCertificate(sid->peerCert);
- }
-
- /*
- * Old SID passed all tests, so resume this old session.
- *
- * XXX make sure compression still matches
- */
- ++ssl3_hch_sid_cache_hits;
- ssl3->hs.isResuming = PR_TRUE;
-
- ssl_GetXmitBufLock(ss); haveXmitBufLock = PR_TRUE;
-
- rv = ssl3_SendServerHello(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- /* reload the FORTEZZA key material.
- * On Fortezza, the following keys & IVs are generated by the KEA,
- * not from the PMS. Since we're not going to redo the KEA, we
- * have to save & restore them for Fortezza.
- * use kea because we haven't call InitCipher Specs yet...?
- */
- if (ssl3->hs.suite_def->bulk_cipher_alg == cipher_fortezza) {
- PK11SymKey * Ks;
- SECItem item;
-
- PORT_Memcpy(pwSpec->client.write_iv,
- sid->u.ssl3.keys.client_write_iv,
- sizeof sid->u.ssl3.keys.client_write_iv);
- PORT_Memcpy(pwSpec->server.write_iv,
- sid->u.ssl3.keys.server_write_iv,
- sizeof sid->u.ssl3.keys.server_write_iv);
-
- /* Now, unwrap the client and server write keys with Ks */
-
- /* get the slot that the fortezza server private key is in. */
- slot = PK11_GetSlotFromPrivateKey(ss->serverKey[kt_fortezza]);
- if (slot == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* Look up the Token Fixed Key */
- Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL,
- ss->pkcs11PinArg);
- PK11_FreeSlot(slot);
- if (Ks == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* unwrap client write key with the local Ks */
- item.data = sid->u.ssl3.keys.wrapped_client_write_key;
- item.len = sizeof sid->u.ssl3.keys.wrapped_client_write_key;
-
- pwSpec->client.write_key =
- PK11_UnwrapSymKey(Ks, CKM_SKIPJACK_WRAP, NULL, &item,
- CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
- if (pwSpec->client.write_key == NULL) {
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
- goto loser;
- }
-
- /* unwrap server write key with the local Ks */
- item.data = sid->u.ssl3.keys.wrapped_server_write_key;
- item.len = sizeof sid->u.ssl3.keys.wrapped_server_write_key;
-
- pwSpec->server.write_key =
- PK11_UnwrapSymKey(Ks, CKM_SKIPJACK_WRAP, NULL, &item,
- CKM_SKIPJACK_CBC64, CKA_ENCRYPT, 0);
- if (pwSpec->server.write_key == NULL) {
- PK11_FreeSymKey(pwSpec->client.write_key);
- pwSpec->client.write_key = NULL;
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
- goto loser;
- }
- /* Set flag that says "generate 8 byte random prefix plaintext." */
- PK11_SetFortezzaHack(pwSpec->server.write_key); /* can't fail */
-
- }
-
- if (haveSpecWriteLock) {
- ssl_ReleaseSpecWriteLock(ss);
- haveSpecWriteLock = PR_FALSE;
- }
-
- /* NULL value for PMS signifies re-use of the old MS */
- rv = ssl3_InitPendingCipherSpec(ss, NULL);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- rv = ssl3_SendChangeCipherSpecs(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
- rv = ssl3_SendFinished(ss, 0);
- ssl3->hs.ws = wait_change_cipher;
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- if (haveXmitBufLock) {
- ssl_ReleaseXmitBufLock(ss);
- haveXmitBufLock = PR_FALSE;
- }
-
- return SECSuccess;
- } while (0);
-
- if (haveSpecWriteLock) {
- ssl_ReleaseSpecWriteLock(ss);
- haveSpecWriteLock = PR_FALSE;
- }
-
- if (sid) { /* we had a sid, but it's no longer valid, free it */
- ++ssl3_hch_sid_cache_not_ok;
- ss->sec->uncache(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- }
- ++ssl3_hch_sid_cache_misses;
-
- sid = ssl3_NewSessionID(ss, PR_TRUE);
- if (sid == NULL) {
- errCode = PORT_GetError();
- goto loser; /* memory error is set. */
- }
- ci->sid = sid;
-
- ssl3->hs.isResuming = PR_FALSE;
- ssl_GetXmitBufLock(ss);
- rv = ssl3_SendServerHelloSequence(ss);
- ssl_ReleaseXmitBufLock(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- if (haveXmitBufLock) {
- ssl_ReleaseXmitBufLock(ss);
- haveXmitBufLock = PR_FALSE;
- }
-
- return SECSuccess;
-
-alert_loser:
- if (haveSpecWriteLock) {
- ssl_ReleaseSpecWriteLock(ss);
- haveSpecWriteLock = PR_FALSE;
- }
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
- /* FALLTHRU */
-loser:
- if (haveSpecWriteLock) {
- ssl_ReleaseSpecWriteLock(ss);
- haveSpecWriteLock = PR_FALSE;
- }
-
- if (sidBytes.data != NULL) SECITEM_FreeItem(&sidBytes, PR_FALSE);
- if (suites.data != NULL) SECITEM_FreeItem(&suites, PR_FALSE);
- if (comps.data != NULL) SECITEM_FreeItem(&comps, PR_FALSE);
-
- if (haveXmitBufLock) {
- ssl_ReleaseXmitBufLock(ss);
- haveXmitBufLock = PR_FALSE;
- }
-
- PORT_SetError(errCode);
- return SECFailure;
-}
-
-/*
- * ssl3_HandleV2ClientHello is used when a V2 formatted hello comes
- * in asking to use the V3 handshake.
- * Called from ssl2_HandleClientHelloMessage() in sslcon.c
- */
-SECStatus
-ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
-{
- sslSessionID * sid = NULL;
- unsigned char * suites;
- unsigned char * random;
- SSL3ProtocolVersion version;
- SECStatus rv;
- int i;
- int j;
- int sid_length;
- int suite_length;
- int rand_length;
- int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
- SSL3AlertDescription desc = handshake_failure;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle v2 client_hello", SSL_GETPID(), ss->fd));
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
-
- ssl_GetSSL3HandshakeLock(ss);
-
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- ssl_ReleaseSSL3HandshakeLock(ss);
- return rv; /* ssl3_InitState has set the error code. */
- }
-
- if (ss->ssl3->hs.ws != wait_client_hello) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
- goto loser; /* alert_loser */
- }
-
- version = (buffer[1] << 8) | buffer[2];
- suite_length = (buffer[3] << 8) | buffer[4];
- sid_length = (buffer[5] << 8) | buffer[6];
- rand_length = (buffer[7] << 8) | buffer[8];
- ss->clientHelloVersion = version;
-
- rv = ssl3_NegotiateVersion(ss, version);
- if (rv != SECSuccess) {
- desc = ss->enableTLS ? protocol_version : handshake_failure;
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- /* It's not appropriate to send back SSL3/TLS alert records in
- ** response to an SSL2 client hello, unless the version is
- ** succesfully negotiated to 3.0 or greater, so just goto loser. */
- goto loser; /* alert_loser */
- }
-
- /* if we get a non-zero SID, just ignore it. */
- if (length !=
- SSL_HL_CLIENT_HELLO_HBYTES + suite_length + sid_length + rand_length) {
- SSL_DBG(("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d",
- SSL_GETPID(), ss->fd, length,
- SSL_HL_CLIENT_HELLO_HBYTES + suite_length + sid_length +
- rand_length));
- goto loser; /* malformed */ /* alert_loser */
- }
-
- suites = buffer + SSL_HL_CLIENT_HELLO_HBYTES;
- random = suites + suite_length + sid_length;
-
- if (rand_length < SSL_MIN_CHALLENGE_BYTES ||
- rand_length > SSL_MAX_CHALLENGE_BYTES) {
- goto loser; /* malformed */ /* alert_loser */
- }
-
- PORT_Assert(SSL_MAX_CHALLENGE_BYTES == SSL3_RANDOM_LENGTH);
-
- PORT_Memset(&ss->ssl3->hs.client_random, 0, SSL3_RANDOM_LENGTH);
- PORT_Memcpy(
- &ss->ssl3->hs.client_random.rand[SSL3_RANDOM_LENGTH - rand_length],
- random, rand_length);
-
- PRINT_BUF(60, (ss, "client random:", &ss->ssl3->hs.client_random.rand[0],
- SSL3_RANDOM_LENGTH));
-
- i = ssl3_config_match_init(ss);
- if (i <= 0) {
- errCode = PORT_GetError(); /* error code is already set. */
- goto alert_loser;
- }
-
- /* Select a cipher suite.
- ** NOTE: This suite selection algorithm should be the same as the one in
- ** ssl3_HandleClientHello().
- */
- for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
- if (!config_match(suite, ss->ssl3->policy, PR_TRUE))
- continue;
- for (i = 0; i < suite_length; i += 3) {
- if ((suites[i] == 0) &&
- (suites[i+1] == MSB(suite->cipher_suite)) &&
- (suites[i+2] == LSB(suite->cipher_suite))) {
-
- ss->ssl3->hs.cipher_suite = suite->cipher_suite;
- ss->ssl3->hs.suite_def =
- ssl_LookupCipherSuiteDef(ss->ssl3->hs.cipher_suite);
- goto suite_found;
- }
- }
- }
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
-
-suite_found:
-
- ss->ssl3->hs.compression = compression_null;
- ss->sec->send = ssl3_SendApplicationData;
-
- /* we don't even search for a cache hit here. It's just a miss. */
- ++ssl3_hch_sid_cache_misses;
- sid = ssl3_NewSessionID(ss, PR_TRUE);
- if (sid == NULL) {
- errCode = PORT_GetError();
- goto loser; /* memory error is set. */
- }
- ss->sec->ci.sid = sid;
- /* do not worry about memory leak of sid since it now belongs to ci */
-
- /* We have to update the handshake hashes before we can send stuff */
- rv = ssl3_UpdateHandshakeHashes(ss, buffer, length);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- ssl_GetXmitBufLock(ss);
- rv = ssl3_SendServerHelloSequence(ss);
- ssl_ReleaseXmitBufLock(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- /* XXX_1 The call stack to here is:
- * ssl_Do1stHandshake -> ssl2_HandleClientHelloMessage -> here.
- * ssl2_HandleClientHelloMessage returns whatever we return here.
- * ssl_Do1stHandshake will continue looping if it gets back either
- * SECSuccess or SECWouldBlock.
- * SECSuccess is preferable here. See XXX_1 in sslgathr.c.
- */
- ssl_ReleaseSSL3HandshakeLock(ss);
- return SECSuccess;
-
-alert_loser:
- SSL3_SendAlert(ss, alert_fatal, desc);
-loser:
- ssl_ReleaseSSL3HandshakeLock(ss);
- PORT_SetError(errCode);
- return SECFailure;
-}
-
-/* The negotiated version number has been already placed in ss->version.
-**
-** Called from: ssl3_HandleClientHello (resuming session),
-** ssl3_SendServerHelloSequence <- ssl3_HandleClientHello (new session),
-** ssl3_SendServerHelloSequence <- ssl3_HandleV2ClientHello (new session)
-*/
-static SECStatus
-ssl3_SendServerHello(sslSocket *ss)
-{
- sslSessionID *sid;
- SECStatus rv;
- PRUint32 length;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(),
- ss->fd));
-
- PORT_Assert(ss->sec);
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0));
-
- if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
- }
-
- sid = ss->sec->ci.sid;
- length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH + 1 +
- ((sid == NULL) ? 0: SSL3_SESSIONID_BYTES) +
- sizeof(ssl3CipherSuite) + 1;
- rv = ssl3_AppendHandshakeHeader(ss, server_hello, length);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeNumber(ss, ss->version, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_GetNewRandom(&ss->ssl3->hs.server_random);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
- return rv;
- }
- rv = ssl3_AppendHandshake(
- ss, &ss->ssl3->hs.server_random, SSL3_RANDOM_LENGTH);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
-
- if (sid)
- rv = ssl3_AppendHandshakeVariable(
- ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
- else
- rv = ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3->hs.cipher_suite, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3->hs.compression, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_SetupPendingCipherSpec(ss, ss->ssl3);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_SetupPendingCipherSpec */
- }
-
- return SECSuccess;
-}
-
-
-static SECStatus
-ssl3_SendServerKeyExchange(sslSocket *ss)
-{
-const ssl3KEADef * kea_def = ss->ssl3->hs.kea_def;
- SECStatus rv = SECFailure;
- int length;
- PRBool isTLS;
- SECItem signed_hash = {siBuffer, NULL, 0};
- SSL3Hashes hashes;
- SECKEYPublicKey * sdPub; /* public key for step-down */
-
- SSL_TRC(3, ("%d: SSL3[%d]: send server_key_exchange handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- switch (kea_def->exchKeyType) {
- case kt_rsa:
- /* Perform SSL Step-Down here. */
- sdPub = ss->stepDownKeyPair->pubKey;
- PORT_Assert(sdPub != NULL);
- if (!sdPub) {
- PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
- rv = ssl3_ComputeExportRSAKeyHash(sdPub->u.rsa.modulus,
- sdPub->u.rsa.publicExponent,
- &ss->ssl3->hs.client_random,
- &ss->ssl3->hs.server_random,
- &hashes);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- return rv;
- }
-
- isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_SignHashes(&hashes, ss->serverKey[kt_rsa], &signed_hash,
- isTLS);
- if (rv != SECSuccess) {
- goto loser; /* ssl3_SignHashes has set err. */
- }
- if (signed_hash.data == NULL) {
- /* how can this happen and rv == SECSuccess ?? */
- PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- length = 2 + sdPub->u.rsa.modulus.len +
- 2 + sdPub->u.rsa.publicExponent.len +
- 2 + signed_hash.len;
-
- rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeVariable(ss, sdPub->u.rsa.modulus.data,
- sdPub->u.rsa.modulus.len, 2);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeVariable(
- ss, sdPub->u.rsa.publicExponent.data,
- sdPub->u.rsa.publicExponent.len, 2);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
- signed_hash.len, 2);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
- PORT_Free(signed_hash.data);
- return SECSuccess;
-
- case kt_fortezza:
-
- /* Set server's "random" public key R_s to the email value == 1 */
- PORT_Memset(ss->ssl3->fortezza.R_s, 0, sizeof(ss->ssl3->fortezza.R_s));
- ss->ssl3->fortezza.R_s[127] = 1;
-
- /* don't waste time signing the random number */
- length = sizeof (ss->ssl3->fortezza.R_s) /*+ 2 + signed_hash.len*/;
-
- rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshake( ss, &ss->ssl3->fortezza.R_s,
- sizeof(ss->ssl3->fortezza.R_s));
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
- return SECSuccess;
-
- case kt_dh:
- case kt_null:
- default:
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- break;
- }
-loser:
- if (signed_hash.data != NULL)
- PORT_Free(signed_hash.data);
- return SECFailure;
-}
-
-
-static SECStatus
-ssl3_SendCertificateRequest(sslSocket *ss)
-{
- SECItem * name;
- CERTDistNames *ca_list;
-const uint8 * certTypes;
- SECItem * names = NULL;
- SECStatus rv;
- int length;
- int i;
- int calen = 0;
- int nnames = 0;
- int certTypesLength;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- /* ssl3->ca_list is initialized to NULL, and never changed. */
- ca_list = ss->ssl3->ca_list;
- if (!ca_list) {
- ca_list = ssl3_server_ca_list;
- }
-
- if (ca_list != NULL) {
- names = ca_list->names;
- nnames = ca_list->nnames;
- }
-
- if (!nnames) {
- PORT_SetError(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA);
- return SECFailure;
- }
-
- for (i = 0, name = names; i < nnames; i++, name++) {
- calen += 2 + name->len;
- }
-
- if (ss->ssl3->hs.kea_def->exchKeyType == kt_fortezza) {
- certTypes = fortezza_certificate_types;
- certTypesLength = sizeof fortezza_certificate_types;
- } else {
- certTypes = certificate_types;
- certTypesLength = sizeof certificate_types;
- }
-
- length = 1 + certTypesLength + 2 + calen;
-
- rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_AppendHandshakeVariable(ss, certTypes, certTypesLength, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_AppendHandshakeNumber(ss, calen, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- for (i = 0, name = names; i < nnames; i++, name++) {
- rv = ssl3_AppendHandshakeVariable(ss, name->data, name->len, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- }
-
- return SECSuccess;
-}
-
-static SECStatus
-ssl3_SendServerHelloDone(sslSocket *ss)
-{
- SECStatus rv;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send server_hello_done handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- rv = ssl3_AppendHandshakeHeader(ss, server_hello_done, 0);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_FlushHandshake(ss, 0);
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
- return SECSuccess;
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Certificate Verify message
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
- SSL3Hashes *hashes)
-{
- SECItem signed_hash = {siBuffer, NULL, 0};
- SECStatus rv;
- int errCode = SSL_ERROR_RX_MALFORMED_CERT_VERIFY;
- SSL3AlertDescription desc = handshake_failure;
- PRBool isTLS;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_verify handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ss->ssl3->hs.ws != wait_cert_verify || ss->sec->peerCert == NULL) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY;
- goto alert_loser;
- }
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &signed_hash, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
-
- isTLS = (PRBool)(ss->ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- /* XXX verify that the key & kea match */
- rv = ssl3_VerifySignedHashes(hashes, ss->sec->peerCert, &signed_hash,
- isTLS, ss->pkcs11PinArg);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- desc = isTLS ? decrypt_error : handshake_failure;
- goto alert_loser;
- }
-
- PORT_Free(signed_hash.data);
- signed_hash.data = NULL;
-
- if (length != 0) {
- desc = isTLS ? decode_error : illegal_parameter;
- goto alert_loser; /* malformed */
- }
- ss->ssl3->hs.ws = wait_change_cipher;
- return SECSuccess;
-
-alert_loser:
- SSL3_SendAlert(ss, alert_fatal, desc);
-loser:
- if (signed_hash.data != NULL) SECITEM_FreeItem(&signed_hash, PR_FALSE);
- PORT_SetError(errCode);
- return SECFailure;
-}
-
-/*
-** Called from ssl3_HandleClientKeyExchange()
-*/
-static SECStatus
-ssl3_HandleFortezzaClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
- PRUint32 length,
- SECKEYPrivateKey *serverKey)
-{
- SECKEYPublicKey * pubKey = NULL;
- PK11SymKey * tek = NULL;
- PK11SymKey * pms;
- PK11SymKey * Ks = NULL;
- sslSessionID * sid = ss->sec->ci.sid;
- ssl3CipherSpec * pwSpec = ss->ssl3->pwSpec;
- void * pwArg = ss->pkcs11PinArg;
- SECStatus rv;
- SECItem raItem;
- SECItem rbItem;
- SECItem param;
- SECItem item;
- SECItem enc_pms;
- SSL3FortezzaKeys fortezza_CKE;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- fortezza_CKE.y_c.data = NULL;
- rv = ssl3_ConsumeHandshakeVariable(ss, &fortezza_CKE.y_c, 1, &b, &length);
- if (rv != SECSuccess) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH);
- goto fortezza_loser;
- }
- rv = ssl3_ConsumeHandshake(ss, &fortezza_CKE.r_c,
- sizeof fortezza_CKE - sizeof fortezza_CKE.y_c,
- &b, &length);
- if (rv != SECSuccess) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH);
- goto fortezza_loser;
- }
-
- /* Build a Token Encryption key (tek). TEK's can never be unloaded
- * from the card, but given these parameters, and *OUR* fortezza
- * card, we can always regenerate the same one on the fly.
- */
- if (ss->sec->peerCert != NULL) {
- /* client-auth case */
-
- pubKey = CERT_ExtractPublicKey(ss->sec->peerCert);
- if (pubKey == NULL) {
- SEND_ALERT
- PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- rv = SECFailure;
- goto fortezza_loser;
- }
-
- if (pubKey->keyType != fortezzaKey) {
- /* handle V3 client-auth case */
- SECItem sigItem;
- SECItem hashItem;
- unsigned char hash[SHA1_LENGTH];
-
- rv = ssl3_ComputeFortezzaPublicKeyHash(fortezza_CKE.y_c, hash);
- if (rv != SECSuccess) {
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
- sigItem.data = fortezza_CKE.y_signature;
- sigItem.len = sizeof fortezza_CKE.y_signature;
-
- hashItem.data = hash;
- hashItem.len = sizeof hash;
-
- rv = PK11_Verify(pubKey, &sigItem, &hashItem, pwArg);
- if (rv != SECSuccess) {
- SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
- SECKEY_DestroyPublicKey(pubKey); pubKey = NULL;
- }
- }
- rv = SECFailure;
-
- /* Make the public key if necessary */
- if (fortezza_CKE.y_c.len != 0) {
- if (pubKey != NULL) {
- /* The client is not allowed to send the public key
- * if it can be extracted from the certificate. */
- SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
- pubKey = PK11_MakeKEAPubKey(fortezza_CKE.y_c.data,
- fortezza_CKE.y_c.len);
- }
- if (pubKey == NULL) {
- /* no public Key in either the cert or the protocol message*/
- SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- /* Now we derive the TEK. r_c is the client's "random" public key. */
- raItem.data = fortezza_CKE.r_c;
- raItem.len = sizeof(fortezza_CKE.r_c);
-
- /* R_s == server's "random" public key, sent in the Server Key Exchange */
- rbItem.data = ss->ssl3->fortezza.R_s;
- rbItem.len = sizeof ss->ssl3->fortezza.R_s;
-
- tek = PK11_PubDerive(serverKey, pubKey, PR_FALSE, /* don't gen r_c */
- &raItem, &rbItem, CKM_KEA_KEY_DERIVE,
- CKM_SKIPJACK_WRAP, CKA_WRAP, 0, pwArg);
- SECKEY_DestroyPublicKey(pubKey); pubKey = NULL;
- if (tek == NULL) {
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- ss->ssl3->fortezza.tek = PK11_ReferenceSymKey(tek);
-
- if (pwSpec->cipher_def->calg == calg_fortezza) {
- item.data = fortezza_CKE.wrapped_client_write_key;
- item.len = sizeof fortezza_CKE.wrapped_client_write_key;
-
- pwSpec->client.write_key =
- PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL, &item,
- CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
- if (pwSpec->client.write_key == NULL) {
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
- goto fortezza_loser;
- }
-
- item.data = fortezza_CKE.wrapped_server_write_key;
- item.len = sizeof fortezza_CKE.wrapped_server_write_key;
-
- pwSpec->server.write_key =
- PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL, &item,
- CKM_SKIPJACK_CBC64, CKA_ENCRYPT, 0);
- if (pwSpec->server.write_key == NULL) {
- PK11_FreeSymKey(pwSpec->client.write_key);
- pwSpec->client.write_key = NULL;
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
- goto fortezza_loser;
- }
- /* Set a flag that says "generate 8 byte random prefix plaintext." */
- PK11_SetFortezzaHack(pwSpec->server.write_key); /* can't fail */
-
- PORT_Memcpy(pwSpec->client.write_iv, fortezza_CKE.client_write_iv,
- sizeof fortezza_CKE.client_write_iv);
- PORT_Memcpy(pwSpec->server.write_iv, fortezza_CKE.server_write_iv,
- sizeof fortezza_CKE.server_write_iv);
-
- }
-
- /* decrypt the pms with the TEK */
- enc_pms.data = fortezza_CKE.encrypted_preMasterSecret;
- enc_pms.len = sizeof fortezza_CKE.encrypted_preMasterSecret;
-
- param.data = fortezza_CKE.master_secret_iv;
- param.len = sizeof fortezza_CKE.master_secret_iv;
-
- pms = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_CBC64, &param, &enc_pms,
- CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
- if (pms == NULL) {
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
- goto fortezza_loser;
- }
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms);
- if (rv != SECSuccess) {
- SEND_ALERT
- goto fortezza_loser; /* err code is set. */
- }
-
- if (pwSpec->cipher_def->calg == calg_fortezza) {
- PK11SlotInfo * slot;
-
- sid->u.ssl3.clientWriteKey =
- PK11_ReferenceSymKey(pwSpec->client.write_key);
- sid->u.ssl3.serverWriteKey =
- PK11_ReferenceSymKey(pwSpec->server.write_key);
-
- PORT_Memcpy(sid->u.ssl3.keys.client_write_iv, pwSpec->client.write_iv,
- sizeof sid->u.ssl3.keys.client_write_iv);
- PORT_Memcpy(sid->u.ssl3.keys.server_write_iv, pwSpec->server.write_iv,
- sizeof sid->u.ssl3.keys.server_write_iv);
-
- /* Now, wrap the client and server write keys in Ks for storage
- * in the on-disk sid.
- */
-
- slot = PK11_GetSlotFromKey(tek); /* get ref to the slot */
- if (slot == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- /* Look up the Token Fixed Key */
- Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL, ss->pkcs11PinArg);
- PK11_FreeSlot(slot);
- if (Ks == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- /* rewrap server write key with the local Ks */
- item.data = sid->u.ssl3.keys.wrapped_server_write_key;
- item.len = sizeof sid->u.ssl3.keys.wrapped_server_write_key;
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, Ks,
- pwSpec->server.write_key, &item);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- /* rewrap client write key with the local Ks */
- item.data = sid->u.ssl3.keys.wrapped_client_write_key;
- item.len = sizeof sid->u.ssl3.keys.wrapped_client_write_key;
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, Ks,
- pwSpec->client.write_key, &item);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- /* wrap the master secret later, when we handle the client's
- * finished message.
- */
- }
-
- sid->u.ssl3.hasFortezza = PR_TRUE;
- sid->u.ssl3.tek = tek; tek = NULL;
-
- rv = SECSuccess;
-
-fortezza_loser:
- if (Ks) PK11_FreeSymKey(Ks);
- if (tek) PK11_FreeSymKey(tek);
- if (pubKey) SECKEY_DestroyPublicKey(pubKey);
- if (fortezza_CKE.y_c.data != NULL)
- SECITEM_FreeItem(&fortezza_CKE.y_c, PR_FALSE);
- return rv;
-}
-
-/* find a slot that is able to generate a PMS and wrap it with RSA.
- * Then generate and return the PMS.
- * If the serverKeySlot parameter is non-null, this function will use
- * that slot to do the job, otherwise it will find a slot.
- *
- * Called from ssl3_GenerateSessionKeys() (above)
- * sendRSAClientKeyExchange() (above)
- * ssl3_HandleRSAClientKeyExchange() (below)
- * Caller must hold the SpecWriteLock, the SSL3HandshakeLock
- */
-static PK11SymKey *
-ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
- PK11SlotInfo * serverKeySlot)
-{
- PK11SymKey * pms = NULL;
- PK11SlotInfo * slot = serverKeySlot;
- void * pwArg = ss->pkcs11PinArg;
- SECItem param;
- CK_VERSION version;
- CK_MECHANISM_TYPE mechanism_array[3];
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- if (slot == NULL) {
- /* The specReadLock would suffice here, but we cannot assert on
- ** read locks. Also, all the callers who call with a non-null
- ** slot already hold the SpecWriteLock.
- */
- PORT_Assert( ssl_HaveSpecWriteLock(ss));
- PORT_Assert(ss->ssl3->prSpec == ss->ssl3->pwSpec);
-
- /* First get an appropriate slot. */
- mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN;
- mechanism_array[1] = CKM_RSA_PKCS;
- mechanism_array[2] = (CK_MECHANISM_TYPE) spec->cipher_def->calg;
- slot = PK11_GetBestSlotMultiple(mechanism_array, 3, pwArg);
- if (slot == NULL) {
- /* can't find a slot with all three, find a slot with the minimum */
- slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg);
- if (slot == NULL) {
- PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND);
- return pms; /* which is NULL */
- }
- }
- }
-
- /* Generate the pre-master secret ... */
- version.major = MSB(ss->clientHelloVersion);
- version.minor = LSB(ss->clientHelloVersion);
-
- param.data = (unsigned char *)&version;
- param.len = sizeof version;
-
- pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, &param, 0, pwArg);
- if (!serverKeySlot)
- PK11_FreeSlot(slot);
- if (pms == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- }
- return pms;
-}
-
-/* Note: The Bleichenbacher attack on PKCS#1 necessitates that we NEVER
- * return any indication of failure of the Client Key Exchange message,
- * where that failure is caused by the content of the client's message.
- * This function must not return SECFailure for any reason that is directly
- * or indirectly caused by the content of the client's encrypted PMS.
- * We must not send an alert and also not drop the connection.
- * Instead, we generate a random PMS. This will cause a failure
- * in the processing the finished message, which is exactly where
- * the failure must occur.
- *
- * Called from ssl3_HandleClientKeyExchange
- */
-static SECStatus
-ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
- SSL3Opaque *b,
- PRUint32 length,
- SECKEYPrivateKey *serverKey)
-{
- PK11SymKey * pms;
- SECStatus rv;
- SECItem enc_pms;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- enc_pms.data = b;
- enc_pms.len = length;
-
- if (ss->ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
- PRInt32 kLen;
- kLen = ssl3_ConsumeHandshakeNumber(ss, 2, &enc_pms.data, &enc_pms.len);
- if (kLen < 0) {
- PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
- if ((unsigned)kLen < enc_pms.len) {
- enc_pms.len = kLen;
- }
- }
- /*
- * decrypt pms out of the incoming buffer
- * Note: CKM_SSL3_PRE_MASTER_KEY_GEN 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_PRE_MASTER_KEY_GEN, 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 pre-master secret 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);
- }
-
- if (pms == NULL) {
- /* last gasp. */
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms);
- if (rv != SECSuccess) {
- SEND_ALERT
- return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
- }
- return SECSuccess;
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 ClientKeyExchange message from the remote client
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- SECKEYPrivateKey *serverKey = NULL;
- SECStatus rv;
-const ssl3KEADef * kea_def;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle client_key_exchange handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ss->ssl3->hs.ws != wait_client_key) {
- SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH);
- return SECFailure;
- }
-
- kea_def = ss->ssl3->hs.kea_def;
-
- serverKey = (ss->ssl3->hs.usedStepDownKey
-#ifdef DEBUG
- && kea_def->is_limited /* XXX OR cert is signing only */
- && kea_def->exchKeyType == kt_rsa
- && ss->stepDownKeyPair != NULL
-#endif
- ) ? ss->stepDownKeyPair->privKey
- : ss->serverKey[kea_def->exchKeyType];
-
- if (serverKey == NULL) {
- SEND_ALERT
- PORT_SetError(SSL_ERROR_NO_SERVER_KEY_FOR_ALG);
- return SECFailure;
- }
-
- switch (kea_def->exchKeyType) {
- case kt_rsa:
- rv = ssl3_HandleRSAClientKeyExchange(ss, b, length, serverKey);
- if (rv != SECSuccess) {
- SEND_ALERT
- return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
- }
- break;
-
- case kt_fortezza:
- rv = ssl3_HandleFortezzaClientKeyExchange(ss, b, length, serverKey);
- if (rv != SECSuccess) {
- return SECFailure; /* error code set */
- }
- break;
-
- default:
- (void) ssl3_HandshakeFailure(ss);
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- return SECFailure;
- }
- ss->ssl3->hs.ws = ss->sec->peerCert ? wait_cert_verify : wait_change_cipher;
- return SECSuccess;
-
-}
-
-/* This is TLS's equivalent of sending a no_certificate alert. */
-static SECStatus
-ssl3_SendEmptyCertificate(sslSocket *ss)
-{
- SECStatus rv;
-
- rv = ssl3_AppendHandshakeHeader(ss, certificate, 3);
- if (rv == SECSuccess) {
- rv = ssl3_AppendHandshakeNumber(ss, 0, 3);
- }
- return rv; /* error, if any, set by functions called above. */
-}
-
-/*
- * Used by both client and server.
- * Called from HandleServerHelloDone and from SendServerHelloSequence.
- */
-static SECStatus
-ssl3_SendCertificate(sslSocket *ss)
-{
- SECStatus rv;
- CERTCertificateList *certChain;
- int len = 0;
- int i;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send certificate handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- certChain = (ss->sec->isServer)
- ? ss->serverCertChain[ss->ssl3->hs.kea_def->exchKeyType]
- : ss->ssl3->clientCertChain;
-
- if (certChain) {
- for (i = 0; i < certChain->len; i++) {
- len += certChain->certs[i].len + 3;
- }
- }
-
- rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_AppendHandshakeNumber(ss, len, 3);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- for (i = 0; i < certChain->len; i++) {
- rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
- certChain->certs[i].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.
- */
-static void
-ssl3_CleanupPeerCerts(ssl3State *ssl3)
-{
- PRArenaPool * arena = ssl3->peerCertArena;
- ssl3CertNode *certs = (ssl3CertNode *)ssl3->peerCertChain;
-
- for (; certs; certs = certs->next) {
- CERT_DestroyCertificate(certs->cert);
- }
- if (arena) PORT_FreeArena(arena, PR_FALSE);
- ssl3->peerCertArena = NULL;
- ssl3->peerCertChain = NULL;
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Certificate message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- ssl3CertNode * c;
- ssl3CertNode * certs = NULL;
- PRArenaPool * arena = NULL;
- ssl3State * ssl3 = ss->ssl3;
- sslSecurityInfo *sec = ss->sec;
- CERTCertificate *cert;
- PRInt32 remaining;
- PRInt32 size;
- SECStatus rv;
- PRBool isServer = (PRBool)(!!sec->isServer);
- PRBool trusted = PR_FALSE;
- PRBool isTLS;
- SSL3AlertDescription desc = bad_certificate;
- int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE;
- SECItem certItem;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle certificate handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- if ((ssl3->hs.ws != wait_server_cert) &&
- (ssl3->hs.ws != wait_client_cert)) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CERTIFICATE;
- goto alert_loser;
- }
-
- PORT_Assert(ssl3->peerCertArena == NULL);
-
- if (sec->peerCert != NULL) {
- if (sec->peerKey) {
- SECKEY_DestroyPublicKey(sec->peerKey);
- sec->peerKey = NULL;
- }
- CERT_DestroyCertificate(sec->peerCert);
- sec->peerCert = NULL;
- }
-
- remaining = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (remaining < 0)
- goto loser; /* fatal alert already sent by ConsumeHandshake. */
-
- isTLS = (PRBool)(ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0);
- if (!remaining && isTLS && isServer) {
- /* This is TLS's version of a no_certificate alert. */
- /* I'm a server. I've requested a client cert. He hasn't got one. */
- rv = ssl3_HandleNoCertificate(ss);
- goto cert_block;
- }
-
- ssl3->peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser; /* don't send alerts on memory errors */
- }
-
- /* First get the peer cert. */
- remaining -= 3;
- if (remaining < 0)
- goto decode_loser;
-
- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (size < 0)
- goto loser; /* fatal alert already sent by ConsumeHandshake. */
-
- remaining -= size;
- if (remaining < 0)
- goto decode_loser;
-
- certItem.data = (unsigned char*)PORT_ArenaAlloc(arena, size);
- if (certItem.data == NULL) {
- goto loser; /* don't send alerts on memory errors */
- }
-
- certItem.len = size;
- rv = ssl3_ConsumeHandshake(ss, certItem.data, certItem.len, &b, &length);
- if (rv != SECSuccess)
- goto loser; /* fatal alert already sent by ConsumeHandshake. */
-
- sec->peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
- if (sec->peerCert == NULL) {
- /* We should report an alert if the cert was bad, but not if the
- * problem was just some local problem, like memory error.
- */
- goto ambiguous_err;
- }
-
- /* Now get all of the CA certs. */
- while (remaining != 0) {
- remaining -= 3;
- if (remaining < 0)
- goto decode_loser;
-
- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (size < 0)
- goto loser; /* fatal alert already sent by ConsumeHandshake. */
-
- remaining -= size;
- if (remaining < 0)
- goto decode_loser;
-
- certItem.data = (unsigned char*)PORT_ArenaAlloc(arena, size);
- if (certItem.data == NULL) {
- goto loser; /* don't send alerts on memory errors */
- }
-
- certItem.len = size;
- rv = ssl3_ConsumeHandshake(ss, certItem.data, certItem.len,
- &b, &length);
- if (rv != SECSuccess)
- goto loser; /* fatal alert already sent by ConsumeHandshake. */
-
- c = PORT_ArenaNew(arena, ssl3CertNode);
- if (c == NULL) {
- goto loser; /* don't send alerts on memory errors */
- }
-
- c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
- if (c->cert == NULL) {
- goto ambiguous_err;
- }
-
- if (c->cert->trust)
- trusted = PR_TRUE;
-
- c->next = certs;
- certs = c;
- }
-
- if (remaining != 0)
- goto decode_loser;
-
- SECKEY_UpdateCertPQG(sec->peerCert);
-
- /*
- * We're making a fortezza connection, and the card hasn't unloaded it's
- * certs, try to unload those certs now.
- */
- if (!trusted) {
- CERTCertificate *ccert;
-
- ccert = PK11_FindBestKEAMatch(sec->peerCert, ss->pkcs11PinArg);
- if (ccert)
- CERT_DestroyCertificate(ccert);
- }
-
-
- rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd,
- PR_TRUE, isServer);
- if (rv) {
- errCode = PORT_GetError();
- if (!ss->handleBadCert) {
- goto bad_cert;
- }
- rv = (SECStatus)(*ss->handleBadCert)(ss->badCertArg, ss->fd);
- if ( rv ) {
- if ( rv == SECWouldBlock ) {
- /* someone will handle this connection asynchronously*/
- SSL_DBG(("%d: SSL3[%d]: go to async cert handler",
- SSL_GETPID(), ss->fd));
- ssl3->peerCertChain = certs;
- certs = NULL;
- ssl_SetAlwaysBlock(ss);
- goto cert_block;
- }
- /* cert is bad */
- goto bad_cert;
- }
- /* cert is good */
- }
-
- /* start SSL Step Up, if appropriate */
- cert = sec->peerCert;
- if (!isServer &&
- ssl3_global_policy_some_restricted &&
- ssl3->policy == SSL_ALLOWED &&
- anyRestrictedEnabled(ss) &&
- SECSuccess == CERT_VerifyCertNow(cert->dbhandle, cert,
- PR_FALSE, /* checkSig */
- certUsageSSLServerWithStepUp,
-/*XXX*/ ss->authCertificateArg) ) {
- ssl3->policy = SSL_RESTRICTED;
- ssl3->hs.rehandshake = PR_TRUE;
- }
-
- sec->ci.sid->peerCert = CERT_DupCertificate(sec->peerCert);
-
- /* We don't need the CA certs now that we've authenticated the peer cert. */
- ssl3->peerCertChain = certs; certs = NULL; arena = NULL;
- ssl3_CleanupPeerCerts(ssl3);
-
-cert_block:
- if (sec->isServer) {
- ssl3->hs.ws = wait_client_key;
- } else {
- ssl3->hs.ws = wait_cert_request; /* disallow server_key_exchange */
- if (ssl3->hs.kea_def->is_limited ||
- /* XXX OR server cert is signing only. */
- ssl3->hs.kea_def->kea == kea_fortezza) {
- ssl3->hs.ws = wait_server_key; /* allow server_key_exchange */
- }
- }
-
- /* rv must normally be equal to SECSuccess here. If we called
- * handleBadCert, it can also be SECWouldBlock.
- */
- return rv;
-
-ambiguous_err:
- errCode = PORT_GetError();
- switch (errCode) {
- case PR_OUT_OF_MEMORY_ERROR:
- case SEC_ERROR_BAD_DATABASE:
- case SEC_ERROR_NO_MEMORY:
- if (isTLS) {
- desc = internal_error;
- goto alert_loser;
- }
- goto loser;
- }
- /* fall through to bad_cert. */
-
-bad_cert: /* caller has set errCode. */
- switch (errCode) {
- case SEC_ERROR_LIBRARY_FAILURE: desc = unsupported_certificate; break;
- case SEC_ERROR_EXPIRED_CERTIFICATE: desc = certificate_expired; break;
- case SEC_ERROR_REVOKED_CERTIFICATE: desc = certificate_revoked; break;
- case SEC_ERROR_INADEQUATE_KEY_USAGE:
- case SEC_ERROR_INADEQUATE_CERT_TYPE:
- desc = certificate_unknown; break;
- case SEC_ERROR_UNTRUSTED_CERT:
- desc = isTLS ? access_denied : certificate_unknown; break;
- case SEC_ERROR_UNKNOWN_ISSUER:
- case SEC_ERROR_UNTRUSTED_ISSUER:
- desc = isTLS ? unknown_ca : certificate_unknown; break;
- case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
- desc = isTLS ? unknown_ca : certificate_expired; break;
-
- case SEC_ERROR_CERT_NOT_IN_NAME_SPACE:
- case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID:
- case SEC_ERROR_CA_CERT_INVALID:
- case SEC_ERROR_BAD_SIGNATURE:
- default: desc = bad_certificate; break;
- }
- SSL_DBG(("%d: SSL3[%d]: peer certificate is no good: error=%d",
- SSL_GETPID(), ss->fd, errCode));
-
- goto alert_loser;
-
-decode_loser:
- desc = isTLS ? decode_error : bad_certificate;
-
-alert_loser:
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
-
-loser:
- ssl3->peerCertChain = certs; certs = NULL; arena = NULL;
- ssl3_CleanupPeerCerts(ssl3);
-
- if (sec->peerCert != NULL) {
- CERT_DestroyCertificate(sec->peerCert);
- sec->peerCert = NULL;
- }
- (void)ssl_MapLowLevelError(errCode);
- return SECFailure;
-}
-
-
-/* restart an SSL connection that we stopped to run certificate dialogs
-** XXX Need to document here how an application marks a cert to show that
-** the application has accepted it (overridden CERT_VerifyCert).
- *
- * XXX This code only works on the initial handshake on a connection, XXX
- * It does not work on a subsequent handshake (redo).
- *
- * Return value: XXX
- *
- * Caller holds 1stHandshakeLock.
-*/
-int
-ssl3_RestartHandshakeAfterServerCert(sslSocket *ss)
-{
- CERTCertificate * cert;
- ssl3State * ssl3 = ss->ssl3;
- int rv = SECSuccess;
-
- if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
- SET_ERROR_CODE
- return SECFailure;
- }
- if (!ss->sec || !ss->ssl3) {
- SET_ERROR_CODE
- return SECFailure;
- }
-
- cert = ss->sec->peerCert;
-
- /* Permit step up if user decided to accept the cert */
- if (!ss->sec->isServer &&
- ssl3_global_policy_some_restricted &&
- ssl3->policy == SSL_ALLOWED &&
- anyRestrictedEnabled(ss) &&
- (SECSuccess == CERT_VerifyCertNow(cert->dbhandle, cert,
- PR_FALSE, /* checksig */
- certUsageSSLServerWithStepUp,
-/*XXX*/ ss->authCertificateArg) )) {
- ssl3->policy = SSL_RESTRICTED;
- ssl3->hs.rehandshake = PR_TRUE;
- }
-
- if (ss->handshake != NULL) {
- ss->handshake = ssl_GatherRecord1stHandshake;
- ssl3_CleanupPeerCerts(ssl3);
- ss->sec->ci.sid->peerCert = CERT_DupCertificate(ss->sec->peerCert);
-
- ssl_GetRecvBufLock(ss);
- if (ssl3->hs.msgState.buf != NULL) {
- rv = ssl3_HandleRecord(ss, NULL, &ss->gather->buf);
- }
- ssl_ReleaseRecvBufLock(ss);
- }
-
- return rv;
-}
-
-static SECStatus
-ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
- PRBool isServer,
- const SSL3Finished * hashes,
- TLSFinished * tlsFinished)
-{
- PK11Context *prf_context;
- const char * label;
- unsigned int len;
- SECStatus rv;
- SECItem param = {siBuffer, NULL, 0};
-
- label = isServer ? "server finished" : "client finished";
- len = 15;
-
- prf_context =
- PK11_CreateContextBySymKey(CKM_TLS_PRF_GENERAL, CKA_SIGN,
- spec->master_secret, &param);
- if (!prf_context)
- return SECFailure;
-
- rv = PK11_DigestBegin(prf_context);
- rv |= PK11_DigestOp(prf_context, (const unsigned char *) label, len);
- rv |= PK11_DigestOp(prf_context, hashes->md5, sizeof *hashes);
- rv |= PK11_DigestFinal(prf_context, tlsFinished->verify_data,
- &len, sizeof *tlsFinished);
- PORT_Assert(rv != SECSuccess || len == sizeof *tlsFinished);
-
- PK11_DestroyContext(prf_context, PR_TRUE);
- return rv;
-}
-
-/* called from ssl3_HandleServerHelloDone
- * ssl3_HandleClientHello
- * ssl3_HandleFinished
- */
-static SECStatus
-ssl3_SendFinished(sslSocket *ss, PRInt32 flags)
-{
- ssl3CipherSpec *cwSpec;
- PRBool isTLS;
- PRBool isServer = ss->sec->isServer;
- SECStatus rv;
- SSL3Sender sender = isServer ? sender_server : sender_client;
- SSL3Finished hashes;
- TLSFinished tlsFinished;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send finished handshake", SSL_GETPID(), ss->fd));
-
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- ssl_GetSpecReadLock(ss);
- cwSpec = ss->ssl3->cwSpec;
- isTLS = (PRBool)(cwSpec->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_ComputeHandshakeHashes(ss, cwSpec, &hashes, sender);
- if (isTLS && rv == SECSuccess) {
- rv = ssl3_ComputeTLSFinished(cwSpec, isServer, &hashes, &tlsFinished);
- }
- ssl_ReleaseSpecReadLock(ss);
- if (rv != SECSuccess) {
- goto fail; /* err code was set by ssl3_ComputeHandshakeHashes */
- }
-
- if (isTLS) {
- rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof tlsFinished);
- if (rv != SECSuccess)
- goto fail; /* err set by AppendHandshake. */
- rv = ssl3_AppendHandshake(ss, &tlsFinished, sizeof tlsFinished);
- if (rv != SECSuccess)
- goto fail; /* err set by AppendHandshake. */
- } else {
- rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof hashes);
- if (rv != SECSuccess)
- goto fail; /* err set by AppendHandshake. */
- rv = ssl3_AppendHandshake(ss, &hashes, sizeof hashes);
- if (rv != SECSuccess)
- goto fail; /* err set by AppendHandshake. */
- }
- rv = ssl3_FlushHandshake(ss, flags);
- if (rv != SECSuccess) {
- goto fail; /* error code set by ssl3_FlushHandshake */
- }
- return SECSuccess;
-
-fail:
- return rv;
-}
-
-
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Finished message from the peer.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
- const SSL3Hashes *hashes)
-{
- sslSecurityInfo * sec = ss->sec;
- ssl3State * ssl3 = ss->ssl3;
- sslSessionID * sid = sec->ci.sid;
- PK11SymKey * wrappingKey = NULL;
- PK11SlotInfo * symKeySlot;
- void * pwArg = ss->pkcs11PinArg;
- SECStatus rv;
- PRBool isServer = sec->isServer;
- PRBool isTLS;
- PRBool doStepUp;
- CK_MECHANISM_TYPE mechanism;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle finished handshake",
- SSL_GETPID(), ss->fd));
-
- if (ssl3->hs.ws != wait_finished) {
- SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_FINISHED);
- return SECFailure;
- }
-
- isTLS = (PRBool)(ssl3->crSpec->version > SSL_LIBRARY_VERSION_3_0);
- if (isTLS) {
- TLSFinished tlsFinished;
-
- if (length != sizeof tlsFinished) {
- (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
- return SECFailure;
- }
- rv = ssl3_ComputeTLSFinished(ssl3->crSpec, !isServer,
- hashes, &tlsFinished);
- if (rv != SECSuccess ||
- 0 != PORT_Memcmp(&tlsFinished, b, length)) {
- (void)SSL3_SendAlert(ss, alert_fatal, decrypt_error);
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- return SECFailure;
- }
- } else {
- if (length != sizeof(SSL3Hashes)) {
- (void)ssl3_IllegalParameter(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
- return SECFailure;
- }
-
- if (0 != PORT_Memcmp(hashes, b, length)) {
- (void)ssl3_HandshakeFailure(ss);
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- return SECFailure;
- }
- }
-
- doStepUp = (PRBool)(!isServer && ssl3->hs.rehandshake);
-
- ssl_GetXmitBufLock(ss); /*************************************/
-
- if ((isServer && !ssl3->hs.isResuming) ||
- (!isServer && ssl3->hs.isResuming)) {
-
- rv = ssl3_SendChangeCipherSpecs(ss);
- if (rv != SECSuccess) {
- goto xmit_loser; /* err is set. */
- }
- /* XXX Right here, if we knew, somehow, that this thread was in
- ** SSL_SecureSend (trying to write some data) and we weren't going
- ** to step up, then we could set the ssl_SEND_FLAG_FORCE_INTO_BUFFER
- ** flag, so that the last two handshake messages
- ** (e.g. change cipher spec and finished) would get
- ** sent out in the same send/write call as the application data.
- */
- rv = ssl3_SendFinished(ss, 0);
- if (rv != SECSuccess) {
- goto xmit_loser; /* err is set. */
- }
- }
-
- /* Optimization: don't cache this connection if we're going to step up. */
- if (doStepUp) {
- ssl_FreeSID(sid);
- ss->sec->ci.sid = sid = NULL;
- ssl3->hs.rehandshake = PR_FALSE;
- rv = ssl3_SendClientHello(ss);
-xmit_loser:
- ssl_ReleaseXmitBufLock(ss);
- return rv; /* err code is set if appropriate. */
- }
-
- ssl_ReleaseXmitBufLock(ss); /*************************************/
-
- /* we're connected now. */
- ss->handshake = NULL;
- ss->connected = PR_TRUE;
- ss->gather->writeOffset = 0;
- ss->gather->readOffset = 0;
-
- if (sid->cached == never_cached) {
-
- /* fill in the sid */
- sid->u.ssl3.cipherSuite = ssl3->hs.cipher_suite;
- sid->u.ssl3.compression = ssl3->hs.compression;
- sid->u.ssl3.policy = ssl3->policy;
- sid->u.ssl3.exchKeyType = ssl3->hs.kea_def->exchKeyType;
- sid->version = ss->version;
-
- ssl_GetSpecReadLock(ss); /*************************************/
- symKeySlot = PK11_GetSlotFromKey(ssl3->crSpec->master_secret);
- if (!isServer) {
- int wrapKeyIndex;
- int incarnation;
-
- /* these next few functions are mere accessors and don't fail. */
- sid->u.ssl3.masterWrapIndex = wrapKeyIndex =
- PK11_GetCurrentWrapIndex(symKeySlot);
- PORT_Assert(wrapKeyIndex == 0); /* array has only one entry! */
-
- sid->u.ssl3.masterWrapSeries = incarnation =
- PK11_GetSlotSeries(symKeySlot);
- sid->u.ssl3.masterSlotID = PK11_GetSlotID(symKeySlot);
- sid->u.ssl3.masterModuleID = PK11_GetModuleID(symKeySlot);
- sid->u.ssl3.masterValid = PR_TRUE;
-
- /* Get the default wrapping key, for wrapping the master secret before
- * placing it in the SID cache entry. */
- wrappingKey = PK11_GetWrapKey(symKeySlot, wrapKeyIndex,
- CKM_INVALID_MECHANISM, incarnation,
- pwArg);
- if (wrappingKey) {
- mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
- } else {
- int keyLength;
- /* if the wrappingKey doesn't exist, attempt to create it.
- * Note: we intentionally ignore errors here. If we cannot
- * generate a wrapping key, it is not fatal to this SSL connection,
- * but we will not be able to restart this session.
- */
- mechanism = PK11_GetBestWrapMechanism(symKeySlot);
- keyLength = PK11_GetBestKeyLength(symKeySlot, mechanism);
- /* Zero length means fixed key length algorithm, or error.
- * It's ambiguous.
- */
- wrappingKey = PK11_KeyGen(symKeySlot, mechanism, NULL,
- keyLength, pwArg);
- if (wrappingKey) {
- PK11_SetWrapKey(symKeySlot, wrapKeyIndex, wrappingKey);
- }
- }
- } else {
- /* server. */
- mechanism = PK11_GetBestWrapMechanism(symKeySlot);
- if (mechanism != CKM_INVALID_MECHANISM) {
- wrappingKey =
- getWrappingKey(ss, symKeySlot, ssl3->hs.kea_def->exchKeyType,
- mechanism, pwArg);
- if (wrappingKey) {
- mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
- }
- }
- }
-
- sid->u.ssl3.masterWrapMech = mechanism;
- PK11_FreeSlot(symKeySlot);
-
- rv = SECFailure;
- if (wrappingKey) {
- SECItem msItem;
-
- msItem.data = sid->u.ssl3.keys.wrapped_master_secret;
- msItem.len = sizeof sid->u.ssl3.keys.wrapped_master_secret;
- rv = PK11_WrapSymKey(mechanism, NULL, wrappingKey,
- ssl3->crSpec->master_secret, &msItem);
- /* rv is examined below. */
- sid->u.ssl3.keys.wrapped_master_secret_len = msItem.len;
- PK11_FreeSymKey(wrappingKey);
- }
- ssl_ReleaseSpecReadLock(ss); /*************************************/
-
- /* If the wrap failed, we don't cache the sid.
- * The connection continues normally however.
- */
- if (!ss->noCache && rv == SECSuccess) {
- (*sec->cache)(sid);
- }
- }
- ss->ssl3->hs.ws = idle_handshake;
-
- /* Do the handshake callback for sslv3 here. */
- if (ss->handshakeCallback != NULL) {
- (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
- }
-
- return SECSuccess;
-}
-
-/* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3
- * hanshake message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- SECStatus rv = SECSuccess;
- SSL3HandshakeType type = ss->ssl3->hs.msg_type;
- SSL3Hashes hashes; /* computed hashes are put here. */
- PRUint8 hdr[4];
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
- /*
- * We have to compute the hashes before we update them with the
- * current message.
- */
- ssl_GetSpecReadLock(ss); /************************************/
- if((type == finished) || (type == certificate_verify)) {
- SSL3Sender sender = (SSL3Sender)0;
- ssl3CipherSpec *rSpec = ss->ssl3->prSpec;
-
- if (type == finished) {
- sender = ss->sec->isServer ? sender_client : sender_server;
- rSpec = ss->ssl3->crSpec;
- }
- rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender);
- }
- ssl_ReleaseSpecReadLock(ss); /************************************/
- if (rv != SECSuccess) {
- return rv; /* error code was set by ssl3_ComputeHandshakeHashes*/
- }
- SSL_TRC(30,("%d: SSL3[%d]: handle handshake message: %s", SSL_GETPID(),
- ss->fd, ssl3_DecodeHandshakeType(ss->ssl3->hs.msg_type)));
- PRINT_BUF(60, (ss, "MD5 handshake hash:",
- (unsigned char*)ss->ssl3->hs.md5, MD5_LENGTH));
- PRINT_BUF(95, (ss, "SHA handshake hash:",
- (unsigned char*)ss->ssl3->hs.sha, SHA1_LENGTH));
-
- hdr[0] = (PRUint8)ss->ssl3->hs.msg_type;
- hdr[1] = (PRUint8)(length >> 16);
- hdr[2] = (PRUint8)(length >> 8);
- hdr[3] = (PRUint8)(length );
-
- /* Start new handshake hashes when we start a new handshake */
- if (ss->ssl3->hs.msg_type == client_hello) {
- SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
- SSL_GETPID(), ss->fd ));
- rv = PK11_DigestBegin(ss->ssl3->hs.md5);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return rv;
- }
- rv = PK11_DigestBegin(ss->ssl3->hs.sha);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return rv;
- }
- }
- /* We should not include hello_request messages in the handshake hashes */
- if (ss->ssl3->hs.msg_type != hello_request) {
- rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) hdr, 4);
- if (rv != SECSuccess) return rv; /* err code already set. */
- rv = ssl3_UpdateHandshakeHashes(ss, b, length);
- if (rv != SECSuccess) return rv; /* err code already set. */
- }
-
- PORT_SetError(0); /* each message starts with no error. */
- switch (ss->ssl3->hs.msg_type) {
- case hello_request:
- if (length != 0) {
- (void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST);
- return SECFailure;
- }
- if (ss->sec->isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST);
- return SECFailure;
- }
- rv = ssl3_HandleHelloRequest(ss);
- break;
- case client_hello:
- if (!ss->sec->isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO);
- return SECFailure;
- }
- rv = ssl3_HandleClientHello(ss, b, length);
- break;
- case server_hello:
- if (ss->sec->isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO);
- return SECFailure;
- }
- rv = ssl3_HandleServerHello(ss, b, length);
- break;
- case certificate:
- rv = ssl3_HandleCertificate(ss, b, length);
- break;
- case server_key_exchange:
- if (ss->sec->isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH);
- return SECFailure;
- }
- rv = ssl3_HandleServerKeyExchange(ss, b, length);
- break;
- case certificate_request:
- if (ss->sec->isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST);
- return SECFailure;
- }
- rv = ssl3_HandleCertificateRequest(ss, b, length);
- break;
- case server_hello_done:
- if (length != 0) {
- (void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_DONE);
- return SECFailure;
- }
- if (ss->sec->isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
- return SECFailure;
- }
- rv = ssl3_HandleServerHelloDone(ss);
- break;
- case certificate_verify:
- if (!ss->sec->isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY);
- return SECFailure;
- }
- rv = ssl3_HandleCertificateVerify(ss, b, length, &hashes);
- break;
- case client_key_exchange:
- if (!ss->sec->isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH);
- return SECFailure;
- }
- rv = ssl3_HandleClientKeyExchange(ss, b, length);
- break;
- case finished:
- rv = ssl3_HandleFinished(ss, b, length, &hashes);
- break;
- default:
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNKNOWN_HANDSHAKE);
- rv = SECFailure;
- }
- return rv;
-}
-
-/* Called only from ssl3_HandleRecord, for each (deciphered) ssl3 record.
- * origBuf is the decrypted ssl record content.
- * Caller must hold the handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
-{
- /*
- * There may be a partial handshake message already in the handshake
- * state. The incoming buffer may contain another portion, or a
- * complete message or several messages followed by another portion.
- *
- * Each message is made contiguous before being passed to the actual
- * message parser.
- */
- ssl3State *ssl3 = ss->ssl3;
- sslBuffer *buf = &ssl3->hs.msgState; /* do not lose the original buffer pointer */
- SECStatus rv;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- if (buf->buf == NULL) {
- *buf = *origBuf;
- }
- while (buf->len > 0) {
- while (ssl3->hs.header_bytes < 4) {
- uint8 t;
- t = *(buf->buf++);
- buf->len--;
- if (ssl3->hs.header_bytes++ == 0)
- ssl3->hs.msg_type = (SSL3HandshakeType)t;
- else
- ssl3->hs.msg_len = (ssl3->hs.msg_len << 8) + t;
-
-#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
-
- if (ssl3->hs.header_bytes == 4) {
- if (ssl3->hs.msg_len > MAX_HANDSHAKE_MSG_LEN) {
- (void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
- return SECFailure;
- }
- }
-#undef MAX_HANDSHAKE_MSG_LEN
- if (buf->len == 0 && ssl3->hs.msg_len > 0) {
- buf->buf = NULL;
- return SECSuccess;
- }
- }
-
- /*
- * Header has been gathered and there is at least one byte of new
- * data available for this message. If it can be done right out
- * of the original buffer, then use it from there.
- */
- if (ssl3->hs.msg_body.len == 0 && buf->len >= ssl3->hs.msg_len) {
- /* handle it from input buffer */
- rv = ssl3_HandleHandshakeMessage(ss, buf->buf, ssl3->hs.msg_len);
- if (rv == SECFailure) {
- /* This test wants to fall through on either
- * SECSuccess or SECWouldBlock.
- * ssl3_HandleHandshakeMessage MUST set the error code.
- */
- return rv;
- }
- buf->buf += ssl3->hs.msg_len;
- buf->len -= ssl3->hs.msg_len;
- ssl3->hs.msg_len = 0;
- ssl3->hs.header_bytes = 0;
- if (rv != SECSuccess) { /* return if SECWouldBlock. */
- return rv;
- }
- } else {
- /* must be copied to msg_body and dealt with from there */
- unsigned int bytes;
-
- bytes = PR_MIN(buf->len, ssl3->hs.msg_len);
-
- /* Grow the buffer if needed */
- if (bytes > ssl3->hs.msg_body.space - ssl3->hs.msg_body.len) {
- rv = sslBuffer_Grow(&ssl3->hs.msg_body,
- ssl3->hs.msg_body.len + bytes);
- if (rv != SECSuccess) {
- /* sslBuffer_Grow has set a memory error code. */
- return SECFailure;
- }
- }
- PORT_Memcpy(ssl3->hs.msg_body.buf + ssl3->hs.msg_body.len,
- buf->buf, buf->len);
- buf->buf += bytes;
- buf->len -= bytes;
-
- /* should not be more than one message in msg_body */
- PORT_Assert(ssl3->hs.msg_body.len <= ssl3->hs.msg_len);
-
- /* if we have a whole message, do it */
- if (ssl3->hs.msg_body.len == ssl3->hs.msg_len) {
- rv = ssl3_HandleHandshakeMessage(
- ss, ssl3->hs.msg_body.buf, ssl3->hs.msg_len);
- /*
- * XXX This appears to be wrong. This error handling
- * should clean up after a SECWouldBlock return, like the
- * error handling used 40 lines before/above this one,
- */
- if (rv != SECSuccess) {
- /* ssl3_HandleHandshakeMessage MUST set error code. */
- return rv;
- }
- ssl3->hs.msg_body.len = 0;
- ssl3->hs.msg_len = 0;
- ssl3->hs.header_bytes = 0;
- } else {
- PORT_Assert(buf->len == 0);
- break;
- }
- }
- } /* end loop */
-
- origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
- buf->buf = NULL; /* not a leak. */
- return SECSuccess;
-}
-
-/* if cText is non-null, then decipher, check MAC, and decompress the
- * SSL record from cText->buf (typically gs->inbuf)
- * into databuf (typically gs->buf), and any previous contents of databuf
- * is lost. Then handle databuf according to its SSL record type,
- * unless it's an application record.
- *
- * If cText is NULL, then the ciphertext has previously been deciphered and
- * checked, and is already sitting in databuf. It is processed as an SSL
- * Handshake message.
- *
- * DOES NOT process the decrypted/decompressed application data.
- * On return, databuf contains the decrypted/decompressed record.
- *
- * Called from ssl3_GatherCompleteHandshake
- * ssl3_RestartHandshakeAfterCertReq
- * ssl3_RestartHandshakeAfterServerCert
- *
- * Caller must hold the RecvBufLock.
- *
- * This function aquires and releases the SSL3Handshake Lock, holding the
- * lock around any calls to functions that handle records other than
- * Application Data records.
- */
-SECStatus
-ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
-{
-const ssl3BulkCipherDef *cipher_def;
- ssl3State * ssl3 = ss->ssl3;
- ssl3CipherSpec * crSpec;
- SECStatus rv;
- unsigned int hashBytes;
- unsigned int padding_length;
- PRBool isTLS;
- SSL3ContentType rType;
- SSL3Opaque hash[MAX_MAC_LENGTH];
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
-
- if (ssl3 == NULL) {
- ssl_GetSSL3HandshakeLock(ss);
- rv = ssl3_InitState(ss);
- ssl_ReleaseSSL3HandshakeLock(ss);
- if (rv != SECSuccess) {
- return rv; /* ssl3_InitState has set the error code. */
- }
- }
-
- ssl3 = ss->ssl3;
-
- /* cText is NULL when we're called from ssl3_RestartHandshakeAfterXXX().
- * This implies that databuf holds a previously deciphered SSL Handshake
- * message.
- */
- if (cText == NULL) {
- SSL_DBG(("%d: SSL3[%d]: HandleRecord, resuming handshake",
- SSL_GETPID(), ss->fd));
- rType = content_handshake;
- goto process_it;
- }
-
- databuf->len = 0; /* filled in by decode call below. */
- if (databuf->space < MAX_FRAGMENT_LENGTH) {
- rv = sslBuffer_Grow(databuf, MAX_FRAGMENT_LENGTH + 2048);
- if (rv != SECSuccess) {
- SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes",
- SSL_GETPID(), ss->fd, MAX_FRAGMENT_LENGTH + 2048));
- /* sslBuffer_Grow has set a memory error code. */
- return SECFailure;
- }
- }
-
- PRINT_BUF(80, (ss, "ciphertext:", cText->buf->buf, cText->buf->len));
-
- ssl_GetSpecReadLock(ss); /******************************************/
-
- crSpec = ssl3->crSpec;
- cipher_def = crSpec->cipher_def;
- isTLS = (PRBool)(crSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- if (isTLS && cText->buf->len > (MAX_FRAGMENT_LENGTH + 2048)) {
- SSL3_SendAlert(ss, alert_fatal, record_overflow);
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
- return SECFailure;
- }
- /* decrypt from cText buf to databuf. */
- rv = crSpec->decode(
- crSpec->decodeContext, databuf->buf, (int *)&databuf->len,
- databuf->space, cText->buf->buf, cText->buf->len);
-
- PRINT_BUF(80, (ss, "cleartext:", databuf->buf, databuf->len));
- if (rv != SECSuccess) {
- ssl_ReleaseSpecReadLock(ss);
- ssl_MapLowLevelError(SSL_ERROR_DECRYPTION_FAILURE);
- if (isTLS)
- (void)SSL3_SendAlert(ss, alert_fatal, decryption_failed);
- ssl_MapLowLevelError(SSL_ERROR_DECRYPTION_FAILURE);
- return SECFailure;
- }
-
- /* If it's a block cipher, check and strip the padding. */
- if (cipher_def->type == type_block) {
- padding_length = *(databuf->buf + databuf->len - 1);
- /* TLS permits padding to exceed the block size, up to 255 bytes. */
- if (padding_length + crSpec->mac_size >= databuf->len)
- goto bad_pad;
- /* if TLS, check value of first padding byte. */
- if (padding_length && isTLS && padding_length !=
- *(databuf->buf + databuf->len - 1 - padding_length))
- goto bad_pad;
- databuf->len -= padding_length + 1;
- if (databuf->len <= 0) {
-bad_pad:
- /* must not hold spec lock when calling SSL3_SendAlert. */
- ssl_ReleaseSpecReadLock(ss);
- /* SSL3 doesn't have an alert for bad padding, so use bad mac. */
- SSL3_SendAlert(ss, alert_fatal,
- isTLS ? decryption_failed : bad_record_mac);
- PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
- return SECFailure;
- }
- }
-
- /* Check the MAC. */
- if (databuf->len < crSpec->mac_size) {
- /* record is too short to have a valid mac. */
- goto bad_mac;
- }
- databuf->len -= crSpec->mac_size;
- rType = cText->type;
- rv = ssl3_ComputeRecordMAC(
- crSpec, (ss->sec->isServer) ? crSpec->client.write_mac_context
- : crSpec->server.write_mac_context,
- rType, cText->version, crSpec->read_seq_num,
- databuf->buf, databuf->len, hash, &hashBytes);
- if (rv != SECSuccess) {
- ssl_ReleaseSpecReadLock(ss);
- ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
- return rv;
- }
-
- if (hashBytes != (unsigned)crSpec->mac_size ||
- PORT_Memcmp(databuf->buf + databuf->len, hash, crSpec->mac_size) != 0) {
-bad_mac:
- /* must not hold spec lock when calling SSL3_SendAlert. */
- ssl_ReleaseSpecReadLock(ss);
- SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
- PORT_SetError(SSL_ERROR_BAD_MAC_READ);
-
- SSL_DBG(("%d: SSL3[%d]: mac check failed", SSL_GETPID(), ss->fd));
-
- return SECFailure;
- }
-
- ssl3_BumpSequenceNumber(&crSpec->read_seq_num);
-
- ssl_ReleaseSpecReadLock(ss); /*****************************************/
-
- /*
- * The decrypted data is now in databuf.
- *
- * the null decompression routine is right here
- */
-
- /*
- ** Having completed the decompression, check the length again.
- */
- if (isTLS && databuf->len > (MAX_FRAGMENT_LENGTH + 1024)) {
- SSL3_SendAlert(ss, alert_fatal, record_overflow);
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
- return SECFailure;
- }
-
- /* Application data records are processed by the caller of this
- ** function, not by this function.
- */
- if (rType == content_application_data) {
- return SECSuccess;
- }
-
- /* It's a record that must be handled by ssl itself, not the application.
- */
-process_it:
- /* XXX Get the xmit lock here. Odds are very high that we'll be xmiting
- * data ang getting the xmit lock here prevents deadlocks.
- */
- ssl_GetSSL3HandshakeLock(ss);
-
- /* All the functions called in this switch MUST set error code if
- ** they return SECFailure or SECWouldBlock.
- */
- switch (rType) {
- case content_change_cipher_spec:
- rv = ssl3_HandleChangeCipherSpecs(ss, databuf);
- break;
- case content_alert:
- rv = ssl3_HandleAlert(ss, databuf);
- break;
- case content_handshake:
- rv = ssl3_HandleHandshake(ss, databuf);
- break;
- case content_application_data:
- rv = SECSuccess;
- break;
- default:
- SSL_DBG(("%d: SSL3[%d]: bogus content type=%d",
- SSL_GETPID(), ss->fd, cText->type));
- /* XXX Send an alert ??? */
- PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE);
- rv = SECFailure;
- break;
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- return rv;
-
-}
-
-/*
- * Initialization functions
- */
-
-/* Called from ssl3_InitState, immediately below. */
-/* Caller must hold the SpecWriteLock. */
-static void
-ssl3_InitCipherSpec(sslSocket *ss, ssl3CipherSpec *spec)
-{
- spec->cipher_def = &bulk_cipher_defs[cipher_null];
- PORT_Assert(spec->cipher_def->cipher == cipher_null);
- spec->mac_def = &mac_defs[mac_null];
- PORT_Assert(spec->mac_def->mac == mac_null);
- spec->encode = Null_Cipher;
- spec->decode = Null_Cipher;
- spec->destroy = NULL;
- spec->mac_size = 0;
- spec->master_secret = NULL;
-
- spec->client.write_key = NULL;
- spec->client.write_mac_key = NULL;
- spec->client.write_mac_context = NULL;
-
- spec->server.write_key = NULL;
- spec->server.write_mac_key = NULL;
- spec->server.write_mac_context = NULL;
-
- spec->write_seq_num.high = 0;
- spec->write_seq_num.low = 0;
-
- spec->read_seq_num.high = 0;
- spec->read_seq_num.low = 0;
-
- spec->version = ss->enableTLS
- ? SSL_LIBRARY_VERSION_3_1_TLS
- : SSL_LIBRARY_VERSION_3_0;
-}
-
-/* Called from: ssl3_SendRecord
-** ssl3_StartHandshakeHash() <- ssl2_BeginClientHandshake()
-** ssl3_SendClientHello()
-** ssl3_HandleServerHello()
-** ssl3_HandleClientHello()
-** ssl3_HandleV2ClientHello()
-** ssl3_HandleRecord()
-**
-** This function should perhaps acquire and release the SpecWriteLock.
-**
-**
-*/
-static SECStatus
-ssl3_InitState(sslSocket *ss)
-{
- ssl3State * ssl3 = NULL;
- PK11Context *md5 = NULL;
- PK11Context *sha = NULL;
- SECStatus rv;
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- /* reinitialization for renegotiated sessions XXX */
- if (ss->ssl3 != NULL)
- return SECSuccess;
-
- ssl3 = PORT_ZNew(ssl3State); /* zero on purpose */
- if (ssl3 == NULL)
- return SECFailure; /* PORT_ZAlloc has set memory error code. */
-
- /* note that entire HandshakeState is zero, including the buffer */
- ssl3->policy = SSL_ALLOWED;
-
- ssl_GetSpecWriteLock(ss);
- ssl3->crSpec = ssl3->cwSpec = &ssl3->specs[0];
- ssl3->prSpec = ssl3->pwSpec = &ssl3->specs[1];
- ssl3->hs.rehandshake = PR_FALSE;
- ssl3_InitCipherSpec(ss, ssl3->crSpec);
- ssl3_InitCipherSpec(ss, ssl3->prSpec);
- ssl3->fortezza.tek = NULL;
-
- ssl3->hs.ws = (ss->sec->isServer) ? wait_client_hello : wait_server_hello;
- ssl_ReleaseSpecWriteLock(ss);
-
- /*
- * note: We should probably lookup an SSL3 slot for these
- * handshake hashes in hopes that we wind up with the same slots
- * that the master secret will wind up in ...
- */
- SSL_TRC(30,("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));
- ssl3->hs.md5 = md5 = PK11_CreateDigestContext(SEC_OID_MD5);
- if (md5 == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- goto loser;
- }
- rv = PK11_DigestBegin(ssl3->hs.md5);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- goto loser;
- }
-
- sha = ssl3->hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (sha == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- goto loser;
- }
- rv = PK11_DigestBegin(ssl3->hs.sha);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- goto loser;
- }
-
- /* Don't hide this from the rest of the world any more. */
- ss->ssl3 = ssl3;
-
- return SECSuccess;
-
-loser:
- if (md5 != NULL) PK11_DestroyContext(md5, PR_TRUE);
- if (sha != NULL) PK11_DestroyContext(sha, PR_TRUE);
- if (ssl3 != NULL) PORT_Free(ssl3);
- return SECFailure;
-}
-
-/* Returns a reference counted object that contains a key pair.
- * Or NULL on failure. Initial ref count is 1.
- * Uses the keys in the pair as input.
- */
-ssl3KeyPair *
-ssl3_NewKeyPair( SECKEYPrivateKey * privKey, SECKEYPublicKey * pubKey)
-{
- ssl3KeyPair * pair;
-
- if (!privKey || !pubKey) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return NULL;
- }
- pair = PORT_ZNew(ssl3KeyPair);
- if (!pair)
- return NULL; /* error code is set. */
- pair->refCount = 1;
- pair->privKey = privKey;
- pair->pubKey = pubKey;
- return pair; /* success */
-}
-
-ssl3KeyPair *
-ssl3_GetKeyPairRef(ssl3KeyPair * keyPair)
-{
- PR_AtomicIncrement(&keyPair->refCount);
- return keyPair;
-}
-
-void
-ssl3_FreeKeyPair(ssl3KeyPair * keyPair)
-{
- PRInt32 newCount = PR_AtomicDecrement(&keyPair->refCount);
- if (!newCount) {
- SECKEY_DestroyPrivateKey(keyPair->privKey);
- SECKEY_DestroyPublicKey( keyPair->pubKey);
- PORT_Free(keyPair);
- }
-}
-
-
-#define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
-
-/*
- * Creates the public and private RSA keys for SSL Step down.
- * Called from SSL_ConfigSecureServer in sslsecur.c
- */
-SECStatus
-ssl3_CreateRSAStepDownKeys(sslSocket *ss)
-{
- SECStatus rv = SECSuccess;
- SECKEYPrivateKey * privKey; /* RSA step down key */
- SECKEYPublicKey * pubKey; /* RSA step down key */
-
- if (ss->stepDownKeyPair)
- ssl3_FreeKeyPair(ss->stepDownKeyPair);
- ss->stepDownKeyPair = NULL;
-#ifndef HACKED_EXPORT_SERVER
- /* Sigh, should have a get key strength call for private keys */
- if (PK11_GetPrivateModulusLen(ss->serverKey[kt_rsa]) >
- EXPORT_RSA_KEY_LENGTH) {
- /* need to ask for the key size in bits */
- privKey = SECKEY_CreateRSAPrivateKey(EXPORT_RSA_KEY_LENGTH * BPB,
- &pubKey, NULL);
- if (!privKey || !pubKey ||
- !(ss->stepDownKeyPair = ssl3_NewKeyPair(privKey, pubKey))) {
- ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
- rv = SECFailure;
- }
- }
-#endif
- return rv;
-}
-
-
-/* record the export policy for this cipher suite */
-SECStatus
-ssl3_SetPolicy(ssl3CipherSuite which, int policy)
-{
- ssl3CipherSuiteCfg *suite;
-
- suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
- if (suite == NULL) {
- return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
- }
- suite->policy = policy;
-
- if (policy == SSL_RESTRICTED) {
- ssl3_global_policy_some_restricted = PR_TRUE;
- }
-
- return SECSuccess;
-}
-
-SECStatus
-ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *oPolicy)
-{
- ssl3CipherSuiteCfg *suite;
- PRInt32 policy;
- SECStatus rv;
-
- suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
- if (suite) {
- policy = suite->policy;
- rv = SECSuccess;
- } else {
- policy = SSL_NOT_ALLOWED;
- rv = SECFailure; /* err code was set by Lookup. */
- }
- *oPolicy = policy;
- return rv;
-}
-
-/* record the user preference for this suite */
-SECStatus
-ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool enabled)
-{
- ssl3CipherSuiteCfg *suite;
-
- suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
- if (suite == NULL) {
- return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
- }
- suite->enabled = enabled;
- return SECSuccess;
-}
-
-/* return the user preference for this suite */
-SECStatus
-ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *enabled)
-{
- ssl3CipherSuiteCfg *suite;
- PRBool pref;
- SECStatus rv;
-
- suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
- if (suite) {
- pref = suite->enabled;
- rv = SECSuccess;
- } else {
- pref = SSL_NOT_ALLOWED;
- rv = SECFailure; /* err code was set by Lookup. */
- }
- *enabled = pref;
- return rv;
-}
-
-SECStatus
-ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool enabled)
-{
- ssl3CipherSuiteCfg *suite;
-
- suite = ssl_LookupCipherSuiteCfg(which, ss->cipherSuites);
- if (suite == NULL) {
- return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
- }
- suite->enabled = enabled;
- return SECSuccess;
-}
-
-SECStatus
-ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *enabled)
-{
- ssl3CipherSuiteCfg *suite;
- PRBool pref;
- SECStatus rv;
-
- suite = ssl_LookupCipherSuiteCfg(which, ss->cipherSuites);
- if (suite) {
- pref = suite->enabled;
- rv = SECSuccess;
- } else {
- pref = SSL_NOT_ALLOWED;
- rv = SECFailure; /* err code was set by Lookup. */
- }
- *enabled = pref;
- return rv;
-}
-
-/* copy global default policy into socket. */
-void
-ssl3_InitSocketPolicy(sslSocket *ss)
-{
- PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites);
-}
-
-/* ssl3_config_match_init must have already been called by
- * the caller of this function.
- */
-SECStatus
-ssl3_ConstructV2CipherSpecsHack(sslSocket *ss, unsigned char *cs, int *size)
-{
- int i, count = 0;
-
- PORT_Assert(ss != 0);
- if (!ss) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- if (!ss->enableSSL3 && !ss->enableTLS) {
- *size = 0;
- return SECSuccess;
- }
- if (cs == NULL) {
- *size = count_cipher_suites(ss, SSL_ALLOWED, PR_TRUE);
- return SECSuccess;
- }
-
- /* ssl3_config_match_init was called by the caller of this function. */
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if (config_match(suite, SSL_ALLOWED, PR_TRUE)) {
- if (cs != NULL) {
- *cs++ = 0x00;
- *cs++ = (suite->cipher_suite >> 8) & 0xFF;
- *cs++ = suite->cipher_suite & 0xFF;
- }
- count++;
- }
- }
- *size = count;
- return SECSuccess;
-}
-
-/*
-** If ssl3 socket is connected and in idle state, then start a new handshake.
-** If flushCache is true, the SID cache will be flushed first, forcing a
-** "Full" handshake (not a session restart handshake), to be done.
-**
-** called from SSL_RedoHandshake(), which already holds the handshake locks.
-*/
-SECStatus
-ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache)
-{
- sslSecurityInfo *sec = ss->sec;
- sslSessionID * sid = ss->sec->ci.sid;
- SECStatus rv;
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- if (!ss->connected ||
- ((ss->version >= SSL_LIBRARY_VERSION_3_0) &&
- ss->ssl3 && (ss->ssl3->hs.ws != idle_handshake))) {
- PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
- return SECFailure;
- }
- if (sid && flushCache) {
- sec->uncache(sid); /* remove it from whichever cache it's in. */
- ssl_FreeSID(sid); /* dec ref count and free if zero. */
- ss->sec->ci.sid = NULL;
- }
-
- ssl_GetXmitBufLock(ss); /**************************************/
-
- /* start off a new handshake. */
- rv = (sec->isServer) ? ssl3_SendHelloRequest(ss)
- : ssl3_SendClientHello(ss);
-
- ssl_ReleaseXmitBufLock(ss); /**************************************/
- return rv;
-}
-
-/* Called from ssl_FreeSocket() in sslsock.c */
-void
-ssl3_DestroySSL3Info(ssl3State *ssl3)
-{
- if (ssl3 == NULL)
- return; /* success the easy way. */
-
- if (ssl3->clientCertificate != NULL)
- CERT_DestroyCertificate(ssl3->clientCertificate);
-
- if (ssl3->clientPrivateKey != NULL)
- SECKEY_DestroyPrivateKey(ssl3->clientPrivateKey);
-
- if (ssl3->peerCertArena != NULL)
- ssl3_CleanupPeerCerts(ssl3);
-
- /* clean up handshake */
- if (ssl3->hs.md5) {
- PK11_DestroyContext(ssl3->hs.md5,PR_TRUE);
- }
- if (ssl3->hs.sha) {
- PK11_DestroyContext(ssl3->hs.sha,PR_TRUE);
- }
-
- if (ssl3->fortezza.tek != NULL) {
- PK11_FreeSymKey(ssl3->fortezza.tek);
- }
- /* free the SSL3Buffer (msg_body) */
- PORT_Free(ssl3->hs.msg_body.buf);
-
- /* free up the CipherSpecs */
- ssl3_DestroyCipherSpec(&ssl3->specs[0]);
- ssl3_DestroyCipherSpec(&ssl3->specs[1]);
-
- PORT_Free(ssl3);
-}
-
-/* End of ssl3con.c */
diff --git a/security/nss/lib/ssl/ssl3gthr.c b/security/nss/lib/ssl/ssl3gthr.c
deleted file mode 100644
index b3f05d83a..000000000
--- a/security/nss/lib/ssl/ssl3gthr.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Gather (Read) entire SSL3 records from socket into buffer.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "ssl3prot.h"
-
-/*
- * Attempt to read in an entire SSL3 record.
- * Blocks here for blocking sockets, otherwise returns -1 with
- * PR_WOULD_BLOCK_ERROR when socket would block.
- *
- * returns 1 if received a complete SSL3 record.
- * returns 0 if recv returns EOF
- * returns -1 if recv returns <0
- * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
- *
- * Caller must hold the recv buf lock.
- *
- * The Gather state machine has 3 states: GS_INIT, GS_HEADER, GS_DATA.
- * GS_HEADER: waiting for the 5-byte SSL3 record header to come in.
- * GS_DATA: waiting for the body of the SSL3 record to come in.
- *
- * This loop returns when either (a) an error or EOF occurs,
- * (b) PR_WOULD_BLOCK_ERROR,
- * (c) data (entire SSL3 record) has been received.
- */
-static int
-ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
-{
- unsigned char *bp;
- unsigned char *lbp;
- int nb;
- int err;
- int rv = 1;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- if (gs->state == GS_INIT) {
- gs->state = GS_HEADER;
- gs->remainder = 5;
- gs->offset = 0;
- gs->writeOffset = 0;
- gs->readOffset = 0;
- }
-
- lbp = gs->inbuf.buf;
- for(;;) {
- SSL_TRC(30, ("%d: SSL3[%d]: gather state %d (need %d more)",
- SSL_GETPID(), ss->fd, gs->state, gs->remainder));
- bp = ((gs->state != GS_HEADER) ? lbp : gs->hdr) + gs->offset;
- nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
-
- if (nb > 0) {
- PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
- } else if (nb == 0) {
- /* EOF */
- SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
- rv = 0;
- break;
- } else /* if (nb < 0) */ {
- SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
- PR_GetError()));
- rv = SECFailure;
- break;
- }
-
- gs->offset += nb;
- gs->inbuf.len += nb;
- gs->remainder -= nb;
-
- /* if there's more to go, read some more. */
- if (gs->remainder > 0) {
- continue;
- }
-
- /* have received entire record header, or entire record. */
- switch (gs->state) {
- case GS_HEADER:
- /*
- ** Have received SSL3 record header in gs->hdr.
- ** Now extract the length of the following encrypted data,
- ** and then read in the rest of the SSL3 record into gs->inbuf.
- */
- gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
-
- /* This is the max fragment length for an encrypted fragment
- ** plus the size of the record header.
- */
- if(gs->remainder > (MAX_FRAGMENT_LENGTH + 2048 + 5)) {
- SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- gs->state = GS_INIT;
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
- return SECFailure;
- }
-
- gs->state = GS_DATA;
- gs->offset = 0;
- gs->inbuf.len = 0;
-
- if (gs->remainder > gs->inbuf.space) {
- err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
- if (err) { /* realloc has set error code to no mem. */
- return err;
- }
- lbp = gs->inbuf.buf;
- }
- break; /* End this case. Continue around the loop. */
-
-
- case GS_DATA:
- /*
- ** SSL3 record has been completely received.
- */
- gs->state = GS_INIT;
- return 1;
- }
- }
-
- return rv;
-}
-
-/* Gather in a record and when complete, Handle that record.
- * Repeat this until the handshake is complete,
- * or until application data is available.
- *
- * Returns 1 when the handshake is completed without error, or
- * application data is available.
- * Returns 0 if ssl3_GatherData hits EOF.
- * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
- * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
- *
- * Called from ssl_GatherRecord1stHandshake in sslcon.c,
- * and from SSL_ForceHandshake in sslsecur.c
- * and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c).
- *
- * Caller must hold the recv buf lock.
- */
-int
-ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
-{
- sslGather * gs = ss->gather;
- SSL3Ciphertext cText;
- int rv;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- do {
- /* bring in the next sslv3 record. */
- rv = ssl3_GatherData(ss, gs, flags);
- if (rv <= 0) {
- return rv;
- }
-
- /* decipher it, and handle it if it's a handshake.
- * If it's application data, gs->buf will not be empty upon return.
- */
- cText.type = (SSL3ContentType)gs->hdr[0];
- cText.version = (gs->hdr[1] << 8) | gs->hdr[2];
- cText.buf = &gs->inbuf;
- rv = ssl3_HandleRecord(ss, &cText, &gs->buf);
- if (rv < 0) {
- return ss->recvdCloseNotify ? 0 : rv;
- }
- } while (ss->ssl3->hs.ws != idle_handshake && gs->buf.len == 0);
-
- gs->readOffset = 0;
- gs->writeOffset = gs->buf.len;
- return 1;
-}
-
-/* Repeatedly gather in a record and when complete, Handle that record.
- * Repeat this until some application data is received.
- *
- * Returns 1 when application data is available.
- * Returns 0 if ssl3_GatherData hits EOF.
- * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
- * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
- *
- * Called from DoRecv in sslsecur.c
- * Caller must hold the recv buf lock.
- */
-int
-ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
-{
- sslGather * gs = ss->gather;
- int rv;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- do {
- rv = ssl3_GatherCompleteHandshake(ss, flags);
- } while (rv > 0 && gs->buf.len == 0);
-
- return rv;
-}
diff --git a/security/nss/lib/ssl/ssl3prot.h b/security/nss/lib/ssl/ssl3prot.h
deleted file mode 100644
index a9162d9b3..000000000
--- a/security/nss/lib/ssl/ssl3prot.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Various and sundry protocol constants. DON'T CHANGE THESE. These
- * values are defined by the SSL 3.0 protocol specification.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#ifndef __ssl3proto_h_
-#define __ssl3proto_h_
-
-typedef uint8 SSL3Opaque;
-
-typedef uint16 SSL3ProtocolVersion;
-/* version numbers are defined in sslproto.h */
-
-typedef uint16 ssl3CipherSuite;
-/* The cipher suites are defined in sslproto.h */
-
-#define MAX_CERT_TYPES 10
-#define MAX_COMPRESSION_METHODS 10
-#define MAX_MAC_LENGTH 64
-#define MAX_PADDING_LENGTH 64
-#define MAX_KEY_LENGTH 64
-#define EXPORT_KEY_LENGTH 5
-#define SSL3_RANDOM_LENGTH 32
-
-#define SSL3_RECORD_HEADER_LENGTH 5
-
-#define MAX_FRAGMENT_LENGTH 16384
-
-typedef enum {
- content_change_cipher_spec = 20,
- content_alert = 21,
- content_handshake = 22,
- content_application_data = 23
-} SSL3ContentType;
-
-typedef struct {
- SSL3ContentType type;
- SSL3ProtocolVersion version;
- uint16 length;
- SECItem fragment;
-} SSL3Plaintext;
-
-typedef struct {
- SSL3ContentType type;
- SSL3ProtocolVersion version;
- uint16 length;
- SECItem fragment;
-} SSL3Compressed;
-
-typedef struct {
- SECItem content;
- SSL3Opaque MAC[MAX_MAC_LENGTH];
-} SSL3GenericStreamCipher;
-
-typedef struct {
- SECItem content;
- SSL3Opaque MAC[MAX_MAC_LENGTH];
- uint8 padding[MAX_PADDING_LENGTH];
- uint8 padding_length;
-} SSL3GenericBlockCipher;
-
-typedef enum { change_cipher_spec_choice = 1 } SSL3ChangeCipherSpecChoice;
-
-typedef struct {
- SSL3ChangeCipherSpecChoice choice;
-} SSL3ChangeCipherSpec;
-
-typedef enum { alert_warning = 1, alert_fatal = 2 } SSL3AlertLevel;
-
-typedef enum {
- close_notify = 0,
- unexpected_message = 10,
- bad_record_mac = 20,
- decryption_failed = 21, /* TLS only */
- record_overflow = 22, /* TLS only */
- decompression_failure = 30,
- handshake_failure = 40,
- no_certificate = 41, /* SSL3 only, NOT TLS */
- bad_certificate = 42,
- unsupported_certificate = 43,
- certificate_revoked = 44,
- certificate_expired = 45,
- certificate_unknown = 46,
- illegal_parameter = 47,
-
-/* All alerts below are TLS only. */
- unknown_ca = 48,
- access_denied = 49,
- decode_error = 50,
- decrypt_error = 51,
- export_restriction = 60,
- protocol_version = 70,
- insufficient_security = 71,
- internal_error = 80,
- user_canceled = 90,
- no_renegotiation = 100
-
-} SSL3AlertDescription;
-
-typedef struct {
- SSL3AlertLevel level;
- SSL3AlertDescription description;
-} SSL3Alert;
-
-typedef enum {
- hello_request = 0,
- client_hello = 1,
- server_hello = 2,
- certificate = 11,
- server_key_exchange = 12,
- certificate_request = 13,
- server_hello_done = 14,
- certificate_verify = 15,
- client_key_exchange = 16,
- finished = 20
-} SSL3HandshakeType;
-
-typedef struct {
- uint8 empty;
-} SSL3HelloRequest;
-
-typedef struct {
- SSL3Opaque rand[SSL3_RANDOM_LENGTH];
-} SSL3Random;
-
-typedef struct {
- SSL3Opaque id[32];
- uint8 length;
-} SSL3SessionID;
-
-typedef enum { compression_null = 0 } SSL3CompressionMethod;
-
-typedef struct {
- SSL3ProtocolVersion client_version;
- SSL3Random random;
- SSL3SessionID session_id;
- SECItem cipher_suites;
- uint8 cm_count;
- SSL3CompressionMethod compression_methods[MAX_COMPRESSION_METHODS];
-} SSL3ClientHello;
-
-typedef struct {
- SSL3ProtocolVersion server_version;
- SSL3Random random;
- SSL3SessionID session_id;
- ssl3CipherSuite cipher_suite;
- SSL3CompressionMethod compression_method;
-} SSL3ServerHello;
-
-typedef struct {
- SECItem list;
-} SSL3Certificate;
-
-typedef enum {
- sign_null, sign_rsa, sign_dsa
-} SSL3SignType;
-
-/* The SSL key exchange method used */
-typedef enum {
- kea_null,
- kea_rsa,
- kea_rsa_export,
- kea_rsa_export_1024,
- kea_dh_dss,
- kea_dh_dss_export,
- kea_dh_rsa,
- kea_dh_rsa_export,
- kea_dhe_dss,
- kea_dhe_dss_export,
- kea_dhe_rsa,
- kea_dhe_rsa_export,
- kea_dh_anon,
- kea_dh_anon_export,
- kea_fortezza,
- kea_rsa_fips
-} SSL3KeyExchangeAlgorithm;
-
-typedef struct {
- SECItem modulus;
- SECItem exponent;
-} SSL3ServerRSAParams;
-
-typedef struct {
- SECItem p;
- SECItem g;
- SECItem Ys;
-} SSL3ServerDHParams;
-
-typedef struct {
- union {
- SSL3ServerDHParams dh;
- SSL3ServerRSAParams rsa;
- } u;
-} SSL3ServerParams;
-
-typedef struct {
- uint8 md5[16];
- uint8 sha[20];
-} SSL3Hashes;
-
-typedef struct {
- union {
- SSL3Opaque anonymous;
- SSL3Hashes certified;
- } u;
-} SSL3ServerKeyExchange;
-
-typedef enum {
- ct_RSA_sign = 1,
- ct_DSS_sign = 2,
- ct_RSA_fixed_DH = 3,
- ct_DSS_fixed_DH = 4,
- ct_RSA_ephemeral_DH = 5,
- ct_DSS_ephemeral_DH = 6,
- ct_Fortezza = 20
-} SSL3ClientCertificateType;
-
-typedef SECItem *SSL3DistinquishedName;
-
-typedef struct {
- SSL3Opaque client_version[2];
- SSL3Opaque random[46];
-} SSL3RSAPreMasterSecret;
-
-typedef SECItem SSL3EncryptedPreMasterSecret;
-
-/* Following struct is the format of a Fortezza ClientKeyExchange message. */
-typedef struct {
- SECItem y_c;
- SSL3Opaque r_c [128];
- SSL3Opaque y_signature [40];
- SSL3Opaque wrapped_client_write_key [12];
- SSL3Opaque wrapped_server_write_key [12];
- SSL3Opaque client_write_iv [24];
- SSL3Opaque server_write_iv [24];
- SSL3Opaque master_secret_iv [24];
- SSL3Opaque encrypted_preMasterSecret[48];
-} SSL3FortezzaKeys;
-
-typedef SSL3Opaque SSL3MasterSecret[48];
-
-typedef enum { implicit, explicit } SSL3PublicValueEncoding;
-
-typedef struct {
- union {
- SSL3Opaque implicit;
- SECItem explicit;
- } dh_public;
-} SSL3ClientDiffieHellmanPublic;
-
-typedef struct {
- union {
- SSL3EncryptedPreMasterSecret rsa;
- SSL3ClientDiffieHellmanPublic diffie_helman;
- SSL3FortezzaKeys fortezza;
- } exchange_keys;
-} SSL3ClientKeyExchange;
-
-typedef SSL3Hashes SSL3PreSignedCertificateVerify;
-
-typedef SECItem SSL3CertificateVerify;
-
-typedef enum {
- sender_client = 0x434c4e54,
- sender_server = 0x53525652
-} SSL3Sender;
-
-typedef SSL3Hashes SSL3Finished;
-
-typedef struct {
- SSL3Opaque verify_data[12];
-} TLSFinished;
-
-#endif /* __ssl3proto_h_ */
diff --git a/security/nss/lib/ssl/sslauth.c b/security/nss/lib/ssl/sslauth.c
deleted file mode 100644
index 7b7fad11e..000000000
--- a/security/nss/lib/ssl/sslauth.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-#include "cert.h"
-#include "secitem.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "pk11func.h"
-
-/* NEED LOCKS IN HERE. */
-CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd)
-{
- sslSocket *ss;
- sslSecurityInfo *sec;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
- SSL_GETPID(), fd));
- return 0;
- }
- sec = ss->sec;
- if (ss->useSecurity && sec && sec->peerCert) {
- return CERT_DupCertificate(sec->peerCert);
- }
- return 0;
-}
-
-/* NEED LOCKS IN HERE. */
-int
-SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1,
- char **ip, char **sp)
-{
- sslSocket *ss;
- sslSecurityInfo *sec;
- const char *cipherName;
- PRBool isDes = PR_FALSE;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SecurityStatus",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (cp) *cp = 0;
- if (kp0) *kp0 = 0;
- if (kp1) *kp1 = 0;
- if (ip) *ip = 0;
- if (sp) *sp = 0;
- if (op) {
- *op = SSL_SECURITY_STATUS_OFF;
- }
-
- if (ss->useSecurity && ss->connected) {
- PORT_Assert(ss->sec != 0);
- sec = ss->sec;
-
- if (ss->version < SSL_LIBRARY_VERSION_3_0) {
- cipherName = ssl_cipherName[sec->cipherType];
- } else {
- cipherName = ssl3_cipherName[sec->cipherType];
- }
- if (cipherName && PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE;
- /* do same key stuff for fortezza */
-
- if (cp) {
- *cp = PORT_Strdup(cipherName);
- }
-
- if (kp0) {
- *kp0 = sec->keyBits;
- if (isDes) *kp0 = (*kp0 * 7) / 8;
- }
- if (kp1) {
- *kp1 = sec->secretKeyBits;
- if (isDes) *kp1 = (*kp1 * 7) / 8;
- }
- if (op) {
- if (sec->keyBits == 0) {
- *op = SSL_SECURITY_STATUS_OFF;
- } else if (sec->secretKeyBits < 90) {
- *op = SSL_SECURITY_STATUS_ON_LOW;
-
- } else {
- *op = SSL_SECURITY_STATUS_ON_HIGH;
- }
- }
-
- if (ip || sp) {
- CERTCertificate *cert;
-
- cert = sec->peerCert;
- if (cert) {
- if (ip) {
- *ip = CERT_NameToAscii(&cert->issuer);
- }
- if (sp) {
- *sp = CERT_NameToAscii(&cert->subject);
- }
- } else {
- if (ip) {
- *ip = PORT_Strdup("no certificate");
- }
- if (sp) {
- *sp = PORT_Strdup("no certificate");
- }
- }
- }
- }
-
- return 0;
-}
-
-/************************************************************************/
-
-/* NEED LOCKS IN HERE. */
-int
-SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_FindSocket(s);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in AuthCertificateHook",
- SSL_GETPID(), s));
- return SECFailure;
- }
-
- if ((rv = ssl_CreateSecurityInfo(ss)) != 0) {
- return(rv);
- }
- ss->authCertificate = func;
- ss->authCertificateArg = arg;
-
- return(0);
-}
-
-/* NEED LOCKS IN HERE. */
-int
-SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func,
- void *arg)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_FindSocket(s);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
- SSL_GETPID(), s));
- return SECFailure;
- }
-
- if ((rv = ssl_CreateSecurityInfo(ss)) != 0) {
- return rv;
- }
- ss->getClientAuthData = func;
- ss->getClientAuthDataArg = arg;
- return 0;
-}
-
-/* NEED LOCKS IN HERE. */
-int
-SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_FindSocket(s);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
- SSL_GETPID(), s));
- return SECFailure;
- }
-
- if ((rv = ssl_CreateSecurityInfo(ss)) != 0) {
- return rv;
- }
- ss->pkcs11PinArg = arg;
- return 0;
-}
-
-
-/* This is the "default" authCert callback function. It is called when a
- * certificate message is received from the peer and the local application
- * has not registered an authCert callback function.
- */
-int
-SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
-{
- SECStatus rv;
- CERTCertDBHandle * handle;
- sslSocket * ss;
- SECCertUsage certUsage;
- char * hostname = NULL;
-
- ss = ssl_FindSocket(fd);
- PORT_Assert(ss != NULL);
-
- handle = (CERTCertDBHandle *)arg;
-
- /* this may seem backwards, but isn't. */
- certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;
-
- rv = CERT_VerifyCertNow(handle, ss->sec->peerCert, checkSig, certUsage,
- ss->pkcs11PinArg);
-
- if ( rv != SECSuccess || isServer )
- return rv;
-
- /* cert is OK. This is the client side of an SSL connection.
- * Now check the name field in the cert against the desired hostname.
- * NB: This is our only defense against Man-In-The-Middle (MITM) attacks!
- */
- hostname = ss->url;
- if (hostname && hostname[0])
- rv = CERT_VerifyCertName(ss->sec->peerCert, hostname);
- else
- rv = SECFailure;
- if (rv != SECSuccess)
- PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
-
- return rv;
-}
diff --git a/security/nss/lib/ssl/sslcon.c b/security/nss/lib/ssl/sslcon.c
deleted file mode 100644
index e4a3e3ecd..000000000
--- a/security/nss/lib/ssl/sslcon.c
+++ /dev/null
@@ -1,3683 +0,0 @@
-/*
- * SSL v2 handshake functions, and functions common to SSL2 and SSL3.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "cert.h"
-#include "secitem.h"
-#include "sechash.h"
-#include "cryptohi.h" /* for SGN_ funcs */
-#include "keyhi.h" /* for SECKEY_ high level functions. */
-#include "softoken.h" /* for RSA_FormatBlock */
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "ssl3prot.h"
-#include "sslerr.h"
-#include "pk11func.h"
-#include "prinit.h"
-#include "prtime.h" /* for PR_Now() */
-
-#define XXX
-
-static PRBool policyWasSet;
-
-/* This ordered list is indexed by (SSL_CK_xx * 3) */
-/* Second and third bytes are MSB and LSB of master key length. */
-static const PRUint8 allCipherSuites[] = {
- 0, 0, 0,
- SSL_CK_RC4_128_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC4_128_EXPORT40_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC2_128_CBC_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80,
- SSL_CK_IDEA_128_CBC_WITH_MD5, 0x00, 0x80,
- SSL_CK_DES_64_CBC_WITH_MD5, 0x00, 0x40,
- SSL_CK_DES_192_EDE3_CBC_WITH_MD5, 0x00, 0xC0,
- 0, 0, 0
-};
-
-#define ssl2_NUM_SUITES_IMPLEMENTED 6
-
-/* This list is sent back to the client when the client-hello message
- * contains no overlapping ciphers, so the client can report what ciphers
- * are supported by the server. Unlike allCipherSuites (above), this list
- * is sorted by descending preference, not by cipherSuite number.
- */
-static const PRUint8 implementedCipherSuites[ssl2_NUM_SUITES_IMPLEMENTED * 3] = {
- SSL_CK_RC4_128_WITH_MD5, 0x00, 0x80,
- SSL_CK_DES_192_EDE3_CBC_WITH_MD5, 0x00, 0xC0,
- SSL_CK_RC2_128_CBC_WITH_MD5, 0x00, 0x80,
- SSL_CK_DES_64_CBC_WITH_MD5, 0x00, 0x40,
- SSL_CK_RC4_128_EXPORT40_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80
-};
-
-typedef struct ssl2SpecsStr {
- PRUint8 nkm; /* do this many hashes to generate key material. */
- PRUint8 nkd; /* size of readKey and writeKey in bytes. */
- PRUint8 blockSize;
- PRUint8 blockShift;
- CK_MECHANISM_TYPE mechanism;
- PRUint8 keyLen; /* cipher symkey size in bytes. */
- PRUint8 pubLen; /* publicly reveal this many bytes of key. */
- PRUint8 ivLen; /* length of IV data at *ca. */
-} ssl2Specs;
-
-static const ssl2Specs ssl_Specs[] = {
-/* NONE */
- { 0, 0, 0, 0, },
-/* SSL_CK_RC4_128_WITH_MD5 */
- { 2, 16, 1, 0, CKM_RC4, 16, 0, 0, },
-/* SSL_CK_RC4_128_EXPORT40_WITH_MD5 */
- { 2, 16, 1, 0, CKM_RC4, 16, 11, 0, },
-/* SSL_CK_RC2_128_CBC_WITH_MD5 */
- { 2, 16, 8, 3, CKM_RC2_CBC, 16, 0, 8, },
-/* SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 */
- { 2, 16, 8, 3, CKM_RC2_CBC, 16, 11, 8, },
-/* SSL_CK_IDEA_128_CBC_WITH_MD5 */
- { 0, 0, 0, 0, },
-/* SSL_CK_DES_64_CBC_WITH_MD5 */
- { 1, 8, 8, 3, CKM_DES_CBC, 8, 0, 8, },
-/* SSL_CK_DES_192_EDE3_CBC_WITH_MD5 */
- { 3, 24, 8, 3, CKM_DES3_CBC, 24, 0, 8, },
-};
-
-#define SET_ERROR_CODE /* reminder */
-#define TEST_FOR_FAILURE /* reminder */
-
-/*
-** Put a string tag in the library so that we can examine an executable
-** and see what kind of security it supports.
-*/
-const char *ssl_version = "SECURITY_VERSION:"
- " +us"
- " +export"
-#ifdef TRACE
- " +trace"
-#endif
-#ifdef DEBUG
- " +debug"
-#endif
- ;
-
-const char * const ssl_cipherName[] = {
- "unknown",
- "RC4",
- "RC4-Export",
- "RC2-CBC",
- "RC2-CBC-Export",
- "IDEA-CBC",
- "DES-CBC",
- "DES-EDE3-CBC",
- "unknown",
- "Fortezza",
-};
-
-
-/* bit-masks, showing which SSLv2 suites are allowed.
- * lsb corresponds to first cipher suite in allCipherSuites[].
- */
-static PRUint16 allowedByPolicy; /* all off by default */
-static PRUint16 maybeAllowedByPolicy; /* all off by default */
-static PRUint16 chosenPreference = 0xff; /* all on by default */
-
-/* bit values for the above two bit masks */
-#define SSL_CB_RC4_128_WITH_MD5 (1 << SSL_CK_RC4_128_WITH_MD5)
-#define SSL_CB_RC4_128_EXPORT40_WITH_MD5 (1 << SSL_CK_RC4_128_EXPORT40_WITH_MD5)
-#define SSL_CB_RC2_128_CBC_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_WITH_MD5)
-#define SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)
-#define SSL_CB_IDEA_128_CBC_WITH_MD5 (1 << SSL_CK_IDEA_128_CBC_WITH_MD5)
-#define SSL_CB_DES_64_CBC_WITH_MD5 (1 << SSL_CK_DES_64_CBC_WITH_MD5)
-#define SSL_CB_DES_192_EDE3_CBC_WITH_MD5 (1 << SSL_CK_DES_192_EDE3_CBC_WITH_MD5)
-#define SSL_CB_IMPLEMENTED \
- (SSL_CB_RC4_128_WITH_MD5 | \
- SSL_CB_RC4_128_EXPORT40_WITH_MD5 | \
- SSL_CB_RC2_128_CBC_WITH_MD5 | \
- SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 | \
- SSL_CB_DES_64_CBC_WITH_MD5 | \
- SSL_CB_DES_192_EDE3_CBC_WITH_MD5)
-
-
-/* Construct a socket's list of cipher specs from the global default values.
- */
-static SECStatus
-ssl2_ConstructCipherSpecs(sslSocket *ss)
-{
- PRUint8 * cs = NULL;
- unsigned int allowed;
- unsigned int count;
- int ssl3_count = 0;
- int final_count;
- int i;
- SECStatus rv;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
-
- count = 0;
- PORT_Assert(ss != 0);
- allowed = !ss->enableSSL2 ? 0 :
- (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
- while (allowed) {
- if (allowed & 1)
- ++count;
- allowed >>= 1;
- }
-
- /* Call ssl3_config_match_init() once here,
- * instead of inside ssl3_ConstructV2CipherSpecsHack(),
- * because the latter gets called twice below,
- * and then again in ssl2_BeginClientHandshake().
- */
- ssl3_config_match_init(ss);
-
- /* ask SSL3 how many cipher suites it has. */
- rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3_count);
- if (rv < 0)
- return rv;
- count += ssl3_count;
-
- /* Allocate memory to hold cipher specs */
- if (count > 0)
- cs = (PRUint8*) PORT_Alloc(count * 3);
- else
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- if (cs == NULL)
- return SECFailure;
-
- if (ss->cipherSpecs != NULL) {
- PORT_Free(ss->cipherSpecs);
- }
- ss->cipherSpecs = cs;
- ss->sizeCipherSpecs = count * 3;
-
- /* fill in cipher specs for SSL2 cipher suites */
- allowed = !ss->enableSSL2 ? 0 :
- (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
- for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) {
- const PRUint8 * hs = implementedCipherSuites + i;
- int ok = allowed & (1U << hs[0]);
- if (ok) {
- cs[0] = hs[0];
- cs[1] = hs[1];
- cs[2] = hs[2];
- cs += 3;
- }
- }
-
- /* now have SSL3 add its suites onto the end */
- rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count);
-
- /* adjust for any difference between first pass and second pass */
- ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3;
-
- return rv;
-}
-
-/* This function is called immediately after ssl2_ConstructCipherSpecs()
-** at the beginning of a handshake. It detects cases where a protocol
-** (e.g. SSL2 or SSL3) is logically enabled, but all its cipher suites
-** for that protocol have been disabled. If such cases, it clears the
-** enable bit for the protocol. If no protocols remain enabled, or
-** if no cipher suites are found, it sets the error code and returns
-** SECFailure, otherwise it returns SECSuccess.
-*/
-static SECStatus
-ssl2_CheckConfigSanity(sslSocket *ss)
-{
- unsigned int allowed;
- int ssl3CipherCount = 0;
- SECStatus rv;
-
- /* count the SSL2 and SSL3 enabled ciphers.
- * if either is zero, clear the socket's enable for that protocol.
- */
- if (!ss->cipherSpecs)
- goto disabled;
-
- allowed = ss->allowedByPolicy & ss->chosenPreference;
- if (! allowed)
- ss->enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */
-
- /* ssl3_config_match_init was called in ssl2_ConstructCipherSpecs(). */
- /* Ask how many ssl3 CipherSuites were enabled. */
- rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3CipherCount);
- if (rv != SECSuccess || ssl3CipherCount <= 0) {
- ss->enableSSL3 = PR_FALSE; /* not really enabled if no ciphers */
- ss->enableTLS = PR_FALSE;
- }
-
- if (!ss->enableSSL2 && !ss->enableSSL3 && !ss->enableTLS) {
- SSL_DBG(("%d: SSL[%d]: Can't handshake! both v2 and v3 disabled.",
- SSL_GETPID(), ss->fd));
-disabled:
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * Since this is a global (not per-socket) setting, we cannot use the
- * HandshakeLock to protect this. Probably want a global lock.
- */
-SECStatus
-ssl2_SetPolicy(PRInt32 which, PRInt32 policy)
-{
- PRUint32 bitMask;
- SECStatus rv = SECSuccess;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- return SECFailure;
- }
-
- if (policy == SSL_ALLOWED) {
- allowedByPolicy |= bitMask;
- maybeAllowedByPolicy |= bitMask;
- } else if (policy == SSL_RESTRICTED) {
- allowedByPolicy &= ~bitMask;
- maybeAllowedByPolicy |= bitMask;
- } else {
- allowedByPolicy &= ~bitMask;
- maybeAllowedByPolicy &= ~bitMask;
- }
- allowedByPolicy &= SSL_CB_IMPLEMENTED;
- maybeAllowedByPolicy &= SSL_CB_IMPLEMENTED;
-
- policyWasSet = PR_TRUE;
- return rv;
-}
-
-SECStatus
-ssl2_GetPolicy(PRInt32 which, PRInt32 *oPolicy)
-{
- PRUint32 bitMask;
- PRInt32 policy;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- /* Caller assures oPolicy is not null. */
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- *oPolicy = SSL_NOT_ALLOWED;
- return SECFailure;
- }
-
- if (maybeAllowedByPolicy & bitMask) {
- policy = (allowedByPolicy & bitMask) ? SSL_ALLOWED : SSL_RESTRICTED;
- } else {
- policy = SSL_NOT_ALLOWED;
- }
-
- *oPolicy = policy;
- return SECSuccess;
-}
-
-/*
- * Since this is a global (not per-socket) setting, we cannot use the
- * HandshakeLock to protect this. Probably want a global lock.
- * Called from SSL_CipherPrefSetDefault in sslsock.c
- * These changes have no effect on any sslSockets already created.
- */
-SECStatus
-ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
-{
- PRUint32 bitMask;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- return SECFailure;
- }
-
- if (enabled)
- chosenPreference |= bitMask;
- else
- chosenPreference &= ~bitMask;
- chosenPreference &= SSL_CB_IMPLEMENTED;
-
- return SECSuccess;
-}
-
-SECStatus
-ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
-{
- PRBool rv = PR_FALSE;
- PRUint32 bitMask;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- *enabled = PR_FALSE;
- return SECFailure;
- }
-
- rv = (PRBool)((chosenPreference & bitMask) != 0);
- *enabled = rv;
- return SECSuccess;
-}
-
-SECStatus
-ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled)
-{
- PRUint32 bitMask;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- return SECFailure;
- }
-
- if (enabled)
- ss->chosenPreference |= bitMask;
- else
- ss->chosenPreference &= ~bitMask;
- ss->chosenPreference &= SSL_CB_IMPLEMENTED;
-
- return SECSuccess;
-}
-
-SECStatus
-ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled)
-{
- PRBool rv = PR_FALSE;
- PRUint32 bitMask;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- *enabled = PR_FALSE;
- return SECFailure;
- }
-
- rv = (PRBool)((ss->chosenPreference & bitMask) != 0);
- *enabled = rv;
- return SECSuccess;
-}
-
-
-/* copy global default policy into socket. */
-void
-ssl2_InitSocketPolicy(sslSocket *ss)
-{
- ss->allowedByPolicy = allowedByPolicy;
- ss->maybeAllowedByPolicy = maybeAllowedByPolicy;
- ss->chosenPreference = chosenPreference;
-}
-
-
-/************************************************************************/
-
-/* Called from ssl2_CreateSessionCypher(), which already holds handshake lock.
- */
-static SECStatus
-ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey,
- int cipherChoice)
-{
- switch (cipherChoice) {
-
- case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
- case SSL_CK_RC2_128_CBC_WITH_MD5:
- case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
- case SSL_CK_RC4_128_WITH_MD5:
- case SSL_CK_DES_64_CBC_WITH_MD5:
- case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
- sec->hash = &SECHashObjects[HASH_AlgMD5];
- SECITEM_CopyItem(0, &sec->sendSecret, writeKey);
- SECITEM_CopyItem(0, &sec->rcvSecret, readKey);
- break;
-
- default:
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
- }
- sec->hashcx = (*sec->hash->create)();
- if (sec->hashcx == NULL)
- return SECFailure;
- return SECSuccess;
-}
-
-/************************************************************************
- * All the Send functions below must acquire and release the socket's
- * xmitBufLock.
- */
-
-/* Called from all the Send* functions below. */
-static SECStatus
-ssl2_GetSendBuffer(sslSocket *ss, unsigned int len)
-{
- sslConnectInfo *ci;
- SECStatus rv = SECSuccess;
-
- PORT_Assert((ss->sec != 0));
-
- PORT_Assert(ssl_HaveXmitBufLock(ss));
-
- ci = &ss->sec->ci;
-
- if (len < 128) {
- len = 128;
- }
- if (len > ci->sendBuf.space) {
- rv = sslBuffer_Grow(&ci->sendBuf, len);
- if (rv != SECSuccess) {
- SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d bytes",
- SSL_GETPID(), ss->fd, len));
- rv = SECFailure;
- }
- }
- return rv;
-}
-
-/* Called from:
- * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
- * ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() <-
- ssl_Do1stHandshake()
- * ssl2_HandleMessage() <- ssl_Do1stHandshake()
- * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake()
- after ssl2_BeginClientHandshake()
- * ssl2_RestartHandshakeAfterCertReq() <- Called from certdlgs.c in nav.
- * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake()
- after ssl2_BeginServerHandshake()
- *
- * Acquires and releases the socket's xmitBufLock.
- */
-int
-ssl2_SendErrorMessage(sslSocket *ss, int error)
-{
- sslSecurityInfo *sec;
- int rv;
- PRUint8 msg[SSL_HL_ERROR_HBYTES];
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- msg[0] = SSL_MT_ERROR;
- msg[1] = MSB(error);
- msg[2] = LSB(error);
-
- ssl_GetXmitBufLock(ss); /***************************************/
- sec = ss->sec;
-
- SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error));
-
- rv = (*sec->send)(ss, msg, sizeof(msg), 0);
- if (rv >= 0) {
- rv = SECSuccess;
- }
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from ssl2_TryToFinish().
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendClientFinishedMessage(sslSocket *ss)
-{
- sslSecurityInfo *sec;
- sslConnectInfo * ci;
- SECStatus rv = SECSuccess;
- int sent;
- PRUint8 msg[1 + SSL_CONNECTIONID_BYTES];
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- ssl_GetXmitBufLock(ss); /***************************************/
- sec = ss->sec;
- ci = &sec->ci;
-
- if (ci->sentFinished == 0) {
- ci->sentFinished = 1;
-
- SSL_TRC(3, ("%d: SSL[%d]: sending client-finished",
- SSL_GETPID(), ss->fd));
-
- msg[0] = SSL_MT_CLIENT_FINISHED;
- PORT_Memcpy(msg+1, ci->connectionID, sizeof(ci->connectionID));
-
- DUMP_MSG(29, (ss, msg, 1 + sizeof(ci->connectionID)));
- sent = (*sec->send)(ss, msg, 1 + sizeof(ci->connectionID), 0);
- rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
- }
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from
- * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage()
- * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake()
- after ssl2_BeginServerHandshake()
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendServerVerifyMessage(sslSocket *ss)
-{
- sslSecurityInfo *sec;
- sslConnectInfo * ci;
- PRUint8 * msg;
- int sendLen;
- int sent;
- SECStatus rv;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- ssl_GetXmitBufLock(ss); /***************************************/
- sec = ss->sec;
- ci = &sec->ci;
-
- sendLen = 1 + SSL_CHALLENGE_BYTES;
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv != SECSuccess) {
- goto done;
- }
-
- msg = ci->sendBuf.buf;
- msg[0] = SSL_MT_SERVER_VERIFY;
- PORT_Memcpy(msg+1, ci->clientChallenge, SSL_CHALLENGE_BYTES);
-
- DUMP_MSG(29, (ss, msg, sendLen));
- sent = (*sec->send)(ss, msg, sendLen, 0);
-
- rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
-
-done:
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from ssl2_TryToFinish().
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendServerFinishedMessage(sslSocket *ss)
-{
- sslSecurityInfo *sec;
- sslConnectInfo * ci;
- sslSessionID * sid;
- PRUint8 * msg;
- int sendLen, sent;
- SECStatus rv = SECSuccess;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- ssl_GetXmitBufLock(ss); /***************************************/
- sec = ss->sec;
- ci = &sec->ci;
-
- if (ci->sentFinished == 0) {
- ci->sentFinished = 1;
- PORT_Assert(ci->sid != 0);
- sid = ci->sid;
-
- SSL_TRC(3, ("%d: SSL[%d]: sending server-finished",
- SSL_GETPID(), ss->fd));
-
- sendLen = 1 + sizeof(sid->u.ssl2.sessionID);
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv != SECSuccess) {
- goto done;
- }
-
- msg = ci->sendBuf.buf;
- msg[0] = SSL_MT_SERVER_FINISHED;
- PORT_Memcpy(msg+1, sid->u.ssl2.sessionID,
- sizeof(sid->u.ssl2.sessionID));
-
- DUMP_MSG(29, (ss, msg, sendLen));
- sent = (*sec->send)(ss, msg, sendLen, 0);
-
- if (sent < 0) {
- /* If send failed, it is now a bogus session-id */
- (*sec->uncache)(sid);
- rv = (SECStatus)sent;
- } else if (!ss->noCache) {
- /* Put the sid in session-id cache, (may already be there) */
- (*sec->cache)(sid);
- rv = SECSuccess;
- }
- ssl_FreeSID(sid);
- ci->sid = 0;
- }
-done:
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from ssl2_ClientSetupSessionCypher() <-
- * ssl2_HandleServerHelloMessage()
- * after ssl2_BeginClientHandshake()
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize,
- PRUint8 *ca, int caLen,
- PRUint8 *ck, int ckLen,
- PRUint8 *ek, int ekLen)
-{
- sslSecurityInfo *sec;
- PRUint8 * msg;
- int sendLen;
- int sent;
- SECStatus rv;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- ssl_GetXmitBufLock(ss); /***************************************/
- sec = ss->sec;
-
- sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen;
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv != SECSuccess)
- goto done;
-
- SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key",
- SSL_GETPID(), ss->fd));
-
- msg = sec->ci.sendBuf.buf;
- msg[0] = SSL_MT_CLIENT_MASTER_KEY;
- msg[1] = cipher;
- msg[2] = MSB(keySize);
- msg[3] = LSB(keySize);
- msg[4] = MSB(ckLen);
- msg[5] = LSB(ckLen);
- msg[6] = MSB(ekLen);
- msg[7] = LSB(ekLen);
- msg[8] = MSB(caLen);
- msg[9] = LSB(caLen);
- PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen);
- PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen, ek, ekLen);
- PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen+ekLen, ca, caLen);
-
- DUMP_MSG(29, (ss, msg, sendLen));
- sent = (*sec->send)(ss, msg, sendLen, 0);
- rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
-done:
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage()
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendCertificateRequestMessage(sslSocket *ss)
-{
- sslSecurityInfo *sec;
- sslConnectInfo * ci;
- PRUint8 * msg;
- int sent;
- int sendLen;
- SECStatus rv;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- ssl_GetXmitBufLock(ss); /***************************************/
- sec = ss->sec;
- ci = &sec->ci;
-
- sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES;
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv != SECSuccess)
- goto done;
-
- SSL_TRC(3, ("%d: SSL[%d]: sending certificate request",
- SSL_GETPID(), ss->fd));
-
- /* Generate random challenge for client to encrypt */
- PK11_GenerateRandom(ci->serverChallenge, SSL_CHALLENGE_BYTES);
-
- msg = ci->sendBuf.buf;
- msg[0] = SSL_MT_REQUEST_CERTIFICATE;
- msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION;
- PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES, ci->serverChallenge,
- SSL_CHALLENGE_BYTES);
-
- DUMP_MSG(29, (ss, msg, sendLen));
- sent = (*sec->send)(ss, msg, sendLen, 0);
- rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
-done:
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage()
- * ssl2_RestartHandshakeAfterCertReq() <- (application)
- * Acquires and releases the socket's xmitBufLock.
- */
-static int
-ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert,
- SECItem *encCode)
-{
- sslSecurityInfo *sec;
- PRUint8 *msg;
- int rv, sendLen;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- ssl_GetXmitBufLock(ss); /***************************************/
- sec = ss->sec;
-
- sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len;
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv)
- goto done;
-
- SSL_TRC(3, ("%d: SSL[%d]: sending certificate response",
- SSL_GETPID(), ss->fd));
-
- msg = sec->ci.sendBuf.buf;
- msg[0] = SSL_MT_CLIENT_CERTIFICATE;
- msg[1] = SSL_CT_X509_CERTIFICATE;
- msg[2] = MSB(cert->len);
- msg[3] = LSB(cert->len);
- msg[4] = MSB(encCode->len);
- msg[5] = LSB(encCode->len);
- PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len);
- PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len,
- encCode->data, encCode->len);
-
- DUMP_MSG(29, (ss, msg, sendLen));
- rv = (*sec->send)(ss, msg, sendLen, 0);
- if (rv >= 0) {
- rv = SECSuccess;
- }
-done:
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/********************************************************************
-** Send functions above this line must aquire & release the socket's
-** xmitBufLock.
-** All the ssl2_Send functions below this line are called vis ss->sec->send
-** and require that the caller hold the xmitBufLock.
-*/
-
-/*
-** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear.
-*/
-static SECStatus
-ssl2_CalcMAC(PRUint8 * result,
- sslSecurityInfo * sec,
- const PRUint8 * data,
- unsigned int dataLen,
- unsigned int paddingLen)
-{
- const PRUint8 * secret = sec->sendSecret.data;
- unsigned int secretLen = sec->sendSecret.len;
- unsigned long sequenceNumber = sec->sendSequence;
- unsigned int nout;
- PRUint8 seq[4];
- PRUint8 padding[32];/* XXX max blocksize? */
-
- if (!sec->hash || !sec->hash->length)
- return SECSuccess;
- if (!sec->hashcx)
- return SECFailure;
-
- /* Reset hash function */
- (*sec->hash->begin)(sec->hashcx);
-
- /* Feed hash the data */
- (*sec->hash->update)(sec->hashcx, secret, secretLen);
- (*sec->hash->update)(sec->hashcx, data, dataLen);
- PORT_Memset(padding, paddingLen, paddingLen);
- (*sec->hash->update)(sec->hashcx, padding, paddingLen);
-
- seq[0] = (PRUint8) (sequenceNumber >> 24);
- seq[1] = (PRUint8) (sequenceNumber >> 16);
- seq[2] = (PRUint8) (sequenceNumber >> 8);
- seq[3] = (PRUint8) (sequenceNumber);
-
- PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen));
- PRINT_BUF(60, (0, "calc-mac data:", data, dataLen));
- PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen));
- PRINT_BUF(60, (0, "calc-mac seq:", seq, 4));
-
- (*sec->hash->update)(sec->hashcx, seq, 4);
-
- /* Get result */
- (*sec->hash->end)(sec->hashcx, result, &nout, sec->hash->length);
-
- return SECSuccess;
-}
-
-/*
-** Maximum transmission amounts. These are tiny bit smaller than they
-** need to be (they account for the MAC length plus some padding),
-** assuming the MAC is 16 bytes long and the padding is a max of 7 bytes
-** long. This gives an additional 9 bytes of slop to work within.
-*/
-#define MAX_STREAM_CYPHER_LEN 0x7fe0
-#define MAX_BLOCK_CYPHER_LEN 0x3fe0
-
-/*
-** Send some data in the clear.
-** Package up data with the length header and send it.
-**
-** Return count of bytes succesfully written, or negative number (failure).
-*/
-static PRInt32
-ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
-{
- sslSecurityInfo * sec = ss->sec;
- PRUint8 * out;
- int rv;
- int amount;
- int count = 0;
-
- PORT_Assert(sec != 0);
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
-
- SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear",
- SSL_GETPID(), ss->fd, len));
- PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));
-
- while (len) {
- amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
- if (amount + 2 > sec->writeBuf.space) {
- rv = sslBuffer_Grow(&sec->writeBuf, amount + 2);
- if (rv != SECSuccess) {
- count = rv;
- break;
- }
- }
- out = sec->writeBuf.buf;
-
- /*
- ** Construct message.
- */
- out[0] = 0x80 | MSB(amount);
- out[1] = LSB(amount);
- PORT_Memcpy(&out[2], in, amount);
-
- /* Now send the data */
- rv = ssl_DefSend(ss, out, amount + 2, flags & ~ssl_SEND_FLAG_MASK);
- if (rv < 0) {
- if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
- rv = 0;
- } else {
- /* Return short write if some data already went out... */
- if (count == 0)
- count = rv;
- break;
- }
- }
-
- if ((unsigned)rv < (amount + 2)) {
- /* Short write. Save the data and return. */
- if (ssl_SaveWriteData(ss, &ss->pendingBuf, out + rv,
- amount + 2 - rv) == SECFailure) {
- count = SECFailure;
- } else {
- count += amount;
- sec->sendSequence++;
- }
- break;
- }
-
- sec->sendSequence++;
- in += amount;
- count += amount;
- len -= amount;
- }
-
- return count;
-}
-
-/*
-** Send some data, when using a stream cipher. Stream ciphers have a
-** block size of 1. Package up the data with the length header
-** and send it.
-*/
-static PRInt32
-ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
-{
- sslSecurityInfo *sec = ss->sec;
- PRUint8 * out;
- int rv;
- int count = 0;
-
- int amount;
- PRUint8 macLen;
- int nout;
- int buflen;
-
- PORT_Assert(sec != 0);
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
-
- SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher",
- SSL_GETPID(), ss->fd, len));
- PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));
-
- while (len) {
- ssl_GetSpecReadLock(ss); /*************************************/
-
- macLen = sec->hash->length;
- amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
- buflen = amount + 2 + macLen;
- if (buflen > sec->writeBuf.space) {
- rv = sslBuffer_Grow(&sec->writeBuf, buflen);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- out = sec->writeBuf.buf;
- nout = amount + macLen;
- out[0] = 0x80 | MSB(nout);
- out[1] = LSB(nout);
-
- /* Calculate MAC */
- rv = ssl2_CalcMAC(out+2, /* put MAC here */
- sec,
- in, amount, /* input addr & length */
- 0); /* no padding */
- if (rv != SECSuccess)
- goto loser;
-
- /* Encrypt MAC */
- rv = (*sec->enc)(sec->writecx, out+2, &nout, macLen, out+2, macLen);
- if (rv) goto loser;
-
- /* Encrypt data from caller */
- rv = (*sec->enc)(sec->writecx, out+2+macLen, &nout, amount, in, amount);
- if (rv) goto loser;
-
- ssl_ReleaseSpecReadLock(ss); /*************************************/
-
- PRINT_BUF(50, (ss, "encrypted data:", out, buflen));
-
- rv = ssl_DefSend(ss, out, buflen, flags & ~ssl_SEND_FLAG_MASK);
- if (rv < 0) {
- if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
- SSL_TRC(50, ("%d: SSL[%d]: send stream would block, "
- "saving data", SSL_GETPID(), ss->fd));
- rv = 0;
- } else {
- SSL_TRC(10, ("%d: SSL[%d]: send stream error %d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- /* Return short write if some data already went out... */
- if (count == 0)
- count = rv;
- goto done;
- }
- }
-
- if ((unsigned)rv < buflen) {
- /* Short write. Save the data and return. */
- if (ssl_SaveWriteData(ss, &ss->pendingBuf, out + rv,
- buflen - rv) == SECFailure) {
- count = SECFailure;
- } else {
- count += amount;
- sec->sendSequence++;
- }
- goto done;
- }
-
- sec->sendSequence++;
- in += amount;
- count += amount;
- len -= amount;
- }
-
-done:
- return count;
-
-loser:
- ssl_ReleaseSpecReadLock(ss);
- return SECFailure;
-}
-
-/*
-** Send some data, when using a block cipher. Package up the data with
-** the length header and send it.
-*/
-/* XXX assumes blocksize is > 7 */
-static PRInt32
-ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
-{
- sslSecurityInfo *sec = ss->sec;
- PRUint8 * out; /* begining of output buffer. */
- PRUint8 * op; /* next output byte goes here. */
- int rv; /* value from funcs we called. */
- int count = 0; /* this function's return value. */
-
- unsigned int hlen; /* output record hdr len, 2 or 3 */
- unsigned int macLen; /* MAC is this many bytes long. */
- int amount; /* of plaintext to go in record. */
- unsigned int padding; /* add this many padding byte. */
- int nout; /* ciphertext size after header. */
- int buflen; /* size of generated record. */
-
- PORT_Assert(sec != 0);
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
-
- SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher",
- SSL_GETPID(), ss->fd, len));
- PRINT_BUF(50, (ss, "clear data:", in, len));
-
- while (len) {
- ssl_GetSpecReadLock(ss); /*************************************/
-
- macLen = sec->hash->length;
- /* Figure out how much to send, including mac and padding */
- amount = PR_MIN( len, MAX_BLOCK_CYPHER_LEN );
- nout = amount + macLen;
- padding = nout & (sec->blockSize - 1);
- if (padding) {
- hlen = 3;
- padding = sec->blockSize - padding;
- nout += padding;
- } else {
- hlen = 2;
- }
- buflen = hlen + nout;
- if (buflen > sec->writeBuf.space) {
- rv = sslBuffer_Grow(&sec->writeBuf, buflen);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- out = sec->writeBuf.buf;
-
- /* Construct header */
- op = out;
- if (padding) {
- *op++ = MSB(nout);
- *op++ = LSB(nout);
- *op++ = padding;
- } else {
- *op++ = 0x80 | MSB(nout);
- *op++ = LSB(nout);
- }
-
- /* Calculate MAC */
- rv = ssl2_CalcMAC(op, /* MAC goes here. */
- sec,
- in, amount, /* intput addr, len */
- padding);
- if (rv != SECSuccess)
- goto loser;
- op += macLen;
-
- /* Copy in the input data */
- /* XXX could eliminate the copy by folding it into the encryption */
- PORT_Memcpy(op, in, amount);
- op += amount;
- if (padding) {
- PORT_Memset(op, padding, padding);
- op += padding;
- }
-
- /* Encrypt result */
- rv = (*sec->enc)(sec->writecx, out+hlen, &nout, buflen-hlen,
- out+hlen, op - (out + hlen));
- if (rv)
- goto loser;
-
- ssl_ReleaseSpecReadLock(ss); /*************************************/
-
- PRINT_BUF(50, (ss, "final xmit data:", out, op - out));
-
- rv = ssl_DefSend(ss, out, op - out, flags & ~ssl_SEND_FLAG_MASK);
- if (rv < 0) {
- if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
- rv = 0;
- } else {
- SSL_TRC(10, ("%d: SSL[%d]: send block error %d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- /* Return short write if some data already went out... */
- if (count == 0)
- count = rv;
- goto done;
- }
- }
-
- if (rv < (op - out)) {
- /* Short write. Save the data and return. */
- if (ssl_SaveWriteData(ss, &ss->pendingBuf, out + rv,
- op - out - rv) == SECFailure) {
- count = SECFailure;
- } else {
- count += amount;
- sec->sendSequence++;
- }
- goto done;
- }
-
- sec->sendSequence++;
- in += amount;
- count += amount;
- len -= amount;
- }
-
-done:
- return count;
-
-loser:
- ssl_ReleaseSpecReadLock(ss);
- return SECFailure;
-}
-
-/*
-** Called from: ssl2_HandleServerHelloMessage,
-** ssl2_HandleClientSessionKeyMessage,
-** ssl2_RestartHandshakeAfterServerCert,
-** ssl2_HandleClientHelloMessage,
-**
-*/
-static void
-ssl2_UseEncryptedSendFunc(sslSocket *ss)
-{
- sslSecurityInfo *sec;
-
- ssl_GetXmitBufLock(ss);
- PORT_Assert(ss->sec != 0);
- sec = ss->sec;
- PORT_Assert(sec->hashcx != 0);
-
- ss->gather->encrypted = 1;
- sec->send = (sec->blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream;
- ssl_ReleaseXmitBufLock(ss);
-}
-
-/* Called while initializing socket in ssl_CreateSecurityInfo().
-** This function allows us to keep the name of ssl2_SendClear static.
-*/
-void
-ssl2_UseClearSendFunc(sslSocket *ss)
-{
- ss->sec->send = ssl2_SendClear;
-}
-
-/************************************************************************
-** END of Send functions. *
-*************************************************************************/
-
-/***********************************************************************
- * For SSL3, this gathers in and handles records/messages until either
- * the handshake is complete or application data is available.
- *
- * For SSL2, this gathers in only the next SSLV2 record.
- *
- * Called from ssl_Do1stHandshake() via function pointer ss->handshake.
- * Caller must hold handshake lock.
- * This function acquires and releases the RecvBufLock.
- *
- * returns SECSuccess for success.
- * returns SECWouldBlock when that value is returned by ssl2_GatherRecord() or
- * ssl3_GatherCompleteHandshake().
- * returns SECFailure on all other errors.
- *
- * The gather functions called by ssl_GatherRecord1stHandshake are expected
- * to return values interpreted as follows:
- * 1 : the function completed without error.
- * 0 : the function read EOF.
- * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
- * -2 : the function wants ssl_GatherRecord1stHandshake to be called again
- * immediately, by ssl_Do1stHandshake.
- *
- * This code is similar to, and easily confused with, DoRecv() in sslsecur.c
- *
- * This function is called from ssl_Do1stHandshake().
- * The following functions put ssl_GatherRecord1stHandshake into ss->handshake:
- * ssl2_HandleMessage
- * ssl2_HandleVerifyMessage
- * ssl2_HandleServerHelloMessage
- * ssl2_BeginClientHandshake
- * ssl2_HandleClientSessionKeyMessage
- * ssl2_RestartHandshakeAfterCertReq
- * ssl3_RestartHandshakeAfterCertReq
- * ssl2_RestartHandshakeAfterServerCert
- * ssl3_RestartHandshakeAfterServerCert
- * ssl2_HandleClientHelloMessage
- * ssl2_BeginServerHandshake
- */
-SECStatus
-ssl_GatherRecord1stHandshake(sslSocket *ss)
-{
- int rv;
-
- PORT_Assert((ss->sec != 0) && (ss->gather != 0));
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
-
- ssl_GetRecvBufLock(ss);
-
- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
- /* Wait for handshake to complete, or application data to arrive. */
- rv = ssl3_GatherCompleteHandshake(ss, 0);
- } else {
- /* See if we have a complete record */
- rv = ssl2_GatherRecord(ss, 0);
- }
- SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d",
- SSL_GETPID(), ss->fd, rv));
-
- ssl_ReleaseRecvBufLock(ss);
-
- if (rv <= 0) {
- if (rv == SECWouldBlock) {
- /* Progress is blocked waiting for callback completion. */
- SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)",
- SSL_GETPID(), ss->fd, ss->gather->remainder));
- return SECWouldBlock;
- }
- if (rv == 0) {
- /* EOF. Loser */
- PORT_SetError(PR_END_OF_FILE_ERROR);
- }
- return SECFailure; /* rv is < 0 here. */
- }
-
- SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes",
- SSL_GETPID(), ss->fd, ss->gather->recordLen));
-
- ss->handshake = 0; /* makes ssl_Do1stHandshake call ss->nextHandshake.*/
- return SECSuccess;
-}
-
-/************************************************************************/
-
-/* Called from ssl2_ServerSetupSessionCypher()
- * ssl2_ClientSetupSessionCypher()
- */
-static SECStatus
-ssl2_FillInSID(sslSessionID * sid,
- int cipher,
- PRUint8 *keyData,
- int keyLen,
- PRUint8 *ca,
- int caLen,
- int keyBits,
- int secretKeyBits)
-{
- PORT_Assert(sid->references == 1);
- PORT_Assert(sid->cached == never_cached);
- PORT_Assert(sid->u.ssl2.masterKey.data == 0);
- PORT_Assert(sid->u.ssl2.cipherArg.data == 0);
-
- sid->version = SSL_LIBRARY_VERSION_2;
-
- sid->u.ssl2.cipherType = cipher;
- sid->u.ssl2.masterKey.data = (PRUint8*) PORT_Alloc(keyLen);
- if (!sid->u.ssl2.masterKey.data) {
- return SECFailure;
- }
- PORT_Memcpy(sid->u.ssl2.masterKey.data, keyData, keyLen);
- sid->u.ssl2.masterKey.len = keyLen;
- sid->u.ssl2.keyBits = keyBits;
- sid->u.ssl2.secretKeyBits = secretKeyBits;
-
- if (caLen) {
- sid->u.ssl2.cipherArg.data = (PRUint8*) PORT_Alloc(caLen);
- if (!sid->u.ssl2.cipherArg.data) {
- return SECFailure;
- }
- sid->u.ssl2.cipherArg.len = caLen;
- PORT_Memcpy(sid->u.ssl2.cipherArg.data, ca, caLen);
- }
- return SECSuccess;
-}
-
-/*
-** Construct session keys given the masterKey (tied to the session-id),
-** the client's challenge and the server's nonce.
-**
-** Called from ssl2_CreateSessionCypher() <-
-*/
-static SECStatus
-ssl2_ProduceKeys(sslSocket * ss,
- SECItem * readKey,
- SECItem * writeKey,
- SECItem * masterKey,
- PRUint8 * challenge,
- PRUint8 * nonce,
- int cipherType)
-{
- PK11Context * cx = 0;
- unsigned nkm = 0; /* number of hashes to generate key mat. */
- unsigned nkd = 0; /* size of readKey and writeKey. */
- unsigned part;
- unsigned i;
- unsigned off;
- SECStatus rv;
- PRUint8 countChar;
- PRUint8 km[3*16]; /* buffer for key material. */
-
- readKey->data = 0;
- writeKey->data = 0;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- rv = SECSuccess;
- cx = PK11_CreateDigestContext(SEC_OID_MD5);
- if (cx == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return SECFailure;
- }
-
- nkm = ssl_Specs[cipherType].nkm;
- nkd = ssl_Specs[cipherType].nkd;
-
- readKey->data = (PRUint8*) PORT_Alloc(nkd);
- if (!readKey->data)
- goto loser;
- readKey->len = nkd;
-
- writeKey->data = (PRUint8*) PORT_Alloc(nkd);
- if (!writeKey->data)
- goto loser;
- writeKey->len = nkd;
-
- /* Produce key material */
- countChar = '0';
- for (i = 0, off = 0; i < nkm; i++, off += 16) {
- rv = PK11_DigestBegin(cx);
- rv |= PK11_DigestOp(cx, masterKey->data, masterKey->len);
- rv |= PK11_DigestOp(cx, &countChar, 1);
- rv |= PK11_DigestOp(cx, challenge, SSL_CHALLENGE_BYTES);
- rv |= PK11_DigestOp(cx, nonce, SSL_CONNECTIONID_BYTES);
- rv |= PK11_DigestFinal(cx, km+off, &part, MD5_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
- countChar++;
- }
-
- /* Produce keys */
- PORT_Memcpy(readKey->data, km, nkd);
- PORT_Memcpy(writeKey->data, km + nkd, nkd);
-
-loser:
- PK11_DestroyContext(cx, PR_TRUE);
- return rv;
-}
-
-/* Called from ssl2_ServerSetupSessionCypher() <- ssl2_HandleClientSessionKeyMessage()
- <- ssl2_HandleClientHelloMessage()
- * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
- */
-static SECStatus
-ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient)
-{
- sslSecurityInfo * sec;
- sslConnectInfo * ci;
- SECItem * rk;
- SECItem * wk;
- SECItem * param;
- SECStatus rv;
- int cipherType = sid->u.ssl2.cipherType;
- PK11SlotInfo * slot = NULL;
- CK_MECHANISM_TYPE mechanism;
- SECItem readKey;
- SECItem writeKey;
-
- void *readcx = 0;
- void *writecx = 0;
- readKey.data = 0;
- writeKey.data = 0;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
- if((ss->sec == 0) || (ss->sec->ci.sid == 0))
- goto sec_loser; /* don't crash if asserts are off */
-
- /* Trying to cut down on all these switch statements that should be tables.
- * So, test cipherType once, here, and then use tables below.
- */
- switch (cipherType) {
- case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
- case SSL_CK_RC4_128_WITH_MD5:
- case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
- case SSL_CK_RC2_128_CBC_WITH_MD5:
- case SSL_CK_DES_64_CBC_WITH_MD5:
- case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
- break;
-
- default:
- SSL_DBG(("%d: SSL[%d]: ssl2_CreateSessionCypher: unknown cipher=%d",
- SSL_GETPID(), ss->fd, cipherType));
- PORT_SetError(isClient ? SSL_ERROR_BAD_SERVER : SSL_ERROR_BAD_CLIENT);
- goto loser;
- }
-
- sec = ss->sec;
- ci = &sec->ci;
- rk = isClient ? &readKey : &writeKey;
- wk = isClient ? &writeKey : &readKey;
-
- /* Produce the keys for this session */
- rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey,
- ci->clientChallenge, ci->connectionID,
- cipherType);
- if (rv != SECSuccess)
- goto loser;
- PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len));
- PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len));
-
- PORT_Memcpy(ci->readKey, readKey.data, readKey.len);
- PORT_Memcpy(ci->writeKey, writeKey.data, writeKey.len);
- ci->keySize = readKey.len;
-
- /* Setup the MAC */
- rv = ssl2_CreateMAC(sec, rk, wk, cipherType);
- if (rv != SECSuccess)
- goto loser;
-
- /* First create the session key object */
- SSL_TRC(3, ("%d: SSL[%d]: using %s", SSL_GETPID(), ss->fd,
- ssl_cipherName[cipherType]));
-
-
- mechanism = ssl_Specs[cipherType].mechanism;
-
- /* set destructer before we call loser... */
- sec->destroy = (void (*)(void*, PRBool)) PK11_DestroyContext;
- slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg);
- if (slot == NULL)
- goto loser;
-
- param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
- if (param == NULL)
- goto loser;
- readcx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
- CKA_DECRYPT, rk, param,
- ss->pkcs11PinArg);
- SECITEM_FreeItem(param, PR_TRUE);
- if (readcx == NULL)
- goto loser;
-
- /* build the client context */
- param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
- if (param == NULL)
- goto loser;
- writecx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
- CKA_ENCRYPT, wk, param,
- ss->pkcs11PinArg);
- SECITEM_FreeItem(param,PR_TRUE);
- if (writecx == NULL)
- goto loser;
- PK11_FreeSlot(slot);
-
- rv = SECSuccess;
- sec->enc = (SSLCipher) PK11_CipherOp;
- sec->dec = (SSLCipher) PK11_CipherOp;
- sec->readcx = (void *) readcx;
- sec->writecx = (void *) writecx;
- sec->blockSize = ssl_Specs[cipherType].blockSize;
- sec->blockShift = ssl_Specs[cipherType].blockShift;
- sec->cipherType = sid->u.ssl2.cipherType;
- sec->keyBits = sid->u.ssl2.keyBits;
- sec->secretKeyBits = sid->u.ssl2.secretKeyBits;
- goto done;
-
- loser:
- if (sec->destroy) {
- if (readcx) (*sec->destroy)(readcx, PR_TRUE);
- if (writecx) (*sec->destroy)(writecx, PR_TRUE);
- }
- if (slot) PK11_FreeSlot(slot);
-
- sec_loser:
- rv = SECFailure;
-
- done:
- SECITEM_ZfreeItem(rk, PR_FALSE);
- SECITEM_ZfreeItem(wk, PR_FALSE);
- return rv;
-}
-
-/*
-** Setup the server ciphers given information from a CLIENT-MASTER-KEY
-** message.
-** "ss" pointer to the ssl-socket object
-** "cipher" the cipher type to use
-** "keyBits" the size of the final cipher key
-** "ck" the clear-key data
-** "ckLen" the number of bytes of clear-key data
-** "ek" the encrypted-key data
-** "ekLen" the number of bytes of encrypted-key data
-** "ca" the cipher-arg data
-** "caLen" the number of bytes of cipher-arg data
-**
-** The MASTER-KEY is constructed by first decrypting the encrypted-key
-** data. This produces the SECRET-KEY-DATA. The MASTER-KEY is composed by
-** concatenating the clear-key data with the SECRET-KEY-DATA. This code
-** checks to make sure that the client didn't send us an improper amount
-** of SECRET-KEY-DATA (it restricts the length of that data to match the
-** spec).
-**
-** Called from ssl2_HandleClientSessionKeyMessage().
-*/
-static SECStatus
-ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
- PRUint8 *ck, unsigned int ckLen,
- PRUint8 *ek, unsigned int ekLen,
- PRUint8 *ca, unsigned int caLen)
-{
- PRUint8 *kk;
- sslSecurityInfo * sec;
- sslSessionID * sid;
- PRUint8 * kbuf = 0; /* buffer for RSA decrypted data. */
- unsigned int el1; /* length of RSA decrypted data in kbuf */
- unsigned int keySize;
- unsigned int modulus;
- SECStatus rv;
- PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES];
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert((ss->sec != 0) && (ss->serverKey[kt_rsa] != 0));
- sec = ss->sec;
- PORT_Assert((sec->ci.sid != 0));
- sid = sec->ci.sid;
-
- keySize = (keyBits + 7) >> 3;
- /* Is the message just way too big? */
- if (keySize > SSL_MAX_MASTER_KEY_BYTES) {
- /* bummer */
- SSL_DBG(("%d: SSL[%d]: keySize=%d ckLen=%d max session key size=%d",
- SSL_GETPID(), ss->fd, keySize, ckLen,
- SSL_MAX_MASTER_KEY_BYTES));
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto loser;
- }
-
-
- /* Trying to cut down on all these switch statements that should be tables.
- * So, test cipherType once, here, and then use tables below.
- */
- switch (cipher) {
- case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
- case SSL_CK_RC4_128_WITH_MD5:
- case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
- case SSL_CK_RC2_128_CBC_WITH_MD5:
- case SSL_CK_DES_64_CBC_WITH_MD5:
- case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
- break;
-
- default:
- SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher=%d",
- SSL_GETPID(), ss->fd, cipher));
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto loser;
- }
-
- /* For export ciphers, make sure they didn't send too much key data. */
- if (ckLen != ssl_Specs[cipher].pubLen) {
- SSL_DBG(("%d: SSL[%d]: odd secret key size, keySize=%d ckLen=%d!",
- SSL_GETPID(), ss->fd, keySize, ckLen));
- /* Somebody tried to sneak by a strange secret key */
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto loser;
- }
-
- /* allocate the buffer to hold the decrypted portion of the key. */
- /* XXX Haven't done any range check on ekLen. */
- kbuf = (PRUint8*) PORT_Alloc(ekLen);
- if (!kbuf) {
- goto loser;
- }
-
- /*
- ** Decrypt encrypted half of the key. Note that encrypted half has
- ** been made to match the modulus size of our public key using
- ** PKCS#1. keySize is the real size of the data that is interesting.
- ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is
- ** desired behavior here.
- */
- rv = PK11_PubDecryptRaw(ss->serverKey[kt_rsa], kbuf, &el1, ekLen, ek, ekLen);
- if (rv != SECSuccess)
- goto hide_loser;
-
- modulus = PK11_GetPrivateModulusLen(ss->serverKey[kt_rsa]);
- if (modulus == -1) {
- /* If the key was really bad, then PK11_pubDecryptRaw
- * would have failed, therefore the we must assume that the card
- * is just being a pain and not giving us the modulus... but it
- * should be the same size as the encrypted key length, so use it
- * and keep cranking */
- modulus = ekLen;
- }
- /* Is the length of the decrypted data (el1) the expected value? */
- if (modulus != el1)
- goto hide_loser;
-
- /* Cheaply verify that PKCS#1 was used to format the encryption block */
- kk = kbuf + modulus - (keySize - ckLen);
- if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (kk[-1] != 0x00)) {
- /* Tsk tsk. */
- SSL_DBG(("%d: SSL[%d]: strange encryption block",
- SSL_GETPID(), ss->fd));
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto hide_loser;
- }
-
- /* Make sure we're not subject to a version rollback attack. */
- if (ss->enableSSL3 || ss->enableTLS) {
- PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03 };
-
- if (PORT_Memcmp(kk - 8 - 1, threes, 8) == 0) {
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto hide_loser;
- }
- }
- if (0) {
-hide_loser:
- /* Defense against the Bleichenbacher attack.
- * Provide the client with NO CLUES that the decrypted master key
- * was erroneous. Don't send any error messages.
- * Instead, Generate a completely bogus master key .
- */
- PK11_GenerateRandom(kbuf, ekLen);
- }
-
- /*
- ** Construct master key out of the pieces.
- */
- if (ckLen) {
- PORT_Memcpy(mkbuf, ck, ckLen);
- }
- PORT_Memcpy(mkbuf+ckLen, kk, keySize-ckLen);
-
- /* Fill in session-id */
- rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen,
- keyBits, keyBits - (ckLen<<3));
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* Create session ciphers */
- rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d",
- SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
- ckLen<<3, keySize<<3));
- rv = SECSuccess;
- goto done;
-
- loser:
- rv = SECFailure;
-
- done:
- PORT_Free(kbuf);
- return rv;
-}
-
-/************************************************************************/
-
-/*
-** Rewrite the incoming cipher specs, comparing to list of specs we support,
-** (ss->cipherSpecs) and eliminating anything we don't support
-**
-* Note: Our list may contain SSL v3 ciphers.
-* We MUST NOT match on any of those.
-* Fortunately, this is easy to detect because SSLv3 ciphers have zero
-* in the first byte, and none of the SSLv2 ciphers do.
-*
-* Called from ssl2_HandleClientHelloMessage().
-*/
-static int
-ssl2_QualifyCypherSpecs(sslSocket *ss,
- PRUint8 * cs, /* cipher specs in client hello msg. */
- int csLen)
-{
- PRUint8 * ms;
- PRUint8 * hs;
- PRUint8 * qs;
- int mc;
- int hc;
- PRUint8 qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3];
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
-
- if (!ss->cipherSpecs) {
- ssl2_ConstructCipherSpecs(ss);
- }
-
- PRINT_BUF(10, (ss, "specs from client:", cs, csLen));
- qs = qualifiedSpecs;
- ms = ss->cipherSpecs;
- for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) {
- if (ms[0] == 0)
- continue;
- for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) {
- if ((hs[0] == ms[0]) &&
- (hs[1] == ms[1]) &&
- (hs[2] == ms[2])) {
- /* Copy this cipher spec into the "keep" section */
- qs[0] = hs[0];
- qs[1] = hs[1];
- qs[2] = hs[2];
- qs += 3;
- break;
- }
- }
- }
- hc = qs - qualifiedSpecs;
- PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc));
- PORT_Memcpy(cs, qualifiedSpecs, hc);
- return hc;
-}
-
-/*
-** Pick the best cipher we can find, given the array of server cipher
-** specs. Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap.
-** If succesful, stores the master key size (bytes) in *pKeyLen.
-**
-** This is correct only for the client side, but presently
-** this function is only called from
-** ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
-**
-** Note that most servers only return a single cipher suite in their
-** ServerHello messages. So, the code below for finding the "best" cipher
-** suite usually has only one choice. The client and server should send
-** their cipher suite lists sorted in descending order by preference.
-*/
-static int
-ssl2_ChooseSessionCypher(sslSocket *ss,
- int hc, /* number of cs's in hs. */
- PRUint8 * hs, /* server hello's cipher suites. */
- int * pKeyLen) /* out: sym key size in bytes. */
-{
- PRUint8 * ms;
- unsigned int i;
- int bestKeySize;
- int bestRealKeySize;
- int bestCypher;
- int keySize;
- int realKeySize;
- PRUint8 * ohs = hs;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
-
- if (!ss->cipherSpecs) {
- ssl2_ConstructCipherSpecs(ss);
- }
-
- if (!ss->preferredCipher) {
- const PRUint8 * preferred = implementedCipherSuites;
- unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference &
- SSL_CB_IMPLEMENTED;
- if (allowed) {
- for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) {
- if (0 != (allowed & (1U << preferred[0]))) {
- ss->preferredCipher = preferred;
- break;
- }
- preferred += 3;
- }
- }
- }
- /*
- ** Scan list of ciphers recieved from peer and look for a match in
- ** our list.
- * Note: Our list may contain SSL v3 ciphers.
- * We MUST NOT match on any of those.
- * Fortunately, this is easy to detect because SSLv3 ciphers have zero
- * in the first byte, and none of the SSLv2 ciphers do.
- */
- bestKeySize = bestRealKeySize = 0;
- bestCypher = -1;
- while (--hc >= 0) {
- for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) {
- if ((hs[0] == ss->preferredCipher[0]) &&
- (hs[1] == ss->preferredCipher[1]) &&
- (hs[2] == ss->preferredCipher[2]) &&
- hs[0] != 0) {
- /* Pick this cipher immediately! */
- *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3;
- return hs[0];
- }
- if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) &&
- hs[0] != 0) {
- /* Found a match */
-
- /* Use secret keySize to determine which cipher is best */
- realKeySize = (hs[1] << 8) | hs[2];
- switch (hs[0]) {
- case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
- case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
- keySize = 40;
- break;
- default:
- keySize = realKeySize;
- break;
- }
- if (keySize > bestKeySize) {
- bestCypher = hs[0];
- bestKeySize = keySize;
- bestRealKeySize = realKeySize;
- }
- }
- }
- hs += 3;
- }
- if (bestCypher < 0) {
- /*
- ** No overlap between server and client. Re-examine server list
- ** to see what kind of ciphers it does support so that we can set
- ** the error code appropriately.
- */
- if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) ||
- (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) {
- PORT_SetError(SSL_ERROR_US_ONLY_SERVER);
- } else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) ||
- (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) {
- PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER);
- } else {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- }
- SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd));
- goto loser;
- }
- *pKeyLen = (bestRealKeySize + 7) >> 3;
- return bestCypher;
-
- loser:
- return -1;
-}
-
-static SECStatus
-ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen)
-{
- CERTCertificate *cert = NULL;
- SECItem certItem;
-
- PORT_Assert(ss->sec != 0);
-
- certItem.data = certData;
- certItem.len = certLen;
-
- /* decode the certificate */
- cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
-
- if (cert == NULL) {
- SSL_DBG(("%d: SSL[%d]: decode of server certificate fails",
- SSL_GETPID(), ss->fd));
- PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
- return SECFailure;
- }
-
-#ifdef TRACE
- {
- if (ssl_trace >= 1) {
- char *issuer;
- char *subject;
- issuer = CERT_NameToAscii(&cert->issuer);
- subject = CERT_NameToAscii(&cert->subject);
- SSL_TRC(1,("%d: server certificate issuer: '%s'",
- SSL_GETPID(), issuer ? issuer : "OOPS"));
- SSL_TRC(1,("%d: server name: '%s'",
- SSL_GETPID(), subject ? subject : "OOPS"));
- PORT_Free(issuer);
- PORT_Free(subject);
- }
- }
-#endif
-
- ss->sec->peerCert = cert;
- return SECSuccess;
-}
-
-/*
-** Given the server's public key and cipher specs, generate a session key
-** that is ready to use for encrypting/decrypting the byte stream. At
-** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and
-** send it to the server.
-**
-** Called from ssl2_HandleServerHelloMessage()
-*/
-static SECStatus
-ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen)
-{
- sslSessionID * sid;
- PRUint8 * ca; /* points to iv data, or NULL if none. */
- PRUint8 * ekbuf = 0;
- CERTCertificate * cert = 0;
- SECKEYPublicKey * serverKey = 0;
- unsigned modulusLen = 0;
- SECStatus rv;
- int cipher;
- int keyLen; /* cipher symkey size in bytes. */
- int ckLen; /* publicly reveal this many bytes of key. */
- int caLen; /* length of IV data at *ca. */
- int nc;
-
- SECItem eblock; /* holds unencrypted PKCS#1 formatted key. */
- SECItem rek; /* holds portion of symkey to be encrypted. */
-
- PRUint8 keyData[SSL_MAX_MASTER_KEY_BYTES];
- PRUint8 iv [8];
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- eblock.data = 0;
- eblock.len = 0;
-
- sid = ss->sec->ci.sid;
- PORT_Assert(sid != 0);
-
- cert = ss->sec->peerCert;
-
- serverKey = CERT_ExtractPublicKey(cert);
- if (!serverKey) {
- SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
- rv = SECFailure;
- goto loser2;
- }
-
- /* Choose a compatible cipher with the server */
- nc = csLen / 3;
- cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen);
- if (cipher < 0) {
- /* ssl2_ChooseSessionCypher has set error code. */
- ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
- goto loser;
- }
-
- /* Generate the random keys */
- PK11_GenerateRandom(keyData, sizeof(keyData));
-
- /*
- ** Next, carve up the keys into clear and encrypted portions. The
- ** clear data is taken from the start of keyData and the encrypted
- ** portion from the remainder. Note that each of these portions is
- ** carved in half, one half for the read-key and one for the
- ** write-key.
- */
- ca = 0;
-
- /* We know that cipher is a legit value here, because
- * ssl2_ChooseSessionCypher doesn't return bogus values.
- */
- ckLen = ssl_Specs[cipher].pubLen; /* cleartext key length. */
- caLen = ssl_Specs[cipher].ivLen; /* IV length. */
- if (caLen) {
- PORT_Assert(sizeof iv >= caLen);
- PK11_GenerateRandom(iv, caLen);
- ca = iv;
- }
-
- /* Fill in session-id */
- rv = ssl2_FillInSID(sid, cipher, keyData, keyLen,
- ca, caLen, keyLen << 3, (keyLen - ckLen) << 3);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d",
- SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
- ckLen<<3, keyLen<<3));
-
- /* Now setup read and write ciphers */
- rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /*
- ** Fill in the encryption buffer with some random bytes. Then
- ** copy in the portion of the session key we are encrypting.
- */
- modulusLen = SECKEY_PublicKeyStrength(serverKey);
- rek.data = keyData + ckLen;
- rek.len = keyLen - ckLen;
- rv = RSA_FormatBlock(&eblock, modulusLen, RSA_BlockPublic, &rek);
- if (rv)
- goto loser;
- /* Set up the padding for version 2 rollback detection. */
- /* XXX We should really use defines here */
- if (ss->enableSSL3 || ss->enableTLS) {
- PORT_Assert((modulusLen - rek.len) > 12);
- PORT_Memset(eblock.data + modulusLen - rek.len - 8 - 1, 0x03, 8);
- }
- ekbuf = (PRUint8*) PORT_Alloc(modulusLen);
- if (!ekbuf)
- goto loser;
- PRINT_BUF(10, (ss, "master key encryption block:",
- eblock.data, eblock.len));
-
- /* Encrypt ekitem */
- rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock.data, modulusLen,
- ss->pkcs11PinArg);
- if (rv)
- goto loser;
-
- if (eblock.len != modulusLen) {
- /* Something strange just happened */
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- goto loser;
- }
-
- /* Now we have everything ready to send */
- rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen,
- keyData, ckLen, ekbuf, modulusLen);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECSuccess;
- goto done;
-
- loser:
- rv = SECFailure;
-
- loser2:
- done:
- PORT_Memset(keyData, 0, sizeof(keyData));
- PORT_ZFree(ekbuf, modulusLen);
- SECITEM_ZfreeItem(&eblock, PR_FALSE);
- SECKEY_DestroyPublicKey(serverKey);
- return rv;
-}
-
-/************************************************************************/
-
-/*
- * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message.
- * Caller holds recvBufLock and handshakeLock
- */
-static void
-ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s)
-{
- sslSecurityInfo *sec;
- sslSessionID *sid;
-
- PORT_Assert((ss->sec != 0));
- sec = ss->sec;
- sid = sec->ci.sid;
-
- /* Record entry in nonce cache */
- if (sid->peerCert == NULL) {
- PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID));
- sid->peerCert = CERT_DupCertificate(sec->peerCert);
-
- }
- if (!ss->noCache)
- (*sec->cache)(sid);
-}
-
-/* Called from ssl2_HandleMessage() */
-static SECStatus
-ssl2_TriggerNextMessage(sslSocket *ss)
-{
- sslConnectInfo * ci;
- SECStatus rv;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- ci = &ss->sec->ci;
-
- if ((ci->requiredElements & CIS_HAVE_CERTIFICATE) &&
- !(ci->sentElements & CIS_HAVE_CERTIFICATE)) {
- ci->sentElements |= CIS_HAVE_CERTIFICATE;
- rv = ssl2_SendCertificateRequestMessage(ss);
- return rv;
- }
- return SECSuccess;
-}
-
-/* See if it's time to send our finished message, or if the handshakes are
-** complete. Send finished message if appropriate.
-** Returns SECSuccess unless anything goes wrong.
-**
-** Called from ssl2_HandleMessage,
-** ssl2_HandleVerifyMessage
-** ssl2_HandleServerHelloMessage
-** ssl2_HandleClientSessionKeyMessage
-** ssl2_RestartHandshakeAfterCertReq
-** ssl2_RestartHandshakeAfterServerCert
-*/
-static SECStatus
-ssl2_TryToFinish(sslSocket *ss)
-{
- sslSecurityInfo *sec;
- sslConnectInfo * ci;
- SECStatus rv;
- char e, ef;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- sec = ss->sec;
- ci = &sec->ci;
-
- e = ci->elements;
- ef = e | CIS_HAVE_FINISHED;
- if ((ef & ci->requiredElements) == ci->requiredElements) {
- if (sec->isServer) {
- /* Send server finished message if we already didn't */
- rv = ssl2_SendServerFinishedMessage(ss);
- } else {
- /* Send client finished message if we already didn't */
- rv = ssl2_SendClientFinishedMessage(ss);
- }
- if (rv != SECSuccess) {
- return rv;
- }
- if ((e & ci->requiredElements) == ci->requiredElements) {
- /* Totally finished */
- ss->handshake = 0;
- return SECSuccess;
- }
- }
- return SECSuccess;
-}
-
-/*
-** Called from ssl2_HandleRequestCertificate
-** ssl2_RestartHandshakeAfterCertReq
-*/
-static SECStatus
-ssl2_SignResponse(sslSocket *ss,
- SECKEYPrivateKey *key,
- SECItem *response)
-{
- SGNContext * sgn = NULL;
- sslConnectInfo * ci;
- sslSecurityInfo *sec;
- PRUint8 * challenge;
- unsigned int len;
- SECStatus rv = SECFailure;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
-
- sec = ss->sec;
- ci = &sec->ci;
- challenge = ci->serverChallenge;
- len = ci->serverChallengeLen;
-
- /* Sign the expected data... */
- sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,key);
- if (!sgn)
- goto done;
- rv = SGN_Begin(sgn);
- if (rv != SECSuccess)
- goto done;
- rv = SGN_Update(sgn, ci->readKey, ci->keySize);
- if (rv != SECSuccess)
- goto done;
- rv = SGN_Update(sgn, ci->writeKey, ci->keySize);
- if (rv != SECSuccess)
- goto done;
- rv = SGN_Update(sgn, challenge, len);
- if (rv != SECSuccess)
- goto done;
- rv = SGN_Update(sgn,
- sec->peerCert->derCert.data, sec->peerCert->derCert.len);
- if (rv != SECSuccess)
- goto done;
- rv = SGN_End(sgn, response);
- if (rv != SECSuccess)
- goto done;
-
-done:
- SGN_DestroyContext(sgn, PR_TRUE);
- return rv == SECSuccess ? SECSuccess : SECFailure;
-}
-
-/*
-** Try to handle a request-certificate message. Get client's certificate
-** and private key and sign a message for the server to see.
-** Caller must hold handshakeLock
-**
-** Called from ssl2_HandleMessage().
-*/
-static int
-ssl2_HandleRequestCertificate(sslSocket *ss)
-{
- CERTCertificate * cert = NULL; /* app-selected client cert. */
- SECKEYPrivateKey *key = NULL; /* priv key for cert. */
- SECStatus rv;
- SECItem response;
- int ret = 0;
- PRUint8 authType;
-
-
- /*
- * These things all need to be initialized before we can "goto loser".
- */
- response.data = NULL;
-
- PORT_Assert((ss->sec != 0));
- if (!ss->sec) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
-
- /* get challenge info from connectionInfo */
- authType = ss->sec->ci.authType;
-
- if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) {
- SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(),
- ss->fd, authType));
- goto no_cert_error;
- }
-
- /* Get certificate and private-key from client */
- if (!ss->getClientAuthData) {
- SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth",
- SSL_GETPID(), ss->fd));
- goto no_cert_error;
- }
- ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd,
- NULL, &cert, &key);
- if ( ret == SECWouldBlock ) {
- ssl_SetAlwaysBlock(ss);
- goto done;
- }
-
- if (ret) {
- goto no_cert_error;
- }
-
- rv = ssl2_SignResponse(ss, key, &response);
- if ( rv != SECSuccess ) {
- ret = -1;
- goto loser;
- }
-
- /* Send response message */
- ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);
- goto done;
-
- no_cert_error:
- SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(),
- ss->fd, ret));
- ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);
-
- loser:
- done:
- if ( cert ) {
- CERT_DestroyCertificate(cert);
- }
- if ( key ) {
- SECKEY_DestroyPrivateKey(key);
- }
- if ( response.data ) {
- PORT_Free(response.data);
- }
-
- return ret;
-}
-
-/*
-** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message.
-** Caller must hold HandshakeLock and RecvBufLock, since cd and response
-** are contained in the gathered input data.
-*/
-static SECStatus
-ssl2_HandleClientCertificate(sslSocket * ss,
- PRUint8 certType, /* XXX unused */
- PRUint8 * cd,
- unsigned int cdLen,
- PRUint8 * response,
- unsigned int responseLen)
-{
- sslSecurityInfo *sec = ss->sec;
- sslConnectInfo * ci;
- CERTCertificate *cert = NULL;
- SECKEYPublicKey *pubKey = NULL;
- VFYContext * vfy = NULL;
- SECStatus rv = SECFailure;
- SECItem certItem;
- SECItem rep;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
-
- /* Extract the certificate */
- certItem.data = cd;
- certItem.len = cdLen;
-
- cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
- if (cert == NULL) {
- goto loser;
- }
-
- /* save the certificate, since the auth routine will need it */
- sec->peerCert = cert;
-
- /* Extract the public key */
- pubKey = CERT_ExtractPublicKey(cert);
- if (!pubKey)
- goto loser;
-
- /* Verify the response data... */
- rep.data = response;
- rep.len = responseLen;
- /* SSL 2.0 only supports RSA certs, so we don't have to worry about
- * DSA here. */
- vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION,
- ss->pkcs11PinArg);
- if (!vfy)
- goto loser;
- rv = VFY_Begin(vfy);
- if (rv)
- goto loser;
-
- ci = &sec->ci;
- rv = VFY_Update(vfy, ci->readKey, ci->keySize);
- if (rv)
- goto loser;
- rv = VFY_Update(vfy, ci->writeKey, ci->keySize);
- if (rv)
- goto loser;
- rv = VFY_Update(vfy, ci->serverChallenge, SSL_CHALLENGE_BYTES);
- if (rv)
- goto loser;
- rv = VFY_Update(vfy, ss->serverCert[kt_rsa]->derCert.data,
- ss->serverCert[kt_rsa]->derCert.len);
- if (rv)
- goto loser;
- rv = VFY_End(vfy);
- if (rv)
- goto loser;
-
- /* Now ask the server application if it likes the certificate... */
- rv = (SECStatus) (*ss->authCertificate)(ss->authCertificateArg,
- ss->fd, PR_TRUE, PR_TRUE);
- /* Hey, it liked it. */
- if (SECSuccess == rv)
- goto done;
-
-loser:
- sec->peerCert = NULL;
- CERT_DestroyCertificate(cert);
-
-done:
- VFY_DestroyContext(vfy, PR_TRUE);
- SECKEY_DestroyPublicKey(pubKey);
- return rv;
-}
-
-/*
-** Handle remaining messages between client/server. Process finished
-** messages from either side and any authentication requests.
-** This should only be called for SSLv2 handshake messages,
-** not for application data records.
-** Caller must hold handshake lock.
-**
-** Called from ssl_Do1stHandshake().
-**
-*/
-static SECStatus
-ssl2_HandleMessage(sslSocket *ss)
-{
- sslSecurityInfo *sec;
- sslConnectInfo * ci;
- sslGather * gs;
- PRUint8 * data;
- PRUint8 * cid;
- unsigned len, certType, certLen, responseLen;
- int rv;
- int rv2;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0) && (ss->gather != 0));
-
- ssl_GetRecvBufLock(ss);
- sec = ss->sec;
- gs = ss->gather;
- ci = &sec->ci;
-
- data = gs->buf.buf + gs->recordOffset;
-
- if (gs->recordLen < 1) {
- goto bad_peer;
- }
- SSL_TRC(3, ("%d: SSL[%d]: received %d message",
- SSL_GETPID(), ss->fd, data[0]));
- DUMP_MSG(29, (ss, data, gs->recordLen));
-
- switch (data[0]) {
- case SSL_MT_CLIENT_FINISHED:
- if (ci->elements & CIS_HAVE_FINISHED) {
- SSL_DBG(("%d: SSL[%d]: dup client-finished message",
- SSL_GETPID(), ss->fd));
- goto bad_peer;
- }
-
- /* See if nonce matches */
- len = gs->recordLen - 1;
- cid = data + 1;
- if ((len != sizeof(ci->connectionID)) ||
- (PORT_Memcmp(ci->connectionID, cid, len) != 0)) {
- SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd));
- PRINT_BUF(5, (ss, "sent connection-id",
- ci->connectionID, sizeof(ci->connectionID)));
- PRINT_BUF(5, (ss, "rcvd connection-id", cid, len));
- goto bad_peer;
- }
-
- SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d",
- SSL_GETPID(), ss->fd, ci->requiredElements ^ ci->elements));
- ci->elements |= CIS_HAVE_FINISHED;
- break;
-
- case SSL_MT_SERVER_FINISHED:
- if (ci->elements & CIS_HAVE_FINISHED) {
- SSL_DBG(("%d: SSL[%d]: dup server-finished message",
- SSL_GETPID(), ss->fd));
- goto bad_peer;
- }
-
- if (gs->recordLen - 1 != SSL_SESSIONID_BYTES) {
- SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d",
- SSL_GETPID(), ss->fd, gs->recordLen));
- goto bad_peer;
- }
- ssl2_ClientRegSessionID(ss, data+1);
- SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d",
- SSL_GETPID(), ss->fd, ci->requiredElements ^ ci->elements));
- ci->elements |= CIS_HAVE_FINISHED;
- break;
-
- case SSL_MT_REQUEST_CERTIFICATE:
- len = gs->recordLen - 2;
- if ((len != SSL_MIN_CHALLENGE_BYTES) ||
- (len > SSL_MAX_CHALLENGE_BYTES)) {
- /* Bad challenge */
- SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d",
- SSL_GETPID(), ss->fd, len));
- goto bad_peer;
- }
-
- /* save auth request info */
- ci->authType = data[1];
- ci->serverChallengeLen = len;
- PORT_Memcpy(ci->serverChallenge, data + 2, len);
-
- rv = ssl2_HandleRequestCertificate(ss);
- if (rv == SECWouldBlock) {
- SSL_TRC(3, ("%d: SSL[%d]: async cert request",
- SSL_GETPID(), ss->fd));
- /* someone is handling this asynchronously */
- ssl_ReleaseRecvBufLock(ss);
- return SECWouldBlock;
- }
- if (rv) {
- SET_ERROR_CODE
- goto loser;
- }
- break;
-
- case SSL_MT_CLIENT_CERTIFICATE:
- if (!ss->authCertificate) {
- /* Server asked for authentication and can't handle it */
- PORT_SetError(SSL_ERROR_BAD_SERVER);
- goto loser;
- }
- if (gs->recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) {
- SET_ERROR_CODE
- goto loser;
- }
- certType = data[1];
- certLen = (data[2] << 8) | data[3];
- responseLen = (data[4] << 8) | data[5];
- if (certType != SSL_CT_X509_CERTIFICATE) {
- PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
- goto loser;
- }
- rv = ssl2_HandleClientCertificate(ss, data[1],
- data + SSL_HL_CLIENT_CERTIFICATE_HBYTES,
- certLen,
- data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen,
- responseLen);
- if (rv) {
- rv2 = ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
- SET_ERROR_CODE
- goto loser;
- }
- ci->elements |= CIS_HAVE_CERTIFICATE;
- break;
-
- case SSL_MT_ERROR:
- rv = (data[1] << 8) | data[2];
- SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x",
- SSL_GETPID(), ss->fd, rv));
-
- /* Convert protocol error number into API error number */
- switch (rv) {
- case SSL_PE_NO_CYPHERS:
- rv = SSL_ERROR_NO_CYPHER_OVERLAP;
- break;
- case SSL_PE_NO_CERTIFICATE:
- rv = SSL_ERROR_NO_CERTIFICATE;
- break;
- case SSL_PE_BAD_CERTIFICATE:
- rv = SSL_ERROR_BAD_CERTIFICATE;
- break;
- case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE:
- rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
- break;
- default:
- goto bad_peer;
- }
- /* XXX make certificate-request optionally fail... */
- PORT_SetError(rv);
- goto loser;
-
- default:
- SSL_DBG(("%d: SSL[%d]: unknown message %d",
- SSL_GETPID(), ss->fd, data[0]));
- goto loser;
- }
-
- SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x",
- SSL_GETPID(), ss->fd, data[0],
- ci->requiredElements, ci->elements));
-
- rv = ssl2_TryToFinish(ss);
- if (rv != SECSuccess)
- goto loser;
-
- ss->gather->recordLen = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- if (ss->handshake == 0) {
- return SECSuccess;
- }
-
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleMessage;
- return ssl2_TriggerNextMessage(ss);
-
- bad_peer:
- PORT_SetError(sec->isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER);
- /* FALL THROUGH */
-
- loser:
- ssl_ReleaseRecvBufLock(ss);
- return SECFailure;
-}
-
-/************************************************************************/
-
-/* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage or
-** ssl2_RestartHandshakeAfterServerCert.
-*/
-static SECStatus
-ssl2_HandleVerifyMessage(sslSocket *ss)
-{
- sslConnectInfo * ci;
- sslGather * gs;
- PRUint8 * data;
- SECStatus rv;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- ssl_GetRecvBufLock(ss);
- PORT_Assert((ss->sec != 0) && (ss->gather != 0));
- ci = &ss->sec->ci;
- gs = ss->gather;
-
- data = gs->buf.buf + gs->recordOffset;
- DUMP_MSG(29, (ss, data, gs->recordLen));
- if ((gs->recordLen != 1 + SSL_CHALLENGE_BYTES) ||
- (data[0] != SSL_MT_SERVER_VERIFY) ||
- PORT_Memcmp(data+1, ci->clientChallenge, SSL_CHALLENGE_BYTES)) {
- /* Bad server */
- PORT_SetError(SSL_ERROR_BAD_SERVER);
- goto loser;
- }
- ci->elements |= CIS_HAVE_VERIFY;
-
- SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x",
- SSL_GETPID(), ss->fd, ci->requiredElements,
- ci->elements));
-
- rv = ssl2_TryToFinish(ss);
- if (rv)
- goto loser;
-
- ss->gather->recordLen = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- if (ss->handshake == 0) {
- return SECSuccess;
- }
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleMessage;
- return SECSuccess;
-
-
- loser:
- ssl_ReleaseRecvBufLock(ss);
- return SECFailure;
-}
-
-/* Not static because ssl2_GatherData() tests ss->nextHandshake for this value.
- * ICK!
- * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake()
- */
-SECStatus
-ssl2_HandleServerHelloMessage(sslSocket *ss)
-{
- sslSecurityInfo *sec;
- sslConnectInfo * ci;
- sslGather * gs;
- sslSessionID * sid;
- PRUint8 * cert;
- PRUint8 * cs;
- PRUint8 * data;
- SECStatus rv;
- int needed, sidHit, certLen, csLen, cidLen, certType, err;
-
- PORT_Assert((ss->sec != 0) && (ss->gather != 0));
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
-
- if (!ss->enableSSL2) {
- PORT_SetError(SSL_ERROR_SSL2_DISABLED);
- return SECFailure;
- }
-
- ssl_GetRecvBufLock(ss);
-
- sec = ss->sec;
- ci = &sec->ci;
- gs = ss->gather;
- PORT_Assert(ci->sid != 0);
-
- data = gs->buf.buf + gs->recordOffset;
- DUMP_MSG(29, (ss, data, gs->recordLen));
-
- /* Make sure first message has some data and is the server hello message */
- if ((gs->recordLen < SSL_HL_SERVER_HELLO_HBYTES)
- || (data[0] != SSL_MT_SERVER_HELLO)) {
- if ((data[0] == SSL_MT_ERROR) && (gs->recordLen == 3)) {
- err = (data[1] << 8) | data[2];
- if (err == SSL_PE_NO_CYPHERS) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- goto loser;
- }
- }
- goto bad_server;
- }
-
- sidHit = data[1];
- certType = data[2];
- ss->version = (data[3] << 8) | data[4];
- certLen = (data[5] << 8) | data[6];
- csLen = (data[7] << 8) | data[8];
- cidLen = (data[9] << 8) | data[10];
- cert = data + SSL_HL_SERVER_HELLO_HBYTES;
- cs = cert + certLen;
-
- SSL_TRC(5,
- ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidLen=%d",
- SSL_GETPID(), ss->fd, sidHit, ss->version, certLen,
- csLen, cidLen));
- if (ss->version != SSL_LIBRARY_VERSION_2) {
- if (ss->version < SSL_LIBRARY_VERSION_2) {
- SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)",
- SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2,
- ss->version));
- } else {
- SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)",
- SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
- /* server claims to be newer but does not follow protocol */
- PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
- goto loser;
- }
- }
-
- /* Save connection-id for later */
- PORT_Memcpy(ci->connectionID, cs + csLen, sizeof(ci->connectionID));
-
- /* See if session-id hit */
- needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY;
- if (sidHit) {
- if (certLen || csLen) {
- /* Uh oh - bogus server */
- SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d",
- SSL_GETPID(), ss->fd, sidHit, certLen, csLen));
- goto bad_server;
- }
-
- /* Total winner. */
- SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x "
- "port=0x%04x",
- SSL_GETPID(), ss->fd, ci->peer, ci->port));
- sec->peerCert = CERT_DupCertificate(ci->sid->peerCert);
- rv = ssl2_CreateSessionCypher(ss, ci->sid, PR_TRUE);
- if (rv != SECSuccess) {
- goto loser;
- }
- } else {
- if (certType != SSL_CT_X509_CERTIFICATE) {
- PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
- goto loser;
- }
- if (csLen == 0) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- SSL_DBG(("%d: SSL[%d]: no cipher overlap",
- SSL_GETPID(), ss->fd));
- goto loser;
- }
- if (certLen == 0) {
- SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d",
- SSL_GETPID(), ss->fd, certLen, csLen));
- goto bad_server;
- }
-
- sid = ci->sid;
- if (sid->cached != never_cached) {
- /* Forget our session-id - server didn't like it */
- SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id",
- SSL_GETPID(), ss->fd));
- (*sec->uncache)(sid);
- ssl_FreeSID(sid);
- ci->sid = sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
- if (!sid) {
- goto loser;
- }
- sid->references = 1;
- sid->addr = ci->peer;
- sid->port = ci->port;
- }
-
- /* decode the server's certificate */
- rv = ssl2_ClientHandleServerCert(ss, cert, certLen);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
- (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
- }
- goto loser;
- }
-
- /* Setup new session cipher */
- rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
- (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
- }
- goto loser;
- }
- }
-
- /* Build up final list of required elements */
- ci->elements = CIS_HAVE_MASTER_KEY;
- ci->requiredElements = needed;
-
- if (!sidHit) {
- /* verify the server's certificate. if sidHit, don't check signatures */
- rv = (* ss->authCertificate)(ss->authCertificateArg, ss->fd,
- (PRBool)(!sidHit), PR_FALSE);
- if (rv) {
- if (ss->handleBadCert) {
- rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd);
- if ( rv ) {
- if ( rv == SECWouldBlock ) {
- /* someone will handle this connection asynchronously*/
-
- SSL_DBG(("%d: SSL[%d]: go to async cert handler",
- SSL_GETPID(), ss->fd));
- ssl_ReleaseRecvBufLock(ss);
- ssl_SetAlwaysBlock(ss);
- return SECWouldBlock;
- }
- /* cert is bad */
- SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- goto loser;
-
- }
- /* cert is good */
- } else {
- SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- goto loser;
- }
- }
- }
- /*
- ** At this point we have a completed session key and our session
- ** cipher is setup and ready to go. Switch to encrypted write routine
- ** as all future message data is to be encrypted.
- */
- ssl2_UseEncryptedSendFunc(ss);
-
- rv = ssl2_TryToFinish(ss);
- if (rv != SECSuccess)
- goto loser;
-
- ss->gather->recordLen = 0;
-
- ssl_ReleaseRecvBufLock(ss);
-
- if (ss->handshake == 0) {
- return SECSuccess;
- }
-
- SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
- SSL_GETPID(), ss->fd, ci->requiredElements, ci->elements));
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleVerifyMessage;
- return SECSuccess;
-
- bad_server:
- PORT_SetError(SSL_ERROR_BAD_SERVER);
- /* FALL THROUGH */
-
- loser:
- ssl_ReleaseRecvBufLock(ss);
- return SECFailure;
-}
-
-/* Sends out the initial client Hello message on the connection.
- * Acquires and releases the socket's xmitBufLock.
- */
-SECStatus
-ssl2_BeginClientHandshake(sslSocket *ss)
-{
- sslSecurityInfo *sec;
- sslConnectInfo *ci;
- sslSessionID *sid;
- PRUint8 *msg;
- PRUint8 *cp;
- PRUint8 *localCipherSpecs = NULL;
- unsigned int localCipherSize;
- unsigned int i;
- int sendLen, sidLen;
- SECStatus rv;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0));
-
- sec = ss->sec;
- sec->isServer = 0;
- sec->sendSequence = 0;
- sec->rcvSequence = 0;
- ssl_ChooseSessionIDProcs(sec);
- ci = &sec->ci;
-
- if (!ss->cipherSpecs) {
- rv = ssl2_ConstructCipherSpecs(ss);
- if (rv != SECSuccess)
- goto loser;
- }
-
- /* count the SSL2 and SSL3 enabled ciphers.
- * if either is zero, clear the socket's enable for that protocol.
- */
- rv = ssl2_CheckConfigSanity(ss);
- if (rv != SECSuccess)
- goto loser;
-
- /* Get peer name of server */
- rv = ssl_GetPeerInfo(ss);
- if (rv < 0) {
- goto loser;
- }
-
- SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd));
-
- /* Try to find server in our session-id cache */
- if (ss->noCache) {
- sid = NULL;
- } else {
- sid = ssl_LookupSID(ci->peer, ci->port, ss->peerID, ss->url);
- }
- if (sid) {
- /* if we're not doing this SID's protocol any more, drop it. */
- if (((sid->version == SSL_LIBRARY_VERSION_2) && !ss->enableSSL2) ||
- ((sid->version == SSL_LIBRARY_VERSION_3_0) && !ss->enableSSL3) ||
- ((sid->version == SSL_LIBRARY_VERSION_3_1_TLS) && !ss->enableTLS)) {
- sec->uncache(sid);
- ssl_FreeSID(sid);
- goto invalid;
- }
- if (ss->enableSSL2 && sid->version < SSL_LIBRARY_VERSION_3_0) {
- /* If the cipher in this sid is not enabled, drop it. */
- for (i = 0; i < ss->sizeCipherSpecs; i += 3) {
- if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType)
- goto sid_cipher_match;
- }
- sec->uncache(sid);
- ssl_FreeSID(sid);
- goto invalid;
- }
-sid_cipher_match:
- sidLen = sizeof(sid->u.ssl2.sessionID);
- PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID,
- sidLen));
- ss->version = sid->version;
- } else {
-invalid:
- sidLen = 0;
- sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
- if (!sid) {
- goto loser;
- }
- sid->references = 1;
- sid->cached = never_cached;
- sid->addr = ci->peer;
- sid->port = ci->port;
- if (ss->peerID != NULL) {
- sid->peerID = PORT_Strdup(ss->peerID);
- }
- if (ss->url != NULL) {
- sid->urlSvrName = PORT_Strdup(ss->url);
- }
- }
- ci->sid = sid;
-
- PORT_Assert(sid != NULL);
-
- if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->v2CompatibleHello) &&
- (ss->enableSSL3 || ss->enableTLS)) {
-
- PORT_Assert(ss->gather != NULL);
- ss->gather->state = GS_INIT;
- ss->handshake = ssl_GatherRecord1stHandshake;
-
- /* ssl3_SendClientHello will override this if it succeeds. */
- ss->version = SSL_LIBRARY_VERSION_3_0;
-
- ssl_GetXmitBufLock(ss); /***************************************/
- ssl_GetSSL3HandshakeLock(ss);
- rv = ssl3_SendClientHello(ss);
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_ReleaseXmitBufLock(ss); /***************************************/
-
- return rv;
- }
-
- if (!ss->cipherSpecs) {
- rv = ssl2_ConstructCipherSpecs(ss);
- if (rv < 0) {
- return rv;
- }
- }
- localCipherSpecs = ss->cipherSpecs;
- localCipherSize = ss->sizeCipherSpecs;
-
- sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + sidLen +
- SSL_CHALLENGE_BYTES;
-
- /* Generate challenge bytes for server */
- PK11_GenerateRandom(ci->clientChallenge, SSL_CHALLENGE_BYTES);
-
- ssl_GetXmitBufLock(ss); /***************************************/
-
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv)
- goto unlock_loser;
-
- /* Construct client-hello message */
- cp = msg = ci->sendBuf.buf;
- msg[0] = SSL_MT_CLIENT_HELLO;
- if ( ss->enableTLS ) {
- ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_1_TLS;
- } else if ( ss->enableSSL3 ) {
- ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_0;
- } else {
- ss->clientHelloVersion = SSL_LIBRARY_VERSION_2;
- }
-
- msg[1] = MSB(ss->clientHelloVersion);
- msg[2] = LSB(ss->clientHelloVersion);
- msg[3] = MSB(localCipherSize);
- msg[4] = LSB(localCipherSize);
- msg[5] = MSB(sidLen);
- msg[6] = LSB(sidLen);
- msg[7] = MSB(SSL_CHALLENGE_BYTES);
- msg[8] = LSB(SSL_CHALLENGE_BYTES);
- cp += SSL_HL_CLIENT_HELLO_HBYTES;
- PORT_Memcpy(cp, localCipherSpecs, localCipherSize);
- cp += localCipherSize;
- if (sidLen) {
- PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen);
- cp += sidLen;
- }
- PORT_Memcpy(cp, ci->clientChallenge, SSL_CHALLENGE_BYTES);
-
- /* Send it to the server */
- DUMP_MSG(29, (ss, msg, sendLen));
- rv = (*sec->send)(ss, msg, sendLen, 0);
-
- ssl_ReleaseXmitBufLock(ss); /***************************************/
-
- if (rv < 0) {
- goto loser;
- }
-
- rv = ssl3_StartHandshakeHash(ss, msg, sendLen);
- if (rv < 0) {
- goto loser;
- }
-
- /* Setup to receive servers hello message */
- ssl_GetRecvBufLock(ss);
- ss->gather->recordLen = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleServerHelloMessage;
- return SECSuccess;
-
-unlock_loser:
- ssl_ReleaseXmitBufLock(ss);
-loser:
- return SECFailure;
-}
-
-/************************************************************************/
-
-/* Handle the CLIENT-MASTER-KEY message.
-** Acquires and releases RecvBufLock.
-** Called from ssl2_HandleClientHelloMessage().
-*/
-static SECStatus
-ssl2_HandleClientSessionKeyMessage(sslSocket *ss)
-{
- sslConnectInfo * ci;
- PRUint8 * data;
- sslGather * gs;
- unsigned int caLen;
- unsigned int ckLen;
- unsigned int ekLen;
- unsigned int keySize;
- int cipher;
- SECStatus rv;
-
- PORT_Assert((ss->sec != 0) && (ss->gather != 0));
-
- ssl_GetRecvBufLock(ss);
- gs = ss->gather;
- ci = &ss->sec->ci;
-
- data = gs->buf.buf + gs->recordOffset;
- DUMP_MSG(29, (ss, data, gs->recordLen));
-
- if ((gs->recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES)
- || (data[0] != SSL_MT_CLIENT_MASTER_KEY)) {
- goto bad_client;
- }
- cipher = data[1];
- keySize = (data[2] << 8) | data[3];
- ckLen = (data[4] << 8) | data[5];
- ekLen = (data[6] << 8) | data[7];
- caLen = (data[8] << 8) | data[9];
-
- SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keySize=%d ckLen=%d ekLen=%d caLen=%d",
- SSL_GETPID(), ss->fd, cipher, keySize, ckLen, ekLen, caLen));
-
- if (gs->recordLen <
- SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) {
- SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d",
- SSL_GETPID(), ss->fd, gs->recordLen));
- goto bad_client;
- }
-
- /* Use info from client to setup session key */
- /* XXX should validate cipher&keySize are in our array */
- rv = ssl2_ServerSetupSessionCypher(ss, cipher, keySize,
- data + SSL_HL_CLIENT_MASTER_KEY_HBYTES, ckLen,
- data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen, ekLen,
- data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen);
- ss->gather->recordLen = 0; /* we're done with this record. */
-
- ssl_ReleaseRecvBufLock(ss);
-
- if (rv != SECSuccess) {
- goto loser;
- }
- ci->elements |= CIS_HAVE_MASTER_KEY;
- ssl2_UseEncryptedSendFunc(ss);
-
- /* Send server verify message now that keys are established */
- rv = ssl2_SendServerVerifyMessage(ss);
- if (rv != SECSuccess)
- goto loser;
-
- rv = ssl2_TryToFinish(ss);
- if (rv != SECSuccess)
- goto loser;
- if (ss->handshake == 0) {
- return SECSuccess;
- }
-
- SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d",
- SSL_GETPID(), ss->fd, ci->requiredElements ^ ci->elements));
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleMessage;
-
- return ssl2_TriggerNextMessage(ss);
-
-bad_client:
- ssl_ReleaseRecvBufLock(ss);
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- /* FALLTHROUGH */
-
-loser:
- return SECFailure;
-}
-
-/*
- * attempt to restart the handshake after asynchronously handling
- * a request for the client's certificate.
- *
- * inputs:
- * cert Client cert chosen by application.
- * key Private key associated with cert.
- *
- * XXX: need to make ssl2 and ssl3 versions of this function agree on whether
- * they take the reference, or bump the ref count!
- *
- * Return value: XXX
- *
- * Caller holds 1stHandshakeLock.
- */
-int
-ssl2_RestartHandshakeAfterCertReq(sslSocket * ss,
- CERTCertificate * cert,
- SECKEYPrivateKey * key)
-{
- int ret;
- SECStatus rv = SECSuccess;
- SECItem response;
-
- if (ss->version >= SSL_LIBRARY_VERSION_3_0)
- return SECFailure;
-
- response.data = NULL;
-
- PORT_Assert((ss->sec != 0));
- if (ss->sec == NULL)
- return SECFailure;
-
- /* generate error if no cert or key */
- if ( ( cert == NULL ) || ( key == NULL ) ) {
- goto no_cert;
- }
-
- /* generate signed response to the challenge */
- rv = ssl2_SignResponse(ss, key, &response);
- if ( rv != SECSuccess ) {
- goto no_cert;
- }
-
- /* Send response message */
- ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);
- if (ret) {
- goto no_cert;
- }
-
- /* try to finish the handshake */
- ret = ssl2_TryToFinish(ss);
- if (ret) {
- goto loser;
- }
-
- /* done with handshake */
- if (ss->handshake == 0) {
- ret = SECSuccess;
- goto done;
- }
-
- /* continue handshake */
- ssl_GetRecvBufLock(ss);
- ss->gather->recordLen = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleMessage;
- ret = ssl2_TriggerNextMessage(ss);
- goto done;
-
-no_cert:
- /* no cert - send error */
- ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);
- goto done;
-
-loser:
- ret = SECFailure;
-done:
- /* free allocated data */
- if ( response.data ) {
- PORT_Free(response.data);
- }
-
- return ret;
-}
-
-
-/* restart an SSL connection that we stopped to run certificate dialogs
-** XXX Need to document here how an application marks a cert to show that
-** the application has accepted it (overridden CERT_VerifyCert).
- *
- * Return value: XXX
- *
- * Caller holds 1stHandshakeLock.
-*/
-int
-ssl2_RestartHandshakeAfterServerCert(sslSocket *ss)
-{
- int rv = SECSuccess;
-
- if (ss->version >= SSL_LIBRARY_VERSION_3_0)
- return SECFailure;
-
- /* SSL 2
- ** At this point we have a completed session key and our session
- ** cipher is setup and ready to go. Switch to encrypted write routine
- ** as all future message data is to be encrypted.
- */
- ssl2_UseEncryptedSendFunc(ss);
-
- rv = ssl2_TryToFinish(ss);
- if (rv == SECSuccess && ss->handshake != NULL) {
- /* handshake is not yet finished. */
-
- SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
- SSL_GETPID(), ss->fd, ss->sec->ci.requiredElements,
- ss->sec->ci.elements));
-
- ssl_GetRecvBufLock(ss);
- ss->gather->recordLen = 0; /* mark it all used up. */
- ssl_ReleaseRecvBufLock(ss);
-
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleVerifyMessage;
- }
-
- return rv;
-}
-
-/*
-** Handle the initial hello message from the client
-**
-** not static because ssl2_GatherData() tests ss->nextHandshake for this value.
-*/
-SECStatus
-ssl2_HandleClientHelloMessage(sslSocket *ss)
-{
- sslSecurityInfo *sec;
- sslConnectInfo *ci;
- sslGather *gs;
- sslSessionID *sid = NULL;
- PRUint8 *msg;
- PRUint8 *data;
- PRUint8 *cs;
- PRUint8 *sd;
- PRUint8 *cert = NULL;
- PRUint8 *challenge;
- unsigned int challengeLen;
- SECStatus rv;
- int hit;
- int csLen;
- int sendLen;
- int sdLen;
- int certLen;
- int pid;
- int sent;
- int gotXmitBufLock = 0;
- PRUint8 csImpl[sizeof implementedCipherSuites];
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert((ss->sec != 0) && (ss->gather != 0));
-
- sec = ss->sec;
- ci = &sec->ci;
-
- ssl_GetRecvBufLock(ss);
-
- gs = ss->gather;
-
- data = gs->buf.buf + gs->recordOffset;
- DUMP_MSG(29, (ss, data, gs->recordLen));
-
- /* Make sure first message has some data and is the client hello message */
- if ((gs->recordLen < SSL_HL_CLIENT_HELLO_HBYTES)
- || (data[0] != SSL_MT_CLIENT_HELLO)) {
- goto bad_client;
- }
-
- /* Get peer name of client */
- rv = ssl_GetPeerInfo(ss);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* Examine version information */
- /*
- * See if this might be a V2 client hello asking to use the V3 protocol
- */
- if ((data[0] == SSL_MT_CLIENT_HELLO) &&
- (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) &&
- (ss->enableSSL3 || ss->enableTLS)) {
- rv = ssl3_HandleV2ClientHello(ss, data, gs->recordLen);
- if (rv != SECFailure) { /* Success */
- ss->handshake = NULL;
- ss->nextHandshake = ssl_GatherRecord1stHandshake;
- ss->securityHandshake = NULL;
- ss->gather->state = GS_INIT;
-
- /* ssl3_HandleV3ClientHello has set ss->version,
- ** and has gotten us a brand new sid.
- */
- ss->sec->ci.sid->version = ss->version;
- }
- ssl_ReleaseRecvBufLock(ss);
- return rv;
- }
- /* Previously, there was a test here to see if SSL2 was enabled.
- ** If not, an error code was set, and SECFailure was returned,
- ** without sending any error code to the other end of the connection.
- ** That test has been removed. If SSL2 has been disabled, there
- ** should be no SSL2 ciphers enabled, and consequently, the code
- ** below should send the ssl2 error message SSL_PE_NO_CYPHERS.
- ** We now believe this is the correct thing to do, even when SSL2
- ** has been explicitly disabled by the application.
- */
-
- /* Extract info from message */
- ss->version = (data[1] << 8) | data[2];
-
- /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it. */
- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
- ss->version = SSL_LIBRARY_VERSION_2;
- }
-
- csLen = (data[3] << 8) | data[4];
- sdLen = (data[5] << 8) | data[6];
- challengeLen = (data[7] << 8) | data[8];
- cs = data + SSL_HL_CLIENT_HELLO_HBYTES;
- sd = cs + csLen;
- challenge = sd + sdLen;
- PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen));
-
- if ((unsigned)gs->recordLen !=
- SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) {
- SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d",
- SSL_GETPID(), ss->fd, gs->recordLen,
- SSL_HL_CLIENT_HELLO_HBYTES+csLen+sdLen+challengeLen));
- goto bad_client;
- }
-
- SSL_TRC(3, ("%d: SSL[%d]: client version is %x",
- SSL_GETPID(), ss->fd, ss->version));
- if (ss->version != SSL_LIBRARY_VERSION_2) {
- if (ss->version > SSL_LIBRARY_VERSION_2) {
- /*
- ** Newer client than us. Things are ok because new clients
- ** are required to be backwards compatible with old servers.
- ** Change version number to our version number so that client
- ** knows whats up.
- */
- ss->version = SSL_LIBRARY_VERSION_2;
- } else {
- SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)",
- SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
- PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
- goto loser;
- }
- }
-
- /* Qualify cipher specs before returning them to client */
- csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
- if (csLen == 0) {
- /* no overlap, send client our list of supported SSL v2 ciphers. */
- cs = csImpl;
- csLen = sizeof implementedCipherSuites;
- PORT_Memcpy(cs, implementedCipherSuites, csLen);
- csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
- if (csLen == 0) {
- /* We don't support any SSL v2 ciphers! */
- ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- goto loser;
- }
- /* Since this handhsake is going to fail, don't cache it. */
- ss->noCache = 1;
- }
-
- /* Squirrel away the challenge for later */
- PORT_Memcpy(ci->clientChallenge, challenge, challengeLen);
-
- /* Examine message and see if session-id is good */
- ci->elements = 0;
- if (ss->noCache) {
- sid = NULL;
- } else if (sdLen) {
- SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x",
- SSL_GETPID(), ss->fd, ci->peer));
- sid = (*ssl_sid_lookup)(ci->peer, sd, sdLen, ss->dbHandle);
- }
- if (sid) {
- /* Got a good session-id. Short cut! */
- SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)",
- SSL_GETPID(), ss->fd, ci->peer, ssl_Time() - sid->time));
- PRINT_BUF(1, (ss, "session-id value:", sd, sdLen));
- ci->sid = sid;
- ci->elements = CIS_HAVE_MASTER_KEY;
- hit = 1;
- certLen = 0;
- csLen = 0;
- rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
- if (rv != SECSuccess) {
- goto loser;
- }
- } else {
- SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed",
- SSL_GETPID(), ss->fd));
- hit = 0;
- sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
- if (!sid) {
- goto loser;
- }
- sid->references = 1;
- sid->addr = ci->peer;
- sid->port = ci->port;
-
- /* Invent a session-id */
- ci->sid = sid;
- PK11_GenerateRandom(sid->u.ssl2.sessionID+2, SSL_SESSIONID_BYTES-2);
-
- pid = SSL_GETPID();
- sid->u.ssl2.sessionID[0] = MSB(pid);
- sid->u.ssl2.sessionID[1] = LSB(pid);
- cert = ss->serverCert[kt_rsa]->derCert.data;
- certLen = ss->serverCert[kt_rsa]->derCert.len;
- }
-
- /* Build up final list of required elements */
- ci->requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED;
- if (ss->requestCertificate) {
- ci->requiredElements |= CIS_HAVE_CERTIFICATE;
- }
- ci->sentElements = 0;
-
- /* Send hello message back to client */
- sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen
- + SSL_CONNECTIONID_BYTES;
-
- ssl_GetXmitBufLock(ss); gotXmitBufLock = 1;
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)",
- SSL_GETPID(), ss->fd, sendLen));
-
- msg = ci->sendBuf.buf;
- msg[0] = SSL_MT_SERVER_HELLO;
- msg[1] = hit;
- msg[2] = SSL_CT_X509_CERTIFICATE;
- msg[3] = MSB(ss->version);
- msg[4] = LSB(ss->version);
- msg[5] = MSB(certLen);
- msg[6] = LSB(certLen);
- msg[7] = MSB(csLen);
- msg[8] = LSB(csLen);
- msg[9] = MSB(SSL_CONNECTIONID_BYTES);
- msg[10] = LSB(SSL_CONNECTIONID_BYTES);
- if (certLen) {
- PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES, cert, certLen);
- }
- if (csLen) {
- PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen, cs, csLen);
- }
- PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen, ci->connectionID,
- SSL_CONNECTIONID_BYTES);
-
- DUMP_MSG(29, (ss, msg, sendLen));
-
- sent = (*sec->send)(ss, msg, sendLen, 0);
- if (sent < 0) {
- goto loser;
- }
- ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
-
- ss->gather->recordLen = 0;
- ss->handshake = ssl_GatherRecord1stHandshake;
- if (hit) {
- /* Old SID Session key is good. Go encrypted */
- ssl2_UseEncryptedSendFunc(ss);
-
- /* Send server verify message now that keys are established */
- rv = ssl2_SendServerVerifyMessage(ss);
- if (rv != SECSuccess)
- goto loser;
-
- ss->nextHandshake = ssl2_HandleMessage;
- ssl_ReleaseRecvBufLock(ss);
- rv = ssl2_TriggerNextMessage(ss);
- return rv;
- }
- ss->nextHandshake = ssl2_HandleClientSessionKeyMessage;
- ssl_ReleaseRecvBufLock(ss);
- return SECSuccess;
-
- bad_client:
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- /* FALLTHROUGH */
-
- loser:
- if (gotXmitBufLock) {
- ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
- }
- SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage",
- SSL_GETPID(), ss->fd));
- ssl_ReleaseRecvBufLock(ss);
- return SECFailure;
-}
-
-SECStatus
-ssl2_BeginServerHandshake(sslSocket *ss)
-{
- sslSecurityInfo *sec;
- sslConnectInfo * ci;
- SECStatus rv;
-
- PORT_Assert((ss->sec != 0));
- sec = ss->sec;
- ci = &sec->ci;
- sec->isServer = 1;
- ssl_ChooseSessionIDProcs(sec);
- sec->sendSequence = 0;
- sec->rcvSequence = 0;
-
- /* don't turn on SSL2 if we don't have an RSA key and cert */
- if (!ss->serverKey[kt_rsa] || !ss->serverCert[kt_rsa]) {
- ss->enableSSL2 = PR_FALSE;
- }
-
- if (!ss->cipherSpecs) {
- rv = ssl2_ConstructCipherSpecs(ss);
- if (rv != SECSuccess)
- goto loser;
- }
-
- /* count the SSL2 and SSL3 enabled ciphers.
- * if either is zero, clear the socket's enable for that protocol.
- */
- rv = ssl2_CheckConfigSanity(ss);
- if (rv != SECSuccess)
- goto loser;
-
- /*
- ** Generate connection-id. Always do this, even if things fail
- ** immediately. This way the random number generator is always
- ** rolling around, every time we get a connection.
- */
- PK11_GenerateRandom(ci->connectionID, sizeof(ci->connectionID));
-
- ss->gather->recordLen = 0;
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleClientHelloMessage;
- return SECSuccess;
-
-loser:
- return SECFailure;
-}
-
diff --git a/security/nss/lib/ssl/ssldef.c b/security/nss/lib/ssl/ssldef.c
deleted file mode 100644
index 7f16c26b7..000000000
--- a/security/nss/lib/ssl/ssldef.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * "Default" SSLSocket methods, used by sockets that do neither SSL nor socks.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-
-#if defined(WIN32)
-#define MAP_ERROR(from,to) if (err == from) { PORT_SetError(to); }
-#else
-#define MAP_ERROR(from,to)
-#endif
-
-int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->connect(lower, sa, ss->cTimeout);
- return rv;
-}
-
-int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->bind(lower, addr);
- return rv;
-}
-
-int ssl_DefListen(sslSocket *ss, int backlog)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->listen(lower, backlog);
- return rv;
-}
-
-int ssl_DefShutdown(sslSocket *ss, int how)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->shutdown(lower, how);
- return rv;
-}
-
-int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout);
- if (rv < 0) {
- PRErrorCode err = PR_GetError();
- MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
- }
- return rv;
-}
-
-/* Default (unencrypted) send.
- * Returns SECSuccess or SECFailure, NOT SECWouldBlock.
- * Returns positive count if any data was written.
- * ALWAYS check for a short write after calling ssl_DefSend.
- */
-int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv, count;
-
- count = 0;
- for (;;) {
- rv = lower->methods->send(lower, (const void *)buf, len,
- flags, ss->wTimeout);
- if (rv < 0) {
- PRErrorCode err = PR_GetError();
- if (err == PR_WOULD_BLOCK_ERROR) {
- return count ? count : rv;
- }
- MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
- /* Loser */
- return rv;
- }
- count += rv;
- if (rv < len) {
- /* Short send. Send the rest in the next call */
- buf += rv;
- len -= rv;
- continue;
- }
- break;
- }
- return count;
-}
-
-int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->read(lower, (void *)buf, len);
- if (rv < 0) {
- PRErrorCode err = PR_GetError();
- MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
- }
- return rv;
-}
-
-int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv, count;
-
- count = 0;
- for (;;) {
- rv = lower->methods->write(lower, (void *)buf, len);
- if (rv < 0) {
- PRErrorCode err = PR_GetError();
- if (err == PR_WOULD_BLOCK_ERROR) {
- return count ? count : rv;
- }
- MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
- /* Loser */
- return rv;
- }
- count += rv;
- if (rv != len) {
- /* Short write. Send the rest in the next call */
- buf += rv;
- len -= rv;
- continue;
- }
- break;
- }
- return count;
-}
-
-int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->getpeername(lower, name);
- return rv;
-}
-
-int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->getsockname(lower, name);
- return rv;
-}
-
-int ssl_DefClose(sslSocket *ss)
-{
- PRFileDesc *fd;
- PRFileDesc *popped;
- int rv;
-
- fd = ss->fd;
-
- /* First, remove the SSL layer PRFileDesc from the socket's stack,
- ** then invoke the SSL layer's PRFileDesc destructor.
- ** This must happen before the next layer down is closed.
- */
- PORT_Assert(fd->higher == NULL);
- if (fd->higher) {
- PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
- return SECFailure;
- }
- ss->fd = NULL;
-
- /* PR_PopIOLayer will swap the contents of the top two PRFileDescs on
- ** the stack, and then remove the second one. This way, the address
- ** of the PRFileDesc on the top of the stack doesn't change.
- */
- popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
- popped->dtor(popped);
-
- /* fd is now the PRFileDesc for the next layer down.
- ** Now close the underlying socket.
- */
- rv = fd->methods->close(fd);
-
- ssl_FreeSocket(ss);
-
- SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d",
- SSL_GETPID(), fd, rv, PORT_GetError()));
- return rv;
-}
diff --git a/security/nss/lib/ssl/sslenum.c b/security/nss/lib/ssl/sslenum.c
deleted file mode 100644
index b94f4bf65..000000000
--- a/security/nss/lib/ssl/sslenum.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Table enumerating all implemented cipher suites
- * Part of public API.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "ssl.h"
-#include "sslproto.h"
-
-const PRUint16 SSL_ImplementedCiphers[] = {
-
- SSL_RSA_WITH_NULL_MD5,
- SSL_RSA_EXPORT_WITH_RC4_40_MD5,
- SSL_RSA_WITH_RC4_128_MD5,
- SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- SSL_RSA_WITH_DES_CBC_SHA,
- SSL_RSA_WITH_3DES_EDE_CBC_SHA,
-
- SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,
- SSL_FORTEZZA_DMS_WITH_NULL_SHA,
- SSL_FORTEZZA_DMS_WITH_RC4_128_SHA,
-
- TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
- TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
-
- /* SSL2 cipher suites. */
- SSL_EN_RC4_128_WITH_MD5,
- SSL_EN_RC4_128_EXPORT40_WITH_MD5,
- SSL_EN_RC2_128_CBC_WITH_MD5,
- SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5,
- SSL_EN_DES_64_CBC_WITH_MD5,
- SSL_EN_DES_192_EDE3_CBC_WITH_MD5,
-
- /* Netscape "experimental" cipher suites. */
- SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
- SSL_RSA_FIPS_WITH_DES_CBC_SHA,
-
- 0
-
-};
-
-const PRUint16 SSL_NumImplementedCiphers =
- (sizeof SSL_ImplementedCiphers) / (sizeof SSL_ImplementedCiphers[0]) - 1;
-
diff --git a/security/nss/lib/ssl/sslerr.c b/security/nss/lib/ssl/sslerr.c
deleted file mode 100644
index 5a2d27a3e..000000000
--- a/security/nss/lib/ssl/sslerr.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Function to set error code only when meaningful error has not already
- * been set.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "prerror.h"
-#include "secerr.h"
-#include "sslerr.h"
-#include "seccomon.h"
-
-/* look at the current value of PR_GetError, and evaluate it to see
- * if it is meaningful or meaningless (out of context).
- * If it is meaningless, replace it with the hiLevelError.
- * Returns the chosen error value.
- */
-int
-ssl_MapLowLevelError(int hiLevelError)
-{
- int oldErr = PORT_GetError();
-
- switch (oldErr) {
-
- case 0:
- case PR_IO_ERROR:
- case SEC_ERROR_IO:
- case SEC_ERROR_BAD_DATA:
- case SEC_ERROR_LIBRARY_FAILURE:
- case SSL_ERROR_BAD_CLIENT:
- case SSL_ERROR_BAD_SERVER:
- PORT_SetError(hiLevelError);
- return hiLevelError;
-
- default: /* leave the majority of error codes alone. */
- return oldErr;
- }
-}
diff --git a/security/nss/lib/ssl/sslerr.h b/security/nss/lib/ssl/sslerr.h
deleted file mode 100644
index 3285fb60c..000000000
--- a/security/nss/lib/ssl/sslerr.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Enumeration of all SSL-specific error codes.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-#ifndef __SSL_ERR_H_
-#define __SSL_ERR_H_
-
-
-#define SSL_ERROR_BASE (-0x3000)
-#define SSL_ERROR_LIMIT (SSL_ERROR_BASE + 1000)
-
-#define IS_SSL_ERROR(code) \
- (((code) >= SSL_ERROR_BASE) && ((code) < SSL_ERROR_LIMIT))
-
-#ifndef NO_SECURITY_ERROR_ENUM
-typedef enum {
-SSL_ERROR_EXPORT_ONLY_SERVER = (SSL_ERROR_BASE + 0),
-SSL_ERROR_US_ONLY_SERVER = (SSL_ERROR_BASE + 1),
-SSL_ERROR_NO_CYPHER_OVERLAP = (SSL_ERROR_BASE + 2),
-/*
- * Received an alert reporting what we did wrong. (more alerts below)
- */
-SSL_ERROR_NO_CERTIFICATE /*_ALERT */ = (SSL_ERROR_BASE + 3),
-SSL_ERROR_BAD_CERTIFICATE = (SSL_ERROR_BASE + 4),
- /* error 5 is obsolete */
-SSL_ERROR_BAD_CLIENT = (SSL_ERROR_BASE + 6),
-SSL_ERROR_BAD_SERVER = (SSL_ERROR_BASE + 7),
-SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE = (SSL_ERROR_BASE + 8),
-SSL_ERROR_UNSUPPORTED_VERSION = (SSL_ERROR_BASE + 9),
- /* error 10 is obsolete */
-SSL_ERROR_WRONG_CERTIFICATE = (SSL_ERROR_BASE + 11),
-SSL_ERROR_BAD_CERT_DOMAIN = (SSL_ERROR_BASE + 12),
-SSL_ERROR_POST_WARNING = (SSL_ERROR_BASE + 13),
-SSL_ERROR_SSL2_DISABLED = (SSL_ERROR_BASE + 14),
-SSL_ERROR_BAD_MAC_READ = (SSL_ERROR_BASE + 15),
-/*
- * Received an alert reporting what we did wrong.
- * (two more alerts above, and many more below)
- */
-SSL_ERROR_BAD_MAC_ALERT = (SSL_ERROR_BASE + 16),
-SSL_ERROR_BAD_CERT_ALERT = (SSL_ERROR_BASE + 17),
-SSL_ERROR_REVOKED_CERT_ALERT = (SSL_ERROR_BASE + 18),
-SSL_ERROR_EXPIRED_CERT_ALERT = (SSL_ERROR_BASE + 19),
-
-SSL_ERROR_SSL_DISABLED = (SSL_ERROR_BASE + 20),
-SSL_ERROR_FORTEZZA_PQG = (SSL_ERROR_BASE + 21),
-SSL_ERROR_UNKNOWN_CIPHER_SUITE = (SSL_ERROR_BASE + 22),
-SSL_ERROR_NO_CIPHERS_SUPPORTED = (SSL_ERROR_BASE + 23),
-SSL_ERROR_BAD_BLOCK_PADDING = (SSL_ERROR_BASE + 24),
-SSL_ERROR_RX_RECORD_TOO_LONG = (SSL_ERROR_BASE + 25),
-SSL_ERROR_TX_RECORD_TOO_LONG = (SSL_ERROR_BASE + 26),
-/*
- * Received a malformed (too long or short) SSL handshake.
- */
-SSL_ERROR_RX_MALFORMED_HELLO_REQUEST = (SSL_ERROR_BASE + 27),
-SSL_ERROR_RX_MALFORMED_CLIENT_HELLO = (SSL_ERROR_BASE + 28),
-SSL_ERROR_RX_MALFORMED_SERVER_HELLO = (SSL_ERROR_BASE + 29),
-SSL_ERROR_RX_MALFORMED_CERTIFICATE = (SSL_ERROR_BASE + 30),
-SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH = (SSL_ERROR_BASE + 31),
-SSL_ERROR_RX_MALFORMED_CERT_REQUEST = (SSL_ERROR_BASE + 32),
-SSL_ERROR_RX_MALFORMED_HELLO_DONE = (SSL_ERROR_BASE + 33),
-SSL_ERROR_RX_MALFORMED_CERT_VERIFY = (SSL_ERROR_BASE + 34),
-SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH = (SSL_ERROR_BASE + 35),
-SSL_ERROR_RX_MALFORMED_FINISHED = (SSL_ERROR_BASE + 36),
-/*
- * Received a malformed (too long or short) SSL record.
- */
-SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER = (SSL_ERROR_BASE + 37),
-SSL_ERROR_RX_MALFORMED_ALERT = (SSL_ERROR_BASE + 38),
-SSL_ERROR_RX_MALFORMED_HANDSHAKE = (SSL_ERROR_BASE + 39),
-SSL_ERROR_RX_MALFORMED_APPLICATION_DATA = (SSL_ERROR_BASE + 40),
-/*
- * Received an SSL handshake that was inappropriate for the state we're in.
- * E.g. Server received message from server, or wrong state in state machine.
- */
-SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST = (SSL_ERROR_BASE + 41),
-SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO = (SSL_ERROR_BASE + 42),
-SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO = (SSL_ERROR_BASE + 43),
-SSL_ERROR_RX_UNEXPECTED_CERTIFICATE = (SSL_ERROR_BASE + 44),
-SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH = (SSL_ERROR_BASE + 45),
-SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST = (SSL_ERROR_BASE + 46),
-SSL_ERROR_RX_UNEXPECTED_HELLO_DONE = (SSL_ERROR_BASE + 47),
-SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY = (SSL_ERROR_BASE + 48),
-SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH = (SSL_ERROR_BASE + 49),
-SSL_ERROR_RX_UNEXPECTED_FINISHED = (SSL_ERROR_BASE + 50),
-/*
- * Received an SSL record that was inappropriate for the state we're in.
- */
-SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER = (SSL_ERROR_BASE + 51),
-SSL_ERROR_RX_UNEXPECTED_ALERT = (SSL_ERROR_BASE + 52),
-SSL_ERROR_RX_UNEXPECTED_HANDSHAKE = (SSL_ERROR_BASE + 53),
-SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA= (SSL_ERROR_BASE + 54),
-/*
- * Received record/message with unknown discriminant.
- */
-SSL_ERROR_RX_UNKNOWN_RECORD_TYPE = (SSL_ERROR_BASE + 55),
-SSL_ERROR_RX_UNKNOWN_HANDSHAKE = (SSL_ERROR_BASE + 56),
-SSL_ERROR_RX_UNKNOWN_ALERT = (SSL_ERROR_BASE + 57),
-/*
- * Received an alert reporting what we did wrong. (more alerts above)
- */
-SSL_ERROR_CLOSE_NOTIFY_ALERT = (SSL_ERROR_BASE + 58),
-SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT = (SSL_ERROR_BASE + 59),
-SSL_ERROR_DECOMPRESSION_FAILURE_ALERT = (SSL_ERROR_BASE + 60),
-SSL_ERROR_HANDSHAKE_FAILURE_ALERT = (SSL_ERROR_BASE + 61),
-SSL_ERROR_ILLEGAL_PARAMETER_ALERT = (SSL_ERROR_BASE + 62),
-SSL_ERROR_UNSUPPORTED_CERT_ALERT = (SSL_ERROR_BASE + 63),
-SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT = (SSL_ERROR_BASE + 64),
-
-SSL_ERROR_GENERATE_RANDOM_FAILURE = (SSL_ERROR_BASE + 65),
-SSL_ERROR_SIGN_HASHES_FAILURE = (SSL_ERROR_BASE + 66),
-SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE = (SSL_ERROR_BASE + 67),
-SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE = (SSL_ERROR_BASE + 68),
-SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE = (SSL_ERROR_BASE + 69),
-
-SSL_ERROR_ENCRYPTION_FAILURE = (SSL_ERROR_BASE + 70),
-SSL_ERROR_DECRYPTION_FAILURE = (SSL_ERROR_BASE + 71),
-SSL_ERROR_SOCKET_WRITE_FAILURE = (SSL_ERROR_BASE + 72),
-
-SSL_ERROR_MD5_DIGEST_FAILURE = (SSL_ERROR_BASE + 73),
-SSL_ERROR_SHA_DIGEST_FAILURE = (SSL_ERROR_BASE + 74),
-SSL_ERROR_MAC_COMPUTATION_FAILURE = (SSL_ERROR_BASE + 75),
-SSL_ERROR_SYM_KEY_CONTEXT_FAILURE = (SSL_ERROR_BASE + 76),
-SSL_ERROR_SYM_KEY_UNWRAP_FAILURE = (SSL_ERROR_BASE + 77),
-SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED = (SSL_ERROR_BASE + 78),
-SSL_ERROR_IV_PARAM_FAILURE = (SSL_ERROR_BASE + 79),
-SSL_ERROR_INIT_CIPHER_SUITE_FAILURE = (SSL_ERROR_BASE + 80),
-SSL_ERROR_SESSION_KEY_GEN_FAILURE = (SSL_ERROR_BASE + 81),
-SSL_ERROR_NO_SERVER_KEY_FOR_ALG = (SSL_ERROR_BASE + 82),
-SSL_ERROR_TOKEN_INSERTION_REMOVAL = (SSL_ERROR_BASE + 83),
-SSL_ERROR_TOKEN_SLOT_NOT_FOUND = (SSL_ERROR_BASE + 84),
-SSL_ERROR_NO_COMPRESSION_OVERLAP = (SSL_ERROR_BASE + 85),
-SSL_ERROR_HANDSHAKE_NOT_COMPLETED = (SSL_ERROR_BASE + 86),
-SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE = (SSL_ERROR_BASE + 87),
-SSL_ERROR_CERT_KEA_MISMATCH = (SSL_ERROR_BASE + 88),
-SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA = (SSL_ERROR_BASE + 89),
-SSL_ERROR_SESSION_NOT_FOUND = (SSL_ERROR_BASE + 90),
-
-SSL_ERROR_DECRYPTION_FAILED_ALERT = (SSL_ERROR_BASE + 91),
-SSL_ERROR_RECORD_OVERFLOW_ALERT = (SSL_ERROR_BASE + 92),
-SSL_ERROR_UNKNOWN_CA_ALERT = (SSL_ERROR_BASE + 93),
-SSL_ERROR_ACCESS_DENIED_ALERT = (SSL_ERROR_BASE + 94),
-SSL_ERROR_DECODE_ERROR_ALERT = (SSL_ERROR_BASE + 95),
-SSL_ERROR_DECRYPT_ERROR_ALERT = (SSL_ERROR_BASE + 96),
-SSL_ERROR_EXPORT_RESTRICTION_ALERT = (SSL_ERROR_BASE + 97),
-SSL_ERROR_PROTOCOL_VERSION_ALERT = (SSL_ERROR_BASE + 98),
-SSL_ERROR_INSUFFICIENT_SECURITY_ALERT = (SSL_ERROR_BASE + 99),
-SSL_ERROR_INTERNAL_ERROR_ALERT = (SSL_ERROR_BASE + 100),
-SSL_ERROR_USER_CANCELED_ALERT = (SSL_ERROR_BASE + 101),
-SSL_ERROR_NO_RENEGOTIATION_ALERT = (SSL_ERROR_BASE + 102),
-
-SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
-} SSLErrorCodes;
-#endif /* NO_SECURITY_ERROR_ENUM */
-
-#endif /* __SSL_ERR_H_ */
diff --git a/security/nss/lib/ssl/sslgathr.c b/security/nss/lib/ssl/sslgathr.c
deleted file mode 100644
index 737a55c9b..000000000
--- a/security/nss/lib/ssl/sslgathr.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * Gather (Read) entire SSL2 records from socket into buffer.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-
-/* Forward static declarations */
-static SECStatus ssl2_HandleV3HandshakeRecord(sslSocket *ss);
-
-/*
-** Gather a single record of data from the receiving stream. This code
-** first gathers the header (2 or 3 bytes long depending on the value of
-** the most significant bit in the first byte) then gathers up the data
-** for the record into gs->buf. This code handles non-blocking I/O
-** and is to be called multiple times until sec->recordLen != 0.
-** This function decrypts the gathered record in place, in gs_buf.
- *
- * Caller must hold RecvBufLock.
- *
- * Returns +1 when it has gathered a complete SSLV2 record.
- * Returns 0 if it hits EOF.
- * Returns -1 (SECFailure) on any error
- * Returns -2 (SECWouldBlock) when it gathers an SSL v3 client hello header.
-**
-** The SSL2 Gather State machine has 4 states:
-** GS_INIT - Done reading in previous record. Haven't begun to read in
-** next record. When ssl2_GatherData is called with the machine
-** in this state, the machine will attempt to read the first 3
-** bytes of the SSL2 record header, and will advance the state
-** to GS_HEADER.
-**
-** GS_HEADER - The machine is in this state while waiting for the completion
-** of the first 3 bytes of the SSL2 record. When complete, the
-** machine will compute the remaining unread length of this record
-** and will initiate a read of that many bytes. The machine will
-** advance to one of two states, depending on whether the record
-** is encrypted (GS_MAC), or unencrypted (GS_DATA).
-**
-** GS_MAC - The machine is in this state while waiting for the remainder
-** of the SSL2 record to be read in. When the read is completed,
-** the machine checks the record for valid length, decrypts it,
-** and checks and discards the MAC, then advances to GS_INIT.
-**
-** GS_DATA - The machine is in this state while waiting for the remainder
-** of the unencrypted SSL2 record to be read in. Upon completion,
-** the machine advances to the GS_INIT state and returns the data.
-*/
-int
-ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags)
-{
- sslSecurityInfo *sec = ss->sec;
- unsigned char * bp;
- unsigned char * pBuf;
- int nb, err, rv;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
-
- if (gs->state == GS_INIT) {
- /* Initialize gathering engine */
- gs->state = GS_HEADER;
- gs->remainder = 3;
- gs->count = 3;
- gs->offset = 0;
- gs->recordLen = 0;
- gs->recordPadding = 0;
- gs->hdr[2] = 0;
-
- gs->writeOffset = 0;
- gs->readOffset = 0;
- }
- if (gs->encrypted) {
- PORT_Assert(sec != 0);
- }
-
- pBuf = gs->buf.buf;
- for (;;) {
- SSL_TRC(30, ("%d: SSL[%d]: gather state %d (need %d more)",
- SSL_GETPID(), ss->fd, gs->state, gs->remainder));
- bp = ((gs->state != GS_HEADER) ? pBuf : gs->hdr) + gs->offset;
- nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
- if (nb > 0) {
- PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
- }
- if (nb == 0) {
- /* EOF */
- SSL_TRC(30, ("%d: SSL[%d]: EOF", SSL_GETPID(), ss->fd));
- rv = 0;
- break;
- }
- if (nb < 0) {
- SSL_DBG(("%d: SSL[%d]: recv error %d", SSL_GETPID(), ss->fd,
- PR_GetError()));
- rv = SECFailure;
- break;
- }
-
- gs->offset += nb;
- gs->remainder -= nb;
-
- if (gs->remainder > 0) {
- continue;
- }
-
- /* Probably finished this piece */
- switch (gs->state) {
- case GS_HEADER:
- if ((ss->enableSSL3 || ss->enableTLS) && !ss->connected) {
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
-
- /* If this looks like an SSL3 handshake record,
- ** and we're expecting an SSL2 Hello message from our peer,
- ** handle it here.
- */
- if (gs->hdr[0] == content_handshake) {
- if ((ss->nextHandshake == ssl2_HandleClientHelloMessage) ||
- (ss->nextHandshake == ssl2_HandleServerHelloMessage)) {
- rv = ssl2_HandleV3HandshakeRecord(ss);
- if (rv == SECFailure) {
- return SECFailure;
- }
- }
- /* XXX_1 The call stack to here is:
- * ssl_Do1stHandshake -> ssl_GatherRecord1stHandshake ->
- * ssl2_GatherRecord -> here.
- * We want to return all the way out to ssl_Do1stHandshake,
- * and have it call ssl_GatherRecord1stHandshake again.
- * ssl_GatherRecord1stHandshake will call
- * ssl3_GatherCompleteHandshake when it is called again.
- *
- * Returning SECWouldBlock here causes
- * ssl_GatherRecord1stHandshake to return without clearing
- * ss->handshake, ensuring that ssl_Do1stHandshake will
- * call it again immediately.
- *
- * If we return 1 here, ssl_GatherRecord1stHandshake will
- * clear ss->handshake before returning, and thus will not
- * be called again by ssl_Do1stHandshake.
- */
- return SECWouldBlock;
- } else if (gs->hdr[0] == content_alert) {
- if (ss->nextHandshake == ssl2_HandleServerHelloMessage) {
- /* XXX This is a hack. We're assuming that any failure
- * XXX on the client hello is a failure to match
- * XXX ciphers.
- */
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
- }
- }
- } /* ((ss->enableSSL3 || ss->enableTLS) && !ss->connected) */
-
- /* we've got the first 3 bytes. The header may be two or three. */
- if (gs->hdr[0] & 0x80) {
- /* This record has a 2-byte header, and no padding */
- gs->count = ((gs->hdr[0] & 0x7f) << 8) | gs->hdr[1];
- gs->recordPadding = 0;
- } else {
- /* This record has a 3-byte header that is all read in now. */
- gs->count = ((gs->hdr[0] & 0x3f) << 8) | gs->hdr[1];
- /* is_escape = (gs->hdr[0] & 0x40) != 0; */
- gs->recordPadding = gs->hdr[2];
- }
-
- if (gs->count > gs->buf.space) {
- err = sslBuffer_Grow(&gs->buf, gs->count);
- if (err) {
- return err;
- }
- pBuf = gs->buf.buf;
- }
-
-
- if (gs->hdr[0] & 0x80) {
- /* we've already read in the first byte of the body.
- ** Put it into the buffer.
- */
- pBuf[0] = gs->hdr[2];
- gs->offset = 1;
- gs->remainder = gs->count - 1;
- } else {
- gs->offset = 0;
- gs->remainder = gs->count;
- }
-
- if (gs->encrypted) {
- gs->state = GS_MAC;
- gs->recordLen = gs->count - gs->recordPadding
- - sec->hash->length;
- } else {
- gs->state = GS_DATA;
- gs->recordLen = gs->count;
- }
-
- break;
-
-
- case GS_MAC:
- /* Have read in entire rest of the ciphertext.
- ** Check for valid length.
- ** Decrypt it.
- ** Check the MAC.
- */
- PORT_Assert(gs->encrypted);
-
- {
- unsigned int macLen;
- int nout;
- unsigned char mac[SSL_MAX_MAC_BYTES];
-
- ssl_GetSpecReadLock(ss); /**********************************/
-
- /* If this is a stream cipher, blockSize will be 1,
- * and this test will always be false.
- * If this is a block cipher, this will detect records
- * that are not a multiple of the blocksize in length.
- */
- if (gs->count & (sec->blockSize - 1)) {
- /* This is an error. Sender is misbehaving */
- SSL_DBG(("%d: SSL[%d]: sender, count=%d blockSize=%d",
- SSL_GETPID(), ss->fd, gs->count,
- sec->blockSize));
- PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
- rv = SECFailure;
- goto spec_locked_done;
- }
- PORT_Assert(gs->count == gs->offset);
-
- if (gs->offset == 0) {
- rv = 0; /* means EOF. */
- goto spec_locked_done;
- }
-
- /* Decrypt the portion of data that we just recieved.
- ** Decrypt it in place.
- */
- rv = (*sec->dec)(sec->readcx, pBuf, &nout, gs->offset,
- pBuf, gs->offset);
- if (rv != SECSuccess) {
- goto spec_locked_done;
- }
-
-
- /* Have read in all the MAC portion of record
- **
- ** Prepare MAC by resetting it and feeding it the shared secret
- */
- macLen = sec->hash->length;
- if (gs->offset >= macLen) {
- uint32 sequenceNumber = sec->rcvSequence++;
- unsigned char seq[4];
-
- seq[0] = (unsigned char) (sequenceNumber >> 24);
- seq[1] = (unsigned char) (sequenceNumber >> 16);
- seq[2] = (unsigned char) (sequenceNumber >> 8);
- seq[3] = (unsigned char) (sequenceNumber);
-
- (*sec->hash->begin)(sec->hashcx);
- (*sec->hash->update)(sec->hashcx, sec->rcvSecret.data,
- sec->rcvSecret.len);
- (*sec->hash->update)(sec->hashcx, pBuf + macLen,
- gs->offset - macLen);
- (*sec->hash->update)(sec->hashcx, seq, 4);
- (*sec->hash->end)(sec->hashcx, mac, &macLen, macLen);
- }
-
- PORT_Assert(macLen == sec->hash->length);
-
- ssl_ReleaseSpecReadLock(ss); /******************************/
-
- if (PORT_Memcmp(mac, pBuf, macLen) != 0) {
- /* MAC's didn't match... */
- SSL_DBG(("%d: SSL[%d]: mac check failed, seq=%d",
- SSL_GETPID(), ss->fd, sec->rcvSequence));
- PRINT_BUF(1, (ss, "computed mac:", mac, macLen));
- PRINT_BUF(1, (ss, "received mac:", pBuf, macLen));
- PORT_SetError(SSL_ERROR_BAD_MAC_READ);
- rv = SECFailure;
- goto cleanup;
- }
-
-
- PORT_Assert(gs->recordPadding + macLen <= gs->offset);
- if (gs->recordPadding + macLen <= gs->offset) {
- gs->recordOffset = macLen;
- gs->readOffset = macLen;
- gs->writeOffset = gs->offset - gs->recordPadding;
- rv = 1;
- } else {
- PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
-cleanup:
- /* nothing in the buffer any more. */
- gs->recordOffset = 0;
- gs->readOffset = 0;
- gs->writeOffset = 0;
- rv = SECFailure;
- }
-
- gs->recordLen = gs->writeOffset - gs->readOffset;
- gs->recordPadding = 0; /* forget we did any padding. */
- gs->state = GS_INIT;
-
-
- if (rv > 0) {
- PRINT_BUF(50, (ss, "recv clear record:",
- pBuf + gs->recordOffset, gs->recordLen));
- }
- return rv;
-
-spec_locked_done:
- ssl_ReleaseSpecReadLock(ss);
- return rv;
- }
-
- case GS_DATA:
- /* Have read in all the DATA portion of record */
-
- gs->recordOffset = 0;
- gs->readOffset = 0;
- gs->writeOffset = gs->offset;
- PORT_Assert(gs->recordLen == gs->writeOffset - gs->readOffset);
- gs->recordLen = gs->offset;
- gs->recordPadding = 0;
- gs->state = GS_INIT;
-
- ++sec->rcvSequence;
-
- PRINT_BUF(50, (ss, "recv clear record:",
- pBuf + gs->recordOffset, gs->recordLen));
- return 1;
-
- } /* end switch gs->state */
- } /* end gather loop. */
- return rv;
-}
-
-/*
-** Gather a single record of data from the receiving stream. This code
-** first gathers the header (2 or 3 bytes long depending on the value of
-** the most significant bit in the first byte) then gathers up the data
-** for the record into the readBuf. This code handles non-blocking I/O
-** and is to be called multiple times until sec->recordLen != 0.
- *
- * Returns +1 when it has gathered a complete SSLV2 record.
- * Returns 0 if it hits EOF.
- * Returns -1 (SECFailure) on any error
- * Returns -2 (SECWouldBlock)
- *
- * Called by ssl_GatherRecord1stHandshake in sslcon.c,
- * and by DoRecv in sslsecur.c
- * Caller must hold RecvBufLock.
- */
-int
-ssl2_GatherRecord(sslSocket *ss, int flags)
-{
- return ssl2_GatherData(ss, ss->gather, flags);
-}
-
-/*
- * Returns +1 when it has gathered a complete SSLV2 record.
- * Returns 0 if it hits EOF.
- * Returns -1 (SECFailure) on any error
- * Returns -2 (SECWouldBlock)
- *
- * Called from SocksStartGather in sslsocks.c
- * Caller must hold RecvBufLock.
- */
-int
-ssl2_StartGatherBytes(sslSocket *ss, sslGather *gs, unsigned int count)
-{
- int rv;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- gs->state = GS_DATA;
- gs->remainder = count;
- gs->count = count;
- gs->offset = 0;
- if (count > gs->buf.space) {
- rv = sslBuffer_Grow(&gs->buf, count);
- if (rv) {
- return rv;
- }
- }
- return ssl2_GatherData(ss, gs, 0);
-}
-
-/* Caller should hold RecvBufLock. */
-sslGather *
-ssl_NewGather(void)
-{
- sslGather *gs;
-
- gs = (sslGather*) PORT_ZAlloc(sizeof(sslGather));
- if (gs) {
- gs->state = GS_INIT;
- }
- return gs;
-}
-
-/* Caller must hold RecvBufLock. */
-void
-ssl_DestroyGather(sslGather *gs)
-{
- if (gs->inbuf.buf != NULL) {
- PORT_ZFree(gs->inbuf.buf, gs->inbuf.len);
- }
- if (gs) {
- PORT_Free(gs->buf.buf);
- PORT_Free(gs);
- }
-}
-
-/* Caller must hold RecvBufLock. */
-static SECStatus
-ssl2_HandleV3HandshakeRecord(sslSocket *ss)
-{
- sslGather * gs = ss->gather;
- SECStatus rv;
- SSL3ProtocolVersion version = (gs->hdr[1] << 8) | gs->hdr[2];
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
-
- /* We've read in 3 bytes, there are 2 more to go in an ssl3 header. */
- gs->remainder = 2;
- gs->count = 0;
-
- /* Clearing these handshake pointers ensures that
- * ssl_Do1stHandshake won't call ssl2_HandleMessage when we return.
- */
- ss->nextHandshake = 0;
- ss->securityHandshake = 0;
-
- /* Setting ss->version to an SSL 3.x value will cause
- ** ssl_GatherRecord1stHandshake to invoke ssl3_GatherCompleteHandshake()
- ** the next time it is called.
- **/
- rv = ssl3_NegotiateVersion(ss, version);
- if (rv != SECSuccess) {
- return rv;
- }
-
- ss->sec->send = ssl3_SendApplicationData;
-
- return SECSuccess;
-}
diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h
deleted file mode 100644
index fe4a68f27..000000000
--- a/security/nss/lib/ssl/sslimpl.h
+++ /dev/null
@@ -1,1250 +0,0 @@
-/*
- * This file is PRIVATE to SSL and should be the first thing included by
- * any SSL implementation file.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#ifndef __sslimpl_h_
-#define __sslimpl_h_
-
-#ifdef DEBUG
-#undef NDEBUG
-#else
-#undef NDEBUG
-#define NDEBUG
-#endif
-#include "secport.h"
-#include "secerr.h"
-#include "sslerr.h"
-#include "ssl3prot.h"
-#include "hasht.h"
-#include "prlock.h"
-#include "pkcs11t.h"
-#ifdef XP_UNIX
-#include "unistd.h"
-#endif
-#include "nssrwlk.h"
-
-
-#if defined(DEBUG) || defined(TRACE)
-#ifdef __cplusplus
-#define Debug 1
-#else
-extern int Debug;
-#endif
-#else
-#undef Debug
-#endif
-#if defined(DEBUG)
-#define TRACE
-#endif
-
-#ifdef TRACE
-#define SSL_TRC(a,b) if (ssl_trace >= (a)) ssl_Trace b
-#define PRINT_BUF(a,b) if (ssl_trace >= (a)) ssl_PrintBuf b
-#define DUMP_MSG(a,b) if (ssl_trace >= (a)) ssl_DumpMsg b
-#else
-#define SSL_TRC(a,b)
-#define PRINT_BUF(a,b)
-#define DUMP_MSG(a,b)
-#endif
-
-#ifdef DEBUG
-#define SSL_DBG(b) if (ssl_debug) ssl_Trace b
-#else
-#define SSL_DBG(b)
-#endif
-
-#if defined (DEBUG)
-#ifdef macintosh
-#include "pprthred.h"
-#else
-#include "private/pprthred.h" /* for PR_InMonitor() */
-#endif
-#define ssl_InMonitor(m) PR_InMonitor(m)
-#endif
-
-#define LSB(x) ((unsigned char) (x & 0xff))
-#define MSB(x) ((unsigned char) (((unsigned)(x)) >> 8))
-
-/************************************************************************/
-
-typedef enum { SSLAppOpRead = 0,
- SSLAppOpWrite,
- SSLAppOpRDWR,
- SSLAppOpPost,
- SSLAppOpHeader
-} SSLAppOperation;
-
-#define SSL_MIN_MASTER_KEY_BYTES 5
-#define SSL_MAX_MASTER_KEY_BYTES 64
-
-#define SSL_SESSIONID_BYTES 16
-#define SSL3_SESSIONID_BYTES 32
-
-#define SSL_MIN_CHALLENGE_BYTES 16
-#define SSL_MAX_CHALLENGE_BYTES 32
-#define SSL_CHALLENGE_BYTES 16
-
-#define SSL_CONNECTIONID_BYTES 16
-
-#define SSL_MIN_CYPHER_ARG_BYTES 0
-#define SSL_MAX_CYPHER_ARG_BYTES 32
-
-#define SSL_MAX_MAC_BYTES 16
-
-/* number of wrap mechanisms potentially used to wrap master secrets. */
-#define SSL_NUM_WRAP_MECHS 13
-
-/* This makes the cert cache entry exactly 4k. */
-#define SSL_MAX_CACHED_CERT_LEN 4060
-
-typedef struct sslBufferStr sslBuffer;
-typedef struct sslConnectInfoStr sslConnectInfo;
-typedef struct sslGatherStr sslGather;
-typedef struct sslSecurityInfoStr sslSecurityInfo;
-typedef struct sslSessionIDStr sslSessionID;
-typedef struct sslSocketStr sslSocket;
-typedef struct sslSocketOpsStr sslSocketOps;
-typedef struct sslSocksInfoStr sslSocksInfo;
-
-typedef struct ssl3StateStr ssl3State;
-typedef struct ssl3CertNodeStr ssl3CertNode;
-typedef struct ssl3BulkCipherDefStr ssl3BulkCipherDef;
-typedef struct ssl3MACDefStr ssl3MACDef;
-typedef struct ssl3KeyPairStr ssl3KeyPair;
-
-struct ssl3CertNodeStr {
- struct ssl3CertNodeStr *next;
- CERTCertificate * cert;
-};
-
-typedef SECStatus (*sslHandshakeFunc)(sslSocket *ss);
-
-/* This type points to the low layer send func,
-** e.g. ssl2_SendStream or ssl3_SendPlainText.
-** These functions return the same values as PR_Send,
-** i.e. >= 0 means number of bytes sent, < 0 means error.
-*/
-typedef PRInt32 (*sslSendFunc)(sslSocket *ss, const unsigned char *buf,
- PRInt32 n, PRInt32 flags);
-
-typedef void (*sslSessionIDCacheFunc) (sslSessionID *sid);
-typedef void (*sslSessionIDUncacheFunc)(sslSessionID *sid);
-typedef sslSessionID *(*sslSessionIDLookupFunc)(PRUint32 addr,
- unsigned char* sid,
- unsigned int sidLen,
- CERTCertDBHandle * dbHandle);
-
-
-/* Socket ops */
-struct sslSocketOpsStr {
- int (*connect) (sslSocket *, const PRNetAddr *);
- PRFileDesc *(*accept) (sslSocket *, PRNetAddr *);
- int (*bind) (sslSocket *, const PRNetAddr *);
- int (*listen) (sslSocket *, int);
- int (*shutdown)(sslSocket *, int);
- int (*close) (sslSocket *);
-
- int (*recv) (sslSocket *, unsigned char *, int, int);
-
- /* points to the higher-layer send func, e.g. ssl_SecureSend. */
- int (*send) (sslSocket *, const unsigned char *, int, int);
- int (*read) (sslSocket *, unsigned char *, int);
- int (*write) (sslSocket *, const unsigned char *, int);
-
- int (*getpeername)(sslSocket *, PRNetAddr *);
- int (*getsockname)(sslSocket *, PRNetAddr *);
-};
-
-/* Flags interpreted by ssl send functions. */
-#define ssl_SEND_FLAG_FORCE_INTO_BUFFER 0x40000000
-#define ssl_SEND_FLAG_NO_BUFFER 0x20000000
-#define ssl_SEND_FLAG_MASK 0x7f000000
-
-/*
-** A buffer object.
-*/
-struct sslBufferStr {
- unsigned char * buf;
- unsigned int len;
- unsigned int space;
-};
-
-/*
-** SSL3 cipher suite policy and preference struct.
-*/
-typedef struct {
-#ifdef AIX
- unsigned int cipher_suite : 16;
- unsigned int policy : 8;
- unsigned int enabled : 1;
- unsigned int isPresent : 1;
-#else
- ssl3CipherSuite cipher_suite;
- PRUint8 policy;
- unsigned char enabled : 1;
- unsigned char isPresent : 1;
-#endif
-} ssl3CipherSuiteCfg;
-
-#define ssl_V3_SUITES_IMPLEMENTED 13
-
-typedef struct sslOptionsStr {
- unsigned int useSecurity : 1; /* 1 */
- unsigned int useSocks : 1; /* 2 */
- unsigned int requestCertificate : 1; /* 3 */
- unsigned int requireCertificate : 2; /* 4-5 */
- unsigned int handshakeAsClient : 1; /* 6 */
- unsigned int handshakeAsServer : 1; /* 7 */
- unsigned int enableSSL2 : 1; /* 8 */
- unsigned int enableSSL3 : 1; /* 9 */
- unsigned int enableTLS : 1; /* 10 */
- unsigned int noCache : 1; /* 11 */
- unsigned int fdx : 1; /* 12 */
- unsigned int v2CompatibleHello : 1; /* 13 */
- unsigned int detectRollBack : 1; /* 14 */
-} sslOptions;
-
-/*
-** SSL Socket struct
-**
-** Protection: XXX
-*/
-struct sslSocketStr {
- PRFileDesc * fd;
-
- /* Pointer to operations vector for this socket */
- sslSocketOps * ops;
-
- /* State flags */
- unsigned int useSocks : 1;
- unsigned int useSecurity : 1;
- unsigned int requestCertificate : 1;
- unsigned int requireCertificate : 2;
-
- unsigned int handshakeAsClient : 1;
- unsigned int handshakeAsServer : 1;
- unsigned int enableSSL2 : 1;
- unsigned int enableSSL3 : 1;
- unsigned int enableTLS : 1;
-
- unsigned int clientAuthRequested: 1;
- unsigned int noCache : 1;
- unsigned int fdx : 1; /* simultaneous read/write threads */
- unsigned int v2CompatibleHello : 1; /* Send v3+ client hello in v2 format */
- unsigned int detectRollBack : 1; /* Detect rollback to SSL v3 */
- unsigned int connected : 1; /* initial handshake is complete. */
- unsigned int recvdCloseNotify : 1; /* received SSL EOF. */
-
- /* version of the protocol to use */
- SSL3ProtocolVersion version;
- SSL3ProtocolVersion clientHelloVersion; /* version sent in client hello. */
-
- /* Non-zero if socks is enabled */
- sslSocksInfo * socks;
-
- /* Non-zero if security is enabled */
- sslSecurityInfo *sec;
-
- /* protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock. */
- const char *url; /* ssl 2 & 3 */
-
- /* Gather object used for gathering data */
- sslGather * gather; /*recvBufLock*/
-
- sslHandshakeFunc handshake; /*firstHandshakeLock*/
- sslHandshakeFunc nextHandshake; /*firstHandshakeLock*/
- sslHandshakeFunc securityHandshake; /*firstHandshakeLock*/
-
- sslBuffer saveBuf; /*xmitBufLock*/
- sslBuffer pendingBuf; /*xmitBufLock*/
-
- /* the following 3 variables are only used with socks or other proxies. */
- long peer; /* Target server IP address */
- int port; /* Target server port number. */
- char * peerID; /* String uniquely identifies target server. */
- /* End of socks variables. */
-
- ssl3State * ssl3;
- unsigned char * cipherSpecs;
- unsigned int sizeCipherSpecs;
-const unsigned char * preferredCipher;
-
- /* Configuration state for server sockets */
- CERTCertificate * serverCert[kt_kea_size];
- CERTCertificateList * serverCertChain[kt_kea_size];
- SECKEYPrivateKey * serverKey[kt_kea_size];
- ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */
-
- /* Callbacks */
- SSLAuthCertificate authCertificate;
- void *authCertificateArg;
- SSLGetClientAuthData getClientAuthData;
- void *getClientAuthDataArg;
- SSLBadCertHandler handleBadCert;
- void *badCertArg;
- SSLHandshakeCallback handshakeCallback;
- void *handshakeCallbackData;
- void *pkcs11PinArg;
-
- PRIntervalTime rTimeout; /* timeout for NSPR I/O */
- PRIntervalTime wTimeout; /* timeout for NSPR I/O */
- PRIntervalTime cTimeout; /* timeout for NSPR I/O */
-
- PRLock * recvLock; /* lock against multiple reader threads. */
- PRLock * sendLock; /* lock against multiple sender threads. */
-
- PRMonitor * recvBufLock; /* locks low level recv buffers. */
- PRMonitor * xmitBufLock; /* locks low level xmit buffers. */
-
- /* Only one thread may operate on the socket until the initial handshake
- ** is complete. This Monitor ensures that. Since SSL2 handshake is
- ** only done once, this is also effectively the SSL2 handshake lock.
- */
- PRMonitor * firstHandshakeLock;
-
- /* This monitor protects the ssl3 handshake state machine data.
- ** Only one thread (reader or writer) may be in the ssl3 handshake state
- ** machine at any time. */
- PRMonitor * ssl3HandshakeLock;
-
- /* reader/writer lock, protects the secret data needed to encrypt and MAC
- ** outgoing records, and to decrypt and MAC check incoming ciphertext
- ** records. */
- NSSRWLock * specLock;
-
- /* handle to perm cert db (and implicitly to the temp cert db) used
- ** with this socket.
- */
- CERTCertDBHandle * dbHandle;
-
- PRUint16 shutdownHow; /* See ssl_SHUTDOWN defines below. */
-
- PRUint16 allowedByPolicy; /* copy of global policy bits. */
- PRUint16 maybeAllowedByPolicy; /* copy of global policy bits. */
- PRUint16 chosenPreference; /* SSL2 cipher preferences. */
-
- ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED];
-
-};
-
-#define SSL_LOCK_RANK_SPEC 255
-#define SSL_LOCK_RANK_GLOBAL NSS_RWLOCK_RANK_NONE
-
-/* These are the valid values for shutdownHow.
-** These values are each 1 greater than the NSPR values, and the code
-** depends on that relation to efficiently convert PR_SHUTDOWN values
-** into ssl_SHUTDOWN values. These values use one bit for read, and
-** another bit for write, and can be used as bitmasks.
-*/
-#define ssl_SHUTDOWN_NONE 0 /* NOT shutdown at all */
-#define ssl_SHUTDOWN_RCV 1 /* PR_SHUTDOWN_RCV +1 */
-#define ssl_SHUTDOWN_SEND 2 /* PR_SHUTDOWN_SEND +1 */
-#define ssl_SHUTDOWN_BOTH 3 /* PR_SHUTDOWN_BOTH +1 */
-
-/*
-** A gather object. Used to read some data until a count has been
-** satisfied. Primarily for support of async sockets.
-** Everything in here is protected by the recvBufLock.
-*/
-struct sslGatherStr {
- int state; /* see GS_ values below. */ /* ssl 2 & 3 */
-
- /* "buf" holds received plaintext SSL records, after decrypt and MAC check.
- * SSL2: recv'd ciphertext records are put here, then decrypted in place.
- * SSL3: recv'd ciphertext records are put in inbuf (see below), then
- * decrypted into buf.
- */
- sslBuffer buf; /*recvBufLock*/ /* ssl 2 & 3 */
-
- /* number of bytes previously read into hdr or buf(ssl2) or inbuf (ssl3).
- ** (offset - writeOffset) is the number of ciphertext bytes read in but
- ** not yet deciphered.
- */
- unsigned int offset; /* ssl 2 & 3 */
-
- /* number of bytes to read in next call to ssl_DefRecv (recv) */
- unsigned int remainder; /* ssl 2 & 3 */
-
- /* Number of ciphertext bytes to read in after 2-byte SSL record header. */
- unsigned int count; /* ssl2 only */
-
- /* size of the final plaintext record.
- ** == count - (recordPadding + MAC size)
- */
- unsigned int recordLen; /* ssl2 only */
-
- /* number of bytes of padding to be removed after decrypting. */
- /* This value is taken from the record's hdr[2], which means a too large
- * value could crash us.
- */
- unsigned int recordPadding; /* ssl2 only */
-
- /* plaintext DATA begins this many bytes into "buf". */
- unsigned int recordOffset; /* ssl2 only */
-
- int encrypted; /* SSL2 session is now encrypted. ssl2 only */
-
- /* These next two values are used by SSL2 and SSL3.
- ** DoRecv uses them to extract application data.
- ** The difference between writeOffset and readOffset is the amount of
- ** data available to the application. Note that the actual offset of
- ** the data in "buf" is recordOffset (above), not readOffset.
- ** In the current implementation, this is made available before the
- ** MAC is checked!!
- */
- unsigned int readOffset; /* Spot where DATA reader (e.g. application
- ** or handshake code) will read next.
- ** Always zero for SSl3 application data.
- */
- /* offset in buf/inbuf/hdr into which new data will be read from socket. */
- unsigned int writeOffset;
-
- /* Buffer for ssl3 to read (encrypted) data from the socket */
- sslBuffer inbuf; /*recvBufLock*/ /* ssl3 only */
-
- /* The ssl[23]_GatherData functions read data into this buffer, rather
- ** than into buf or inbuf, while in the GS_HEADER state.
- ** The portion of the SSL record header put here always comes off the wire
- ** as plaintext, never ciphertext.
- ** For SSL2, the plaintext portion is two bytes long. For SSl3 it is 5.
- */
- unsigned char hdr[5]; /* ssl 2 & 3 */
-};
-
-/* sslGather.state */
-#define GS_INIT 0
-#define GS_HEADER 1
-#define GS_MAC 2
-#define GS_DATA 3
-#define GS_PAD 4
-
-typedef SECStatus (*SSLCipher)(void * context,
- unsigned char * out,
- int * outlen,
- int maxout,
- const unsigned char *in,
- int inlen);
-typedef SECStatus (*SSLDestroy)(void *context, PRBool freeit);
-
-
-/*
- * SSL2 buffers used in SSL3.
- * writeBuf in the SecurityInfo maintained by sslsecur.c is used
- * to hold the data just about to be passed to the kernel
- * sendBuf in the ConnectInfo maintained by sslcon.c is used
- * to hold handshake messages as they are accumulated
- */
-
-/*
-** This is "ci", as in "ss->sec.ci".
-**
-** Protection: All the variables in here are protected by
-** firstHandshakeLock AND (in ssl3) ssl3HandshakeLock
-*/
-struct sslConnectInfoStr {
- /* outgoing handshakes appended to this. */
- sslBuffer sendBuf; /*xmitBufLock*/ /* ssl 2 & 3 */
-
- unsigned long peer; /* ssl 2 & 3 */
- unsigned short port; /* ssl 2 & 3 */
-
- sslSessionID *sid; /* ssl 2 & 3 */
-
- /* see CIS_HAVE defines below for the bit values in *elements. */
- char elements; /* ssl2 only */
- char requiredElements; /* ssl2 only */
- char sentElements; /* ssl2 only */
-
- char sentFinished; /* ssl2 only */
-
- /* Length of server challenge. Used by client when saving challenge */
- int serverChallengeLen; /* ssl2 only */
- /* type of authentication requested by server */
- unsigned char authType; /* ssl2 only */
-
- /* Challenge sent by client to server in client-hello message */
- /* SSL3 gets a copy of this. See ssl3_StartHandshakeHash(). */
- unsigned char clientChallenge[SSL_MAX_CHALLENGE_BYTES]; /* ssl 2 & 3 */
-
- /* Connection-id sent by server to client in server-hello message */
- unsigned char connectionID[SSL_CONNECTIONID_BYTES]; /* ssl2 only */
-
- /* Challenge sent by server to client in request-certificate message */
- unsigned char serverChallenge[SSL_MAX_CHALLENGE_BYTES]; /* ssl2 only */
-
- /* Information kept to handle a request-certificate message */
- unsigned char readKey[SSL_MAX_MASTER_KEY_BYTES]; /* ssl2 only */
- unsigned char writeKey[SSL_MAX_MASTER_KEY_BYTES]; /* ssl2 only */
- unsigned keySize; /* ssl2 only */
-};
-
-/* bit values for ci->elements, ci->requiredElements, sentElements. */
-#define CIS_HAVE_MASTER_KEY 0x01
-#define CIS_HAVE_CERTIFICATE 0x02
-#define CIS_HAVE_FINISHED 0x04
-#define CIS_HAVE_VERIFY 0x08
-
-/* Note: The entire content of this struct and whatever it points to gets
- * blown away by SSL_ResetHandshake(). This is "sec" as in "ss->sec".
- *
- * Unless otherwise specified below, the contents of this struct are
- * protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock.
- */
-struct sslSecurityInfoStr {
- sslSendFunc send; /*xmitBufLock*/ /* ssl 2 & 3 */
- int isServer; /* Spec Lock?*/ /* ssl 2 & 3 */
- sslBuffer writeBuf; /*xmitBufLock*/ /* ssl 2 & 3 */
-
- int cipherType; /* ssl 2 & 3 */
- int keyBits; /* ssl 2 & 3 */
- int secretKeyBits; /* ssl 2 & 3 */
- CERTCertificate *peerCert; /* ssl 2 & 3 */
- SECKEYPublicKey *peerKey; /* ssl3 only */
-
- /*
- ** Procs used for SID cache (nonce) management.
- ** Different implementations exist for clients/servers
- ** The lookup proc is only used for servers. Baloney!
- */
- sslSessionIDCacheFunc cache; /* ssl 2 & 3 */
- sslSessionIDUncacheFunc uncache; /* ssl 2 & 3 */
-
- /*
- ** everything below here is for ssl2 only.
- ** This stuff is equivalent to SSL3's "spec", and is protected by the
- ** same "Spec Lock" as used for SSL3's specs.
- */
- uint32 sendSequence; /*xmitBufLock*/ /* ssl2 only */
- uint32 rcvSequence; /*recvBufLock*/ /* ssl2 only */
-
- /* Hash information; used for one-way-hash functions (MD2, MD5, etc.) */
- SECHashObject *hash; /* Spec Lock */ /* ssl2 only */
- void *hashcx; /* Spec Lock */ /* ssl2 only */
-
- SECItem sendSecret; /* Spec Lock */ /* ssl2 only */
- SECItem rcvSecret; /* Spec Lock */ /* ssl2 only */
-
- /* Session cypher contexts; one for each direction */
- void *readcx; /* Spec Lock */ /* ssl2 only */
- void *writecx; /* Spec Lock */ /* ssl2 only */
- SSLCipher enc; /* Spec Lock */ /* ssl2 only */
- SSLCipher dec; /* Spec Lock */ /* ssl2 only */
- void (*destroy)(void *, PRBool); /* Spec Lock */ /* ssl2 only */
-
- /* Blocking information for the session cypher */
- int blockShift; /* Spec Lock */ /* ssl2 only */
- int blockSize; /* Spec Lock */ /* ssl2 only */
-
- /* These are used during a connection handshake */
- sslConnectInfo ci; /* ssl 2 & 3 */
-
-};
-
-/*
-** ssl3State and CipherSpec structs
-*/
-
-/* The SSL bulk cipher definition */
-typedef enum {
- cipher_null,
- cipher_rc4,
- cipher_rc4_40,
- cipher_rc4_56,
- cipher_rc2,
- cipher_rc2_40,
- cipher_des,
- cipher_3des,
- cipher_des40,
- cipher_idea,
- cipher_fortezza,
- cipher_missing /* reserved for no such supported cipher */
-} SSL3BulkCipher;
-
-/* The specific cipher algorithm */
-
-typedef enum {
- calg_null = (int)0x80000000L,
- calg_rc4 = CKM_RC4,
- calg_rc2 = CKM_RC2_CBC,
- calg_des = CKM_DES_CBC,
- calg_3des = CKM_DES3_CBC,
- calg_idea = CKM_IDEA_CBC,
- calg_fortezza = CKM_SKIPJACK_CBC64,
- calg_init = (int) 0x7fffffffL
-} CipherAlgorithm;
-
-/* hmac added to help TLS conversion by rjr... */
-typedef enum {
- malg_null = (int)0x80000000L,
- malg_md5 = CKM_SSL3_MD5_MAC,
- malg_sha = CKM_SSL3_SHA1_MAC,
- malg_md5_hmac = CKM_MD5_HMAC,
- malg_sha_hmac = CKM_SHA_1_HMAC
-} MACAlgorithm;
-
-
-/* Key Exchange values moved to ssl.h */
-typedef SSLKEAType SSL3KEAType;
-
-typedef enum {
- mac_null,
- mac_md5,
- mac_sha,
- hmac_md5, /* TLS HMAC version of mac_md5 */
- hmac_sha /* TLS HMAC version of mac_sha */
-} SSL3MACAlgorithm;
-
-typedef enum { type_stream, type_block } CipherType;
-
-#define MAX_IV_LENGTH 64
-
-/*
- * Do not depend upon 64 bit arithmetic in the underlying machine.
- */
-typedef struct {
- uint32 high;
- uint32 low;
-} SSL3SequenceNumber;
-
-typedef struct {
- SSL3Opaque write_iv[MAX_IV_LENGTH];
- PK11SymKey *write_key;
- PK11SymKey *write_mac_key;
- PK11Context *write_mac_context;
-} ssl3KeyMaterial;
-
-typedef struct {
- SSL3Opaque wrapped_client_write_key[12]; /* wrapped with Ks */
- SSL3Opaque wrapped_server_write_key[12]; /* wrapped with Ks */
- SSL3Opaque client_write_iv [24];
- SSL3Opaque server_write_iv [24];
- SSL3Opaque wrapped_master_secret [48];
- PRUint16 wrapped_master_secret_len;
-} ssl3SidKeys;
-
-/*
-** These are the "specs" in the "ssl3" struct.
-** Access to the pointers to these specs, and all the specs' contents
-** (direct and indirect) is protected by the reader/writer lock ss->specLock.
-*/
-typedef struct {
- const ssl3BulkCipherDef *cipher_def;
- const ssl3MACDef * mac_def;
- int mac_size;
- SSLCipher encode;
- void * encodeContext;
- SSLCipher decode;
- void * decodeContext;
- SSLDestroy destroy;
- PK11SymKey * master_secret;
- ssl3KeyMaterial client;
- ssl3KeyMaterial server;
- SSL3SequenceNumber write_seq_num;
- SSL3SequenceNumber read_seq_num;
- SSL3ProtocolVersion version;
-} ssl3CipherSpec;
-
-typedef enum { never_cached,
- in_client_cache,
- in_server_cache,
- invalid_cache /* no longer in any cache. */
-} Cached;
-
-struct sslSessionIDStr {
- sslSessionID * next; /* chain used for client sockets, only */
-
- CERTCertificate * peerCert;
- const char * peerID; /* client only */
- const char * urlSvrName; /* client only */
-
- PRUint32 addr;
- PRUint16 port;
-
- SSL3ProtocolVersion version;
-
- PRUint32 time;
- Cached cached;
- int references;
-
- union {
- struct {
- /* the V2 code depends upon the size of sessionID. */
- unsigned char sessionID[SSL_SESSIONID_BYTES];
-
- /* Stuff used to recreate key and read/write cipher objects */
- SECItem masterKey;
- int cipherType;
- SECItem cipherArg;
- int keyBits;
- int secretKeyBits;
- } ssl2;
- struct {
- /* values that are copied into the server's on-disk SID cache. */
- uint8 sessionIDLength;
- SSL3Opaque sessionID[SSL3_SESSIONID_BYTES];
-
- ssl3CipherSuite cipherSuite;
- SSL3CompressionMethod compression;
- PRBool resumable;
- int policy;
- PRBool hasFortezza;
- ssl3SidKeys keys;
- CK_MECHANISM_TYPE masterWrapMech;
- /* mechanism used to wrap master secret */
- SSL3KEAType exchKeyType;
- /* key type used in exchange algorithm,
- * and to wrap the sym wrapping key. */
-
- /* The following values are NOT restored from the server's on-disk
- * session cache, but are restored from the client's cache.
- */
- PK11SymKey * clientWriteKey;
- PK11SymKey * serverWriteKey;
- PK11SymKey * tek;
-
- /* The following values pertain to the slot that wrapped the
- ** master secret. (used only in client)
- */
- SECMODModuleID masterModuleID;
- /* what module wrapped the master secret */
- CK_SLOT_ID masterSlotID;
- PRUint16 masterWrapIndex;
- /* what's the key index for the wrapping key */
- PRUint16 masterWrapSeries;
- /* keep track of the slot series, so we don't
- * accidently try to use new keys after the
- * card gets removed and replaced.*/
-
- /* The following values pertain to the slot that did the signature
- ** for client auth. (used only in client)
- */
- SECMODModuleID clAuthModuleID;
- CK_SLOT_ID clAuthSlotID;
- PRUint16 clAuthSeries;
-
- char masterValid;
- char clAuthValid;
-
- /* the following values are used only in the client, and only
- * with fortezza.
- */
- SSL3Opaque clientWriteSave[80];
- int clientWriteSaveLen;
- } ssl3;
- } u;
-};
-
-
-typedef struct ssl3CipherSuiteDefStr {
- ssl3CipherSuite cipher_suite;
- SSL3BulkCipher bulk_cipher_alg;
- SSL3MACAlgorithm mac_alg;
- SSL3KeyExchangeAlgorithm key_exchange_alg;
-} ssl3CipherSuiteDef;
-
-/*
-** There are tables of these, all const.
-*/
-typedef struct {
- SSL3KeyExchangeAlgorithm kea;
- SSL3KEAType exchKeyType;
- SSL3SignType signKeyType;
- PRBool is_limited;
- int key_size_limit;
- PRBool tls_keygen;
-} ssl3KEADef;
-
-typedef enum { kg_null, kg_strong, kg_export } SSL3KeyGenMode;
-
-/*
-** There are tables of these, all const.
-*/
-struct ssl3BulkCipherDefStr {
- SSL3BulkCipher cipher;
- CipherAlgorithm calg;
- int key_size;
- int secret_key_size;
- CipherType type;
- int iv_size;
- int block_size;
- SSL3KeyGenMode keygen_mode;
-};
-
-/*
-** There are tables of these, all const.
-*/
-struct ssl3MACDefStr {
- SSL3MACAlgorithm mac;
- MACAlgorithm malg;
- int pad_size;
- int mac_size;
-};
-
-typedef enum {
- wait_client_hello,
- wait_client_cert,
- wait_client_key,
- wait_cert_verify,
- wait_change_cipher,
- wait_finished,
- wait_server_hello,
- wait_server_cert,
- wait_server_key,
- wait_cert_request,
- wait_hello_done,
- idle_handshake
-} SSL3WaitState;
-
-/*
-** This is the "hs" member of the "ssl3" struct.
-** This entire struct is protected by ssl3HandshakeLock
-*/
-typedef struct SSL3HandshakeStateStr {
- SSL3Random server_random;
- SSL3Random client_random;
- SSL3WaitState ws;
- PK11Context * md5; /* handshake running hashes */
- PK11Context * sha;
-const ssl3KEADef * kea_def;
- ssl3CipherSuite cipher_suite;
-const ssl3CipherSuiteDef *suite_def;
- SSL3CompressionMethod compression;
- sslBuffer msg_body; /* protected by recvBufLock */
- /* partial handshake message from record layer */
- unsigned int header_bytes;
- /* number of bytes consumed from handshake */
- /* message for message type and header length */
- SSL3HandshakeType msg_type;
- unsigned long msg_len;
- SECItem ca_list; /* used only by client */
- PRBool isResuming; /* are we resuming a session */
- PRBool rehandshake; /* immediately start another handshake
- * when this one finishes */
- PRBool usedStepDownKey; /* we did a server key exchange. */
- sslBuffer msgState; /* current state for handshake messages*/
- /* protected by recvBufLock */
-} SSL3HandshakeState;
-
-struct SSL3FortezzaKEAParamsStr {
- unsigned char R_s[128]; /* server's "random" public key */
- PK11SymKey * tek;
-};
-
-typedef struct SSL3FortezzaKEAParamsStr SSL3FortezzaKEAParams;
-
-/*
-** This is the "ssl3" struct, as in "ss->ssl3".
-** note:
-** usually, crSpec == cwSpec and prSpec == pwSpec.
-** Sometimes, crSpec == pwSpec and prSpec == cwSpec.
-** But there are never more than 2 actual specs.
-** No spec must ever be modified if either "current" pointer points to it.
-*/
-struct ssl3StateStr {
-
- /*
- ** The following Specs and Spec pointers must be protected using the
- ** Spec Lock.
- */
- ssl3CipherSpec * crSpec; /* current read spec. */
- ssl3CipherSpec * prSpec; /* pending read spec. */
- ssl3CipherSpec * cwSpec; /* current write spec. */
- ssl3CipherSpec * pwSpec; /* pending write spec. */
- ssl3CipherSpec specs[2]; /* one is current, one is pending. */
-
- SSL3HandshakeState hs;
-
- CERTCertificate * clientCertificate; /* used by client */
- SECKEYPrivateKey * clientPrivateKey; /* used by client */
- CERTCertificateList *clientCertChain; /* used by client */
- PRBool sendEmptyCert; /* used by client */
-
- int policy;
- /* This says what cipher suites we can do, and should
- * be either SSL_ALLOWED or SSL_RESTRICTED
- */
- PRArenaPool * peerCertArena;
- /* These are used to keep track of the peer CA */
- void * peerCertChain;
- /* chain while we are trying to validate it. */
- CERTDistNames * ca_list;
- /* used by server. trusted CAs for this socket. */
- SSL3FortezzaKEAParams fortezza;
-};
-
-typedef struct {
- SSL3ContentType type;
- SSL3ProtocolVersion version;
- sslBuffer * buf;
-} SSL3Ciphertext;
-
-struct ssl3KeyPairStr {
- SECKEYPrivateKey * privKey; /* RSA step down key */
- SECKEYPublicKey * pubKey; /* RSA step down key */
- PRInt32 refCount; /* use PR_Atomic calls for this. */
-};
-
-typedef struct SSLWrappedSymWrappingKeyStr {
- SSL3Opaque wrappedSymmetricWrappingkey[512];
- SSL3Opaque wrapIV[24];
- CK_MECHANISM_TYPE symWrapMechanism;
- /* unwrapped symmetric wrapping key uses this mechanism */
- CK_MECHANISM_TYPE asymWrapMechanism;
- /* mechanism used to wrap the SymmetricWrappingKey using
- * server's public and/or private keys. */
- SSL3KEAType exchKeyType; /* type of keys used to wrap SymWrapKey*/
- PRInt32 symWrapMechIndex;
- PRUint16 wrappedSymKeyLen;
- PRUint16 wrapIVLen;
-} SSLWrappedSymWrappingKey;
-
-/* All the global data items declared here should be protected using the
-** ssl_global_data_lock, which is a reader/writer lock.
-*/
-extern NSSRWLock * ssl_global_data_lock;
-extern char ssl_debug;
-extern char ssl_trace;
-extern CERTDistNames * ssl3_server_ca_list;
-extern PRUint32 ssl_sid_timeout;
-extern PRUint32 ssl3_sid_timeout;
-extern PRBool ssl3_global_policy_some_restricted;
-
-extern const char * const ssl_cipherName[];
-extern const char * const ssl3_cipherName[];
-
-extern sslSessionIDLookupFunc ssl_sid_lookup;
-extern sslSessionIDCacheFunc ssl_sid_cache;
-extern sslSessionIDUncacheFunc ssl_sid_uncache;
-
-/************************************************************************/
-
-SEC_BEGIN_PROTOS
-
-/* Implementation of ops for default (non socks, non secure) case */
-extern int ssl_DefConnect(sslSocket *ss, const PRNetAddr *addr);
-extern PRFileDesc *ssl_DefAccept(sslSocket *ss, PRNetAddr *addr);
-extern int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr);
-extern int ssl_DefListen(sslSocket *ss, int backlog);
-extern int ssl_DefShutdown(sslSocket *ss, int how);
-extern int ssl_DefClose(sslSocket *ss);
-extern int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags);
-extern int ssl_DefSend(sslSocket *ss, const unsigned char *buf,
- int len, int flags);
-extern int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len);
-extern int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len);
-extern int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name);
-extern int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name);
-extern int ssl_DefGetsockopt(sslSocket *ss, PRSockOption optname,
- void *optval, PRInt32 *optlen);
-extern int ssl_DefSetsockopt(sslSocket *ss, PRSockOption optname,
- const void *optval, PRInt32 optlen);
-
-/* Implementation of ops for socks only case */
-extern int ssl_SocksConnect(sslSocket *ss, const PRNetAddr *addr);
-extern PRFileDesc *ssl_SocksAccept(sslSocket *ss, PRNetAddr *addr);
-extern int ssl_SocksBind(sslSocket *ss, const PRNetAddr *addr);
-extern int ssl_SocksListen(sslSocket *ss, int backlog);
-extern int ssl_SocksGetsockname(sslSocket *ss, PRNetAddr *name);
-extern int ssl_SocksRecv(sslSocket *ss, unsigned char *buf, int len, int flags);
-extern int ssl_SocksSend(sslSocket *ss, const unsigned char *buf,
- int len, int flags);
-extern int ssl_SocksRead(sslSocket *ss, unsigned char *buf, int len);
-extern int ssl_SocksWrite(sslSocket *ss, const unsigned char *buf, int len);
-
-/* Implementation of ops for secure only case */
-extern int ssl_SecureConnect(sslSocket *ss, const PRNetAddr *addr);
-extern PRFileDesc *ssl_SecureAccept(sslSocket *ss, PRNetAddr *addr);
-extern int ssl_SecureRecv(sslSocket *ss, unsigned char *buf,
- int len, int flags);
-extern int ssl_SecureSend(sslSocket *ss, const unsigned char *buf,
- int len, int flags);
-extern int ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len);
-extern int ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len);
-extern int ssl_SecureShutdown(sslSocket *ss, int how);
-extern int ssl_SecureClose(sslSocket *ss);
-
-/* Implementation of ops for secure socks case */
-extern int ssl_SecureSocksConnect(sslSocket *ss, const PRNetAddr *addr);
-extern PRFileDesc *ssl_SecureSocksAccept(sslSocket *ss, PRNetAddr *addr);
-extern PRFileDesc *ssl_FindTop(sslSocket *ss);
-
-/* Gather funcs. */
-extern sslGather * ssl_NewGather(void);
-extern void ssl_DestroyGather(sslGather *gs);
-extern int ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags);
-extern int ssl2_GatherRecord(sslSocket *ss, int flags);
-extern SECStatus ssl_GatherRecord1stHandshake(sslSocket *ss);
-
-extern SECStatus ssl2_HandleClientHelloMessage(sslSocket *ss);
-extern SECStatus ssl2_HandleServerHelloMessage(sslSocket *ss);
-extern int ssl2_StartGatherBytes(sslSocket *ss, sslGather *gs,
- unsigned int count);
-
-extern SECStatus ssl_CreateSecurityInfo(sslSocket *ss);
-extern SECStatus ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os);
-extern void ssl_DestroySecurityInfo(sslSecurityInfo *sec);
-
-extern SECStatus ssl_CreateSocksInfo(sslSocket *ss);
-extern SECStatus ssl_CopySocksInfo(sslSocket *ss, sslSocket *os);
-extern void ssl_DestroySocksInfo(sslSocksInfo *si);
-
-extern sslSocket * ssl_DupSocket(sslSocket *old);
-
-extern void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *cp, int len);
-extern void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len);
-
-extern int ssl_SendSavedWriteData(sslSocket *ss, sslBuffer *buf,
- sslSendFunc fp);
-extern SECStatus ssl_SaveWriteData(sslSocket *ss, sslBuffer *buf,
- const void* p, unsigned int l);
-extern SECStatus ssl2_BeginClientHandshake(sslSocket *ss);
-extern SECStatus ssl2_BeginServerHandshake(sslSocket *ss);
-extern int ssl_Do1stHandshake(sslSocket *ss);
-
-extern SECStatus sslBuffer_Grow(sslBuffer *b, unsigned int newLen);
-
-extern void ssl2_UseClearSendFunc(sslSocket *ss);
-extern void ssl_ChooseSessionIDProcs(sslSecurityInfo *sec);
-
-extern sslSessionID *ssl_LookupSID(PRUint32 addr, PRUint16 port,
- const char *peerID, const char *urlSvrName);
-extern void ssl_FreeSID(sslSessionID *sid);
-
-extern int ssl3_SendApplicationData(sslSocket *ss, const PRUint8 *in,
- int len, int flags);
-
-extern PRBool ssl_FdIsBlocking(PRFileDesc *fd);
-
-extern PRBool ssl_SocketIsBlocking(sslSocket *ss);
-
-extern void ssl_SetAlwaysBlock(sslSocket *ss);
-
-#define SSL_LOCK_READER(ss) if (ss->recvLock) PR_Lock(ss->recvLock)
-#define SSL_UNLOCK_READER(ss) if (ss->recvLock) PR_Unlock(ss->recvLock)
-#define SSL_LOCK_WRITER(ss) if (ss->sendLock) PR_Lock(ss->sendLock)
-#define SSL_UNLOCK_WRITER(ss) if (ss->sendLock) PR_Unlock(ss->sendLock)
-
-#define ssl_Get1stHandshakeLock(ss) PR_EnterMonitor((ss)->firstHandshakeLock)
-#define ssl_Release1stHandshakeLock(ss) PR_ExitMonitor((ss)->firstHandshakeLock)
-#define ssl_Have1stHandshakeLock(ss) PR_InMonitor( (ss)->firstHandshakeLock)
-
-#define ssl_GetSSL3HandshakeLock(ss) PR_EnterMonitor((ss)->ssl3HandshakeLock)
-#define ssl_ReleaseSSL3HandshakeLock(ss) PR_ExitMonitor((ss)->ssl3HandshakeLock)
-#define ssl_HaveSSL3HandshakeLock(ss) PR_InMonitor( (ss)->ssl3HandshakeLock)
-
-#define ssl_GetSpecReadLock(ss) NSSRWLock_LockRead( (ss)->specLock)
-#define ssl_ReleaseSpecReadLock(ss) NSSRWLock_UnlockRead( (ss)->specLock)
-
-#define ssl_GetSpecWriteLock(ss) NSSRWLock_LockWrite( (ss)->specLock)
-#define ssl_ReleaseSpecWriteLock(ss) NSSRWLock_UnlockWrite((ss)->specLock)
-#define ssl_HaveSpecWriteLock(ss) NSSRWLock_HaveWriteLock((ss)->specLock)
-
-#define ssl_GetRecvBufLock(ss) PR_EnterMonitor((ss)->recvBufLock)
-#define ssl_ReleaseRecvBufLock(ss) PR_ExitMonitor( (ss)->recvBufLock)
-#define ssl_HaveRecvBufLock(ss) PR_InMonitor( (ss)->recvBufLock)
-
-#define ssl_GetXmitBufLock(ss) PR_EnterMonitor((ss)->xmitBufLock)
-#define ssl_ReleaseXmitBufLock(ss) PR_ExitMonitor( (ss)->xmitBufLock)
-#define ssl_HaveXmitBufLock(ss) PR_InMonitor( (ss)->xmitBufLock)
-
-
-/* These functions are called from secnav, even though they're "private". */
-
-extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error);
-extern int SSL_RestartHandshakeAfterServerCert(struct sslSocketStr *ss);
-extern int SSL_RestartHandshakeAfterCertReq(struct sslSocketStr *ss,
- CERTCertificate *cert,
- SECKEYPrivateKey *key,
- CERTCertificateList *certChain);
-extern sslSocket *ssl_FindSocket(PRFileDesc *fd);
-extern void ssl_FreeSocket(struct sslSocketStr *ssl);
-extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level,
- SSL3AlertDescription desc);
-
-extern int ssl2_RestartHandshakeAfterCertReq(sslSocket * ss,
- CERTCertificate * cert,
- SECKEYPrivateKey * key);
-
-extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss,
- CERTCertificate * cert,
- SECKEYPrivateKey * key,
- CERTCertificateList *certChain);
-
-extern int ssl2_RestartHandshakeAfterServerCert(sslSocket *ss);
-extern int ssl3_RestartHandshakeAfterServerCert(sslSocket *ss);
-
-/*
- * for dealing with SSL 3.0 clients sending SSL 2.0 format hellos
- */
-extern SECStatus ssl3_HandleV2ClientHello(
- sslSocket *ss, unsigned char *buffer, int length);
-extern SECStatus ssl3_StartHandshakeHash(
- sslSocket *ss, unsigned char *buf, int length);
-
-/*
- * SSL3 specific routines
- */
-SECStatus ssl3_SendClientHello(sslSocket *ss);
-
-/*
- * input into the SSL3 machinery from the actualy network reading code
- */
-SECStatus ssl3_HandleRecord(
- sslSocket *ss, SSL3Ciphertext *cipher, sslBuffer *out);
-
-int ssl3_GatherAppDataRecord(sslSocket *ss, int flags);
-int ssl3_GatherCompleteHandshake(sslSocket *ss, int flags);
-/*
- * When talking to export clients or using export cipher suites, servers
- * with public RSA keys larger than 512 bits need to use a 512-bit public
- * key, signed by the larger key. The smaller key is a "step down" key.
- * Generate that key pair and keep it around.
- */
-extern SECStatus ssl3_CreateRSAStepDownKeys(sslSocket *ss);
-
-extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on);
-extern SECStatus ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *on);
-extern SECStatus ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled);
-extern SECStatus ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled);
-
-extern SECStatus ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool on);
-extern SECStatus ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *on);
-extern SECStatus ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled);
-extern SECStatus ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled);
-
-extern SECStatus ssl3_SetPolicy(ssl3CipherSuite which, PRInt32 policy);
-extern SECStatus ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *policy);
-extern SECStatus ssl2_SetPolicy(PRInt32 which, PRInt32 policy);
-extern SECStatus ssl2_GetPolicy(PRInt32 which, PRInt32 *policy);
-
-extern void ssl2_InitSocketPolicy(sslSocket *ss);
-extern void ssl3_InitSocketPolicy(sslSocket *ss);
-
-extern SECStatus ssl3_ConstructV2CipherSpecsHack(sslSocket *ss,
- unsigned char *cs, int *size);
-
-extern SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache);
-
-extern void ssl3_DestroySSL3Info(ssl3State *ssl3);
-
-extern SECStatus ssl3_NegotiateVersion(sslSocket *ss,
- SSL3ProtocolVersion peerVersion);
-
-extern SECStatus ssl_GetPeerInfo(sslSocket *ss);
-
-/* Construct a new NSPR socket for the app to use */
-extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd);
-extern void ssl_FreePRSocket(PRFileDesc *fd);
-
-/* Internal config function so SSL2 can initialize the present state of
- * various ciphers */
-extern int ssl3_config_match_init(sslSocket *);
-
-
-/* Create a new ref counted key pair object from two keys. */
-extern ssl3KeyPair * ssl3_NewKeyPair( SECKEYPrivateKey * privKey,
- SECKEYPublicKey * pubKey);
-
-/* get a new reference (bump ref count) to an ssl3KeyPair. */
-extern ssl3KeyPair * ssl3_GetKeyPairRef(ssl3KeyPair * keyPair);
-
-/* Decrement keypair's ref count and free if zero. */
-extern void ssl3_FreeKeyPair(ssl3KeyPair * keyPair);
-
-/* calls for accessing wrapping keys across processes. */
-extern PRBool
-ssl_GetWrappingKey( PRInt32 symWrapMechIndex,
- SSL3KEAType exchKeyType,
- SSLWrappedSymWrappingKey *wswk);
-
-/* The caller passes in the new value it wants
- * to set. This code tests the wrapped sym key entry in the file on disk.
- * If it is uninitialized, this function writes the caller's value into
- * the disk entry, and returns false.
- * Otherwise, it overwrites the caller's wswk with the value obtained from
- * the disk, and returns PR_TRUE.
- * This is all done while holding the locks/semaphores necessary to make
- * the operation atomic.
- */
-extern PRBool
-ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk);
-
-/********************** misc calls *********************/
-
-extern int ssl_MapLowLevelError(int hiLevelError);
-
-extern PRUint32 ssl_Time(void);
-
-/* emulation of NSPR routines. */
-extern PRInt32
-ssl_EmulateAcceptRead( PRFileDesc * sd,
- PRFileDesc ** nd,
- PRNetAddr ** raddr,
- void * buf,
- PRInt32 amount,
- PRIntervalTime timeout);
-extern PRInt32
-ssl_EmulateTransmitFile( PRFileDesc * sd,
- PRFileDesc * fd,
- const void * headers,
- PRInt32 hlen,
- PRTransmitFileFlags flags,
- PRIntervalTime timeout);
-extern PRInt32
-ssl_EmulateSendFile( PRFileDesc * sd,
- PRSendFileData * sfd,
- PRTransmitFileFlags flags,
- PRIntervalTime timeout);
-
-#ifdef TRACE
-#define SSL_TRACE(msg) ssl_Trace msg
-#else
-#define SSL_TRACE(msg)
-#endif
-
-void ssl_Trace(const char *format, ...);
-
-SEC_END_PROTOS
-
-
-#ifdef XP_UNIX
-#define SSL_GETPID() getpid()
-#else
-#define SSL_GETPID() 0
-#endif
-
-#endif /* __sslimpl_h_ */
diff --git a/security/nss/lib/ssl/sslnonce.c b/security/nss/lib/ssl/sslnonce.c
deleted file mode 100644
index 6096de656..000000000
--- a/security/nss/lib/ssl/sslnonce.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * This file implements the CLIENT Session ID cache.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "cert.h"
-#include "secitem.h"
-#include "ssl.h"
-
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "prlock.h"
-#include "nsslocks.h"
-
-
-PRUint32 ssl_sid_timeout = 100;
-PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */
-
-static sslSessionID *cache;
-static PRLock * cacheLock;
-
-/* sids can be in one of 4 states:
- *
- * never_cached, created, but not yet put into cache.
- * in_client_cache, in the client cache's linked list.
- * in_server_cache, entry came from the server's cache file.
- * invalid_cache has been removed from the cache.
- */
-
-#define LOCK_CACHE lock_cache()
-#define UNLOCK_CACHE PR_Unlock(cacheLock)
-
-static void
-lock_cache(void)
-{
- /* XXX Since the client session cache has no init function, we must
- * XXX init the cacheLock on the first call. Fix in NSS 3.0.
- */
- if (!cacheLock)
- nss_InitLock(&cacheLock);
- PR_Lock(cacheLock);
-}
-
-/* BEWARE: This function gets called for both client and server SIDs !!
- * If the unreferenced sid is not in the cache, Free sid and its contents.
- */
-static void
-ssl_DestroySID(sslSessionID *sid)
-{
- SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached));
- PORT_Assert((sid->references == 0));
-
- if (sid->cached == in_client_cache)
- return; /* it will get taken care of next time cache is traversed. */
-
- if (sid->version < SSL_LIBRARY_VERSION_3_0) {
- SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE);
- SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE);
- }
- if (sid->peerID != NULL)
- PORT_Free((void *)sid->peerID); /* CONST */
-
- if (sid->urlSvrName != NULL)
- PORT_Free((void *)sid->urlSvrName); /* CONST */
-
- if ( sid->peerCert ) {
- CERT_DestroyCertificate(sid->peerCert);
- }
-
- PORT_ZFree(sid, sizeof(sslSessionID));
-}
-
-/* BEWARE: This function gets called for both client and server SIDs !!
- * Decrement reference count, and
- * free sid if ref count is zero, and sid is not in the cache.
- * Does NOT remove from the cache first.
- * If the sid is still in the cache, it is left there until next time
- * the cache list is traversed.
- */
-static void
-ssl_FreeLockedSID(sslSessionID *sid)
-{
- PORT_Assert(sid->references >= 1);
- if (--sid->references == 0) {
- ssl_DestroySID(sid);
- }
-}
-
-/* BEWARE: This function gets called for both client and server SIDs !!
- * Decrement reference count, and
- * free sid if ref count is zero, and sid is not in the cache.
- * Does NOT remove from the cache first.
- * These locks are necessary because the sid _might_ be in the cache list.
- */
-void
-ssl_FreeSID(sslSessionID *sid)
-{
- LOCK_CACHE;
- ssl_FreeLockedSID(sid);
- UNLOCK_CACHE;
-}
-
-/************************************************************************/
-
-/*
-** Lookup sid entry in cache by Address, port, and peerID string.
-** If found, Increment reference count, and return pointer to caller.
-** If it has timed out or ref count is zero, remove from list and free it.
-*/
-
-sslSessionID *
-ssl_LookupSID(PRUint32 addr, PRUint16 port, const char *peerID,
- const char * urlSvrName)
-{
- sslSessionID **sidp;
- sslSessionID * sid;
- PRUint32 now;
-
- if (!urlSvrName)
- return NULL;
- now = ssl_Time();
- LOCK_CACHE;
- sidp = &cache;
- while ((sid = *sidp) != 0) {
- PORT_Assert(sid->cached == in_client_cache);
- PORT_Assert(sid->references >= 1);
-
- SSL_TRC(8, ("SSL: Lookup1: sid=0x%x", sid));
-
- if (sid->time < now || !sid->references) {
- /*
- ** This session-id timed out, or was orphaned.
- ** Don't even care who it belongs to, blow it out of our cache.
- */
- SSL_TRC(7, ("SSL: lookup1, throwing sid out, age=%d refs=%d",
- now - sid->time, sid->references));
-
- *sidp = sid->next; /* delink it from the list. */
- sid->cached = invalid_cache; /* mark not on list. */
- if (!sid->references)
- ssl_DestroySID(sid);
- else
- ssl_FreeLockedSID(sid); /* drop ref count, free. */
-
- } else if ((sid->addr == addr) && /* server IP addr matches */
- (sid->port == port) && /* server port matches */
- /* proxy (peerID) matches */
- (((peerID == NULL) && (sid->peerID == NULL)) ||
- ((peerID != NULL) && (sid->peerID != NULL) &&
- PORT_Strcmp(sid->peerID, peerID) == 0)) &&
- /* is cacheable */
- (sid->version < SSL_LIBRARY_VERSION_3_0 ||
- sid->u.ssl3.resumable) &&
- /* server hostname matches. */
- (sid->urlSvrName != NULL) &&
- ((0 == PORT_Strcmp(urlSvrName, sid->urlSvrName)) ||
- ((sid->peerCert != NULL) && (SECSuccess ==
- CERT_VerifyCertName(sid->peerCert, urlSvrName))) )
- ) {
- /* Hit */
- sid->references++;
- break;
- } else {
- sidp = &sid->next;
- }
- }
- UNLOCK_CACHE;
- return sid;
-}
-
-/*
-** Add an sid to the cache or return a previously cached entry to the cache.
-** Although this is static, it is called via ss->sec->cache().
-*/
-static void
-CacheSID(sslSessionID *sid)
-{
- PRUint32 expirationPeriod;
- SSL_TRC(8, ("SSL: Cache: sid=0x%x cached=%d addr=0x%08x port=0x%04x "
- "time=%x cached=%d",
- sid, sid->cached, sid->addr, sid->port, sid->time,
- sid->cached));
-
- if (sid->cached == in_client_cache)
- return;
-
- /* XXX should be different trace for version 2 vs. version 3 */
- if (sid->version < SSL_LIBRARY_VERSION_3_0) {
- expirationPeriod = ssl3_sid_timeout;
- PRINT_BUF(8, (0, "sessionID:",
- sid->u.ssl2.sessionID, sizeof(sid->u.ssl2.sessionID)));
- PRINT_BUF(8, (0, "masterKey:",
- sid->u.ssl2.masterKey.data, sid->u.ssl2.masterKey.len));
- PRINT_BUF(8, (0, "cipherArg:",
- sid->u.ssl2.cipherArg.data, sid->u.ssl2.cipherArg.len));
- } else {
- if (sid->u.ssl3.sessionIDLength == 0)
- return;
- expirationPeriod = ssl_sid_timeout;
- PRINT_BUF(8, (0, "sessionID:",
- sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength));
- }
-
- /*
- * Put sid into the cache. Bump reference count to indicate that
- * cache is holding a reference. Uncache will reduce the cache
- * reference.
- */
- LOCK_CACHE;
- sid->references++;
- sid->cached = in_client_cache;
- sid->next = cache;
- cache = sid;
- sid->time = ssl_Time() + expirationPeriod;
- UNLOCK_CACHE;
-}
-
-/*
- * If sid "zap" is in the cache,
- * removes sid from cache, and decrements reference count.
- * Caller must hold cache lock.
- */
-static void
-UncacheSID(sslSessionID *zap)
-{
- sslSessionID **sidp = &cache;
- sslSessionID *sid;
-
- if (zap->cached != in_client_cache) {
- return;
- }
-
- SSL_TRC(8,("SSL: Uncache: zap=0x%x cached=%d addr=0x%08x port=0x%04x "
- "time=%x cipher=%d",
- zap, zap->cached, zap->addr, zap->port, zap->time,
- zap->u.ssl2.cipherType));
- if (zap->version < SSL_LIBRARY_VERSION_3_0) {
- PRINT_BUF(8, (0, "sessionID:",
- zap->u.ssl2.sessionID, sizeof(zap->u.ssl2.sessionID)));
- PRINT_BUF(8, (0, "masterKey:",
- zap->u.ssl2.masterKey.data, zap->u.ssl2.masterKey.len));
- PRINT_BUF(8, (0, "cipherArg:",
- zap->u.ssl2.cipherArg.data, zap->u.ssl2.cipherArg.len));
- }
-
- /* See if it's in the cache, if so nuke it */
- while ((sid = *sidp) != 0) {
- if (sid == zap) {
- /*
- ** Bingo. Reduce reference count by one so that when
- ** everyone is done with the sid we can free it up.
- */
- *sidp = zap->next;
- zap->cached = invalid_cache;
- ssl_FreeLockedSID(zap);
- return;
- }
- sidp = &sid->next;
- }
-}
-
-/* If sid "zap" is in the cache,
- * removes sid from cache, and decrements reference count.
- * Although this function is static, it is called externally via
- * ss->sec->uncache().
- */
-static void
-LockAndUncacheSID(sslSessionID *zap)
-{
- LOCK_CACHE;
- UncacheSID(zap);
- UNLOCK_CACHE;
-
-}
-
-/* choose client or server cache functions for this sslsocket. */
-void
-ssl_ChooseSessionIDProcs(sslSecurityInfo *sec)
-{
- if (sec->isServer) {
- sec->cache = ssl_sid_cache;
- sec->uncache = ssl_sid_uncache;
- } else {
- sec->cache = CacheSID;
- sec->uncache = LockAndUncacheSID;
- }
-}
-
-/* wipe out the entire client session cache. */
-void
-SSL_ClearSessionCache(void)
-{
- LOCK_CACHE;
- while(cache != NULL)
- UncacheSID(cache);
- UNLOCK_CACHE;
-}
-
-/* returns an unsigned int containing the number of seconds in PR_Now() */
-PRUint32
-ssl_Time(void)
-{
- PRTime now;
- PRInt64 ll;
- PRUint32 time;
-
- now = PR_Now();
- LL_I2L(ll, 1000000L);
- LL_DIV(now, now, ll);
- LL_L2UI(time, now);
- return time;
-}
-
diff --git a/security/nss/lib/ssl/sslproto.h b/security/nss/lib/ssl/sslproto.h
deleted file mode 100644
index 51b780ca2..000000000
--- a/security/nss/lib/ssl/sslproto.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Various and sundry protocol constants. DON'T CHANGE THESE. These values
- * are mostly defined by the SSL2, SSL3, or TLS protocol specifications.
- * Cipher kinds and ciphersuites are part of the public API.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#ifndef __sslproto_h_
-#define __sslproto_h_
-
-#define SSL_LIBRARY_VERSION_2 0x0002
-#define SSL_LIBRARY_VERSION_2_1 0x0201
-#define SSL_LIBRARY_VERSION_3_0 0x0300
-#define SSL_LIBRARY_VERSION_3_1_TLS 0x0301
-
-/* Header lengths of some of the messages */
-#define SSL_HL_ERROR_HBYTES 3
-#define SSL_HL_CLIENT_HELLO_HBYTES 9
-#define SSL_HL_CLIENT_MASTER_KEY_HBYTES 10
-#define SSL_HL_CLIENT_FINISHED_HBYTES 1
-#define SSL_HL_SERVER_HELLO_HBYTES 11
-#define SSL_HL_SERVER_VERIFY_HBYTES 1
-#define SSL_HL_SERVER_FINISHED_HBYTES 1
-#define SSL_HL_REQUEST_CERTIFICATE_HBYTES 2
-#define SSL_HL_CLIENT_CERTIFICATE_HBYTES 6
-
-/* Security handshake protocol codes */
-#define SSL_MT_ERROR 0
-#define SSL_MT_CLIENT_HELLO 1
-#define SSL_MT_CLIENT_MASTER_KEY 2
-#define SSL_MT_CLIENT_FINISHED 3
-#define SSL_MT_SERVER_HELLO 4
-#define SSL_MT_SERVER_VERIFY 5
-#define SSL_MT_SERVER_FINISHED 6
-#define SSL_MT_REQUEST_CERTIFICATE 7
-#define SSL_MT_CLIENT_CERTIFICATE 8
-
-/* Certificate types */
-#define SSL_CT_X509_CERTIFICATE 0x01
-#if 0 /* XXX Not implemented yet */
-#define SSL_PKCS6_CERTIFICATE 0x02
-#endif
-#define SSL_AT_MD5_WITH_RSA_ENCRYPTION 0x01
-
-/* Error codes */
-#define SSL_PE_NO_CYPHERS 0x0001
-#define SSL_PE_NO_CERTIFICATE 0x0002
-#define SSL_PE_BAD_CERTIFICATE 0x0004
-#define SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
-
-/* Cypher kinds (not the spec version!) */
-#define SSL_CK_RC4_128_WITH_MD5 0x01
-#define SSL_CK_RC4_128_EXPORT40_WITH_MD5 0x02
-#define SSL_CK_RC2_128_CBC_WITH_MD5 0x03
-#define SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x04
-#define SSL_CK_IDEA_128_CBC_WITH_MD5 0x05
-#define SSL_CK_DES_64_CBC_WITH_MD5 0x06
-#define SSL_CK_DES_192_EDE3_CBC_WITH_MD5 0x07
-
-/* Cipher enables. These are used only for SSL_EnableCipher
- * These values define the SSL2 suites, and do not colide with the
- * SSL3 Cipher suites defined below.
- */
-#define SSL_EN_RC4_128_WITH_MD5 0xFF01
-#define SSL_EN_RC4_128_EXPORT40_WITH_MD5 0xFF02
-#define SSL_EN_RC2_128_CBC_WITH_MD5 0xFF03
-#define SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5 0xFF04
-#define SSL_EN_IDEA_128_CBC_WITH_MD5 0xFF05
-#define SSL_EN_DES_64_CBC_WITH_MD5 0xFF06
-#define SSL_EN_DES_192_EDE3_CBC_WITH_MD5 0xFF07
-
-/* SSL v3 Cipher Suites */
-#define SSL_NULL_WITH_NULL_NULL 0x0000
-
-#define SSL_RSA_WITH_NULL_MD5 0x0001
-#define SSL_RSA_WITH_NULL_SHA 0x0002
-#define SSL_RSA_EXPORT_WITH_RC4_40_MD5 0x0003
-#define SSL_RSA_WITH_RC4_128_MD5 0x0004
-#define SSL_RSA_WITH_RC4_128_SHA 0x0005
-#define SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 0x0006
-#define SSL_RSA_WITH_IDEA_CBC_SHA 0x0007
-#define SSL_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0008
-#define SSL_RSA_WITH_DES_CBC_SHA 0x0009
-#define SSL_RSA_WITH_3DES_EDE_CBC_SHA 0x000a
-
-#define SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA 0x000b
-#define SSL_DH_DSS_WITH_DES_CBC_SHA 0x000c
-#define SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA 0x000d
-#define SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA 0x000e
-#define SSL_DH_RSA_WITH_DES_CBC_SHA 0x000f
-#define SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA 0x0010
-
-#define SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA 0x0011
-#define SSL_DHE_DSS_WITH_DES_CBC_SHA 0x0012
-#define SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA 0x0013
-#define SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0014
-#define SSL_DHE_RSA_WITH_DES_CBC_SHA 0x0015
-#define SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016
-
-#define SSL_DH_ANON_EXPORT_WITH_RC4_40_MD5 0x0017
-#define SSL_DH_ANON_WITH_RC4_128_MD5 0x0018
-#define SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA 0x0019
-#define SSL_DH_ANON_WITH_DES_CBC_SHA 0x001a
-#define SSL_DH_ANON_WITH_3DES_EDE_CBC_SHA 0x001b
-
-#define SSL_FORTEZZA_DMS_WITH_NULL_SHA 0x001c
-#define SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA 0x001d
-#define SSL_FORTEZZA_DMS_WITH_RC4_128_SHA 0x001e
-
-/* New TLS cipher suites backported to SSL3. */
-#define TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x0062
-#define TLS_RSA_EXPORT1024_WITH_RC4_56_SHA 0x0064
-
-#define TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x0063
-#define TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x0065
-#define TLS_DHE_DSS_WITH_RC4_128_SHA 0x0066
-
-/* Netscape "experimental" cipher suites. */
-#define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0
-#define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1
-
-/* New non-experimental openly spec'ed versions of those cipher suites. */
-#define SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA 0xfeff
-#define SSL_RSA_FIPS_WITH_DES_CBC_SHA 0xfefe
-
-#endif /* __sslproto_h_ */
diff --git a/security/nss/lib/ssl/sslreveal.c b/security/nss/lib/ssl/sslreveal.c
deleted file mode 100644
index dcba7c3ef..000000000
--- a/security/nss/lib/ssl/sslreveal.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Accessor functions for SSLSocket private members.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "cert.h"
-#include "ssl.h"
-#include "certt.h"
-#include "sslimpl.h"
-
-/* given PRFileDesc, returns a copy of certificate associated with the socket
- * the caller should delete the cert when done with SSL_DestroyCertificate
- */
-CERTCertificate *
-SSL_RevealCert(PRFileDesc * fd)
-{
- CERTCertificate * cert = NULL;
- sslSocket * sslsocket = NULL;
-
- sslsocket = ssl_FindSocket(fd);
-
- /* CERT_DupCertificate increases reference count and returns pointer to
- * the same cert
- */
- if (sslsocket && sslsocket->sec)
- cert = CERT_DupCertificate(sslsocket->sec->peerCert);
-
- return cert;
-}
-
-/* given PRFileDesc, returns a pointer to PinArg associated with the socket
- */
-void *
-SSL_RevealPinArg(PRFileDesc * fd)
-{
- sslSocket * sslsocket = NULL;
- void * PinArg = NULL;
-
- sslsocket = ssl_FindSocket(fd);
-
- /* is pkcs11PinArg part of the sslSocket or sslSecurityInfo ? */
- if (sslsocket)
- PinArg = sslsocket->pkcs11PinArg;
-
- return PinArg;
-}
-
-
-/* given PRFileDesc, returns a pointer to the URL associated with the socket
- * the caller should free url when done
- */
-char *
-SSL_RevealURL(PRFileDesc * fd)
-{
- sslSocket * sslsocket = NULL;
- char * url = NULL;
-
- sslsocket = ssl_FindSocket(fd);
-
- if (sslsocket && sslsocket->url)
- url = PL_strdup(sslsocket->url);
-
- return url;
-}
-
diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c
deleted file mode 100644
index 76b252064..000000000
--- a/security/nss/lib/ssl/sslsecur.c
+++ /dev/null
@@ -1,1372 +0,0 @@
-/*
- * Various SSL functions.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-#include "cert.h"
-#include "secitem.h"
-#include "keyhi.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "secoid.h" /* for SECOID_GetALgorithmTag */
-#include "pk11func.h" /* for PK11_GenerateRandom */
-
-#if defined(_WINDOWS)
-#include "winsock.h" /* for MSG_PEEK */
-#elif defined(XP_MAC)
-#include "macsocket.h"
-#else
-#include <sys/socket.h> /* for MSG_PEEK */
-#endif
-
-#define MAX_BLOCK_CYPHER_SIZE 32
-
-#define TEST_FOR_FAILURE /* reminder */
-#define SET_ERROR_CODE /* reminder */
-
-/* Returns a SECStatus: SECSuccess or SECFailure, NOT SECWouldBlock.
- *
- * Currently, the list of functions called through ss->handshake is:
- *
- * In sslsocks.c:
- * SocksGatherRecord
- * SocksHandleReply
- * SocksStartGather
- *
- * In sslcon.c:
- * ssl_GatherRecord1stHandshake
- * ssl2_HandleClientSessionKeyMessage
- * ssl2_HandleMessage
- * ssl2_HandleVerifyMessage
- * ssl2_BeginClientHandshake
- * ssl2_BeginServerHandshake
- * ssl2_HandleClientHelloMessage
- * ssl2_HandleServerHelloMessage
- *
- * The ss->handshake function returns SECWouldBlock under these conditions:
- * 1. ssl_GatherRecord1stHandshake called ssl2_GatherData which read in
- * the beginning of an SSL v3 hello message and returned SECWouldBlock
- * to switch to SSL v3 handshake processing.
- *
- * 2. ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming
- * v2 client hello msg, and called ssl3_HandleV2ClientHello which
- * returned SECWouldBlock.
- *
- * 3. SECWouldBlock was returned by one of the callback functions, via
- * one of these paths:
- * - ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() -> ss->getClientAuthData()
- *
- * - ssl2_HandleServerHelloMessage() -> ss->handleBadCert()
- *
- * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() ->
- * ssl3_HandleRecord() -> ssl3_HandleHandshake() ->
- * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificate() ->
- * ss->handleBadCert()
- *
- * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() ->
- * ssl3_HandleRecord() -> ssl3_HandleHandshake() ->
- * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificateRequest() ->
- * ss->getClientAuthData()
- *
- * Called from: SSL_ForceHandshake (below),
- * ssl_SecureRecv (below) and
- * ssl_SecureSend (below)
- * from: WaitForResponse in sslsocks.c
- * ssl_SocksRecv in sslsocks.c
- * ssl_SocksSend in sslsocks.c
- *
- * Caller must hold the (write) handshakeLock.
- */
-int
-ssl_Do1stHandshake(sslSocket *ss)
-{
- int rv = SECSuccess;
- int loopCount = 0;
-
- PORT_Assert(ss->gather != 0);
-
- do {
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( !ssl_HaveRecvBufLock(ss) );
- PORT_Assert( !ssl_HaveXmitBufLock(ss) );
-
- if (ss->handshake == 0) {
- /* Previous handshake finished. Switch to next one */
- ss->handshake = ss->nextHandshake;
- ss->nextHandshake = 0;
- }
- if (ss->handshake == 0) {
- /* Previous handshake finished. Switch to security handshake */
- ss->handshake = ss->securityHandshake;
- ss->securityHandshake = 0;
- }
- if (ss->handshake == 0) {
- ssl_GetRecvBufLock(ss);
- ss->gather->recordLen = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- SSL_TRC(3, ("%d: SSL[%d]: handshake is completed",
- SSL_GETPID(), ss->fd));
- /* call handshake callback for ssl v2 */
- /* for v3 this is done in ssl3_HandleFinished() */
- if ((ss->sec != NULL) && /* used SSL */
- (ss->handshakeCallback != NULL) && /* has callback */
- (!ss->connected) && /* only first time */
- (ss->version < SSL_LIBRARY_VERSION_3_0)) { /* not ssl3 */
- ss->connected = PR_TRUE;
- (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
- }
- ss->connected = PR_TRUE;
- ss->gather->writeOffset = 0;
- ss->gather->readOffset = 0;
- break;
- }
- rv = (*ss->handshake)(ss);
- ++loopCount;
- /* This code must continue to loop on SECWouldBlock,
- * or any positive value. See XXX_1 comments.
- */
- } while (rv != SECFailure); /* was (rv >= 0); XXX_1 */
-
- PORT_Assert( !ssl_HaveRecvBufLock(ss) );
- PORT_Assert( !ssl_HaveXmitBufLock(ss) );
-
- if (rv == SECWouldBlock) {
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- rv = SECFailure;
- }
- return rv;
-}
-
-/*
- * Handshake function that blocks. Used to force a
- * retry on a connection on the next read/write.
- */
-#ifdef macintosh
-static SECStatus
-#else
-static int
-#endif
-AlwaysBlock(sslSocket *ss)
-{
- PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */
- return SECWouldBlock;
-}
-
-/*
- * set the initial handshake state machine to block
- */
-void
-ssl_SetAlwaysBlock(sslSocket *ss)
-{
- if (!ss->connected) {
- ss->handshake = AlwaysBlock;
- ss->nextHandshake = 0;
- }
-}
-
-/* Acquires and releases HandshakeLock.
-*/
-SECStatus
-SSL_ResetHandshake(PRFileDesc *s, PRBool asServer)
-{
- sslSocket *ss;
- SECStatus rv;
-
- ss = ssl_FindSocket(s);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in ResetHandshake", SSL_GETPID(), s));
- return SECFailure;
- }
-
- /* Don't waste my time */
- if (!ss->useSecurity)
- return SECSuccess;
-
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
-
- /* Reset handshake state */
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- ss->connected = PR_FALSE;
- ss->handshake = asServer ? ssl2_BeginServerHandshake
- : ssl2_BeginClientHandshake;
- ss->nextHandshake = 0;
- ss->securityHandshake = 0;
-
- ssl_GetRecvBufLock(ss);
- ss->gather->state = GS_INIT;
- ss->gather->writeOffset = 0;
- ss->gather->readOffset = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- /*
- ** Blow away old security state and get a fresh setup. This way if
- ** ssl was used to connect to the first point in communication, ssl
- ** can be used for the next layer.
- */
- if (ss->sec) {
- ssl_DestroySecurityInfo(ss->sec);
- ss->sec = 0;
- }
- rv = ssl_CreateSecurityInfo(ss);
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- SSL_UNLOCK_WRITER(ss);
- SSL_UNLOCK_READER(ss);
-
- return rv;
-}
-
-/* For SSLv2, does nothing but return an error.
-** For SSLv3, flushes SID cache entry (if requested),
-** and then starts new client hello or hello request.
-** Acquires and releases HandshakeLock.
-*/
-int
-SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd));
- PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
- return SECFailure;
- }
-
- if (!ss->useSecurity)
- return SECSuccess;
-
- ssl_Get1stHandshakeLock(ss);
-
- /* SSL v2 protocol does not support subsequent handshakes. */
- if (ss->version < SSL_LIBRARY_VERSION_3_0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- } else {
- ssl_GetSSL3HandshakeLock(ss);
- rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */
- ssl_ReleaseSSL3HandshakeLock(ss);
- }
-
- ssl_Release1stHandshakeLock(ss);
-
- return rv;
-}
-
-int
-SSL_RedoHandshake(PRFileDesc *fd)
-{
- return SSL_ReHandshake(fd, PR_TRUE);
-}
-
-/* Register an application callback to be called when SSL handshake completes.
-** Acquires and releases HandshakeLock.
-*/
-int
-SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb,
- void *client_data)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeCallback",
- SSL_GETPID(), fd));
- PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
- return SECFailure;
- }
-
- if (!ss->useSecurity) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- PORT_Assert(ss->sec);
- ss->handshakeCallback = cb;
- ss->handshakeCallbackData = client_data;
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- return SECSuccess;
-}
-
-/* Try to make progress on an SSL handshake by attempting to read the
-** next handshake from the peer, and sending any responses.
-** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot
-** read the next handshake from the underlying socket.
-** For SSLv2, returns when handshake is complete or fatal error occurs.
-** For SSLv3, returns when handshake is complete, or application data has
-** arrived that must be taken by application before handshake can continue,
-** or a fatal error occurs.
-** Application should use handshake completion callback to tell which.
-*/
-int
-SSL_ForceHandshake(PRFileDesc *fd)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in ForceHandshake",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- /* Don't waste my time */
- if (!ss->useSecurity)
- return 0;
-
- ssl_Get1stHandshakeLock(ss);
-
- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
- ssl_GetRecvBufLock(ss);
- rv = ssl3_GatherCompleteHandshake(ss, 0);
- ssl_ReleaseRecvBufLock(ss);
- if (rv == 0) {
- PORT_SetError(PR_END_OF_FILE_ERROR);
- rv = SECFailure;
- } else if (rv == SECWouldBlock) {
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- rv = SECFailure;
- }
- } else if (!ss->connected) {
- rv = ssl_Do1stHandshake(ss);
- } else {
- /* tried to force handshake on a connected SSL 2 socket. */
- rv = SECSuccess; /* just pretend we did it. */
- }
-
- ssl_Release1stHandshakeLock(ss);
-
- if (rv > 0)
- rv = SECSuccess;
- return rv;
-}
-
-/************************************************************************/
-
-/*
-** Grow a buffer to hold newLen bytes of data.
-** Called for both recv buffers and xmit buffers.
-** Caller must hold xmitBufLock or recvBufLock, as appropriate.
-*/
-SECStatus
-sslBuffer_Grow(sslBuffer *b, unsigned int newLen)
-{
- if (newLen > b->space) {
- if (b->buf) {
- b->buf = (unsigned char *) PORT_Realloc(b->buf, newLen);
- } else {
- b->buf = (unsigned char *) PORT_Alloc(newLen);
- }
- if (!b->buf) {
- return SECFailure;
- }
- SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d",
- SSL_GETPID(), b->space, newLen));
- b->space = newLen;
- }
- return SECSuccess;
-}
-
-/*
-** Save away write data that is trying to be written before the security
-** handshake has been completed. When the handshake is completed, we will
-** flush this data out.
-** Caller must hold xmitBufLock
-*/
-SECStatus
-ssl_SaveWriteData(sslSocket *ss, sslBuffer *buf, const void *data,
- unsigned int len)
-{
- unsigned int newlen;
- SECStatus rv;
-
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
- newlen = buf->len + len;
- if (newlen > buf->space) {
- rv = sslBuffer_Grow(buf, newlen);
- if (rv) {
- return rv;
- }
- }
- SSL_TRC(5, ("%d: SSL[%d]: saving %d bytes of data (%d total saved so far)",
- SSL_GETPID(), ss->fd, len, newlen));
- PORT_Memcpy(buf->buf + buf->len, data, len);
- buf->len = newlen;
- return SECSuccess;
-}
-
-/*
-** Send saved write data. This will flush out data sent prior to a
-** complete security handshake. Hopefully there won't be too much of it.
-** Returns count of the bytes sent, NOT a SECStatus.
-** Caller must hold xmitBufLock
-*/
-int
-ssl_SendSavedWriteData(sslSocket *ss, sslBuffer *buf, sslSendFunc send)
-{
- int rv = 0;
- int len = buf->len;
-
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
- if (len != 0) {
- SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data",
- SSL_GETPID(), ss->fd, len));
- rv = (*send)(ss, buf->buf, len, 0);
- if (rv < 0) {
- return rv;
- }
- if (rv < len) {
- /* UGH !! This shifts the whole buffer down by copying it, and
- ** it depends on PORT_Memmove doing overlapping moves correctly!
- ** It should advance the pointer offset instead !!
- */
- PORT_Memmove(buf->buf, buf->buf + rv, len - rv);
- buf->len = len - rv;
- } else {
- buf->len = 0;
- }
- }
- return rv;
-}
-
-/************************************************************************/
-
-/*
-** Receive some application data on a socket. Reads SSL records from the input
-** stream, decrypts them and then copies them to the output buffer.
-** Called from ssl_SecureRecv() below.
-**
-** Caller does NOT hold 1stHandshakeLock because that handshake is over.
-** Caller doesn't call this until initial handshake is complete.
-** For SSLv2, there is no subsequent handshake.
-** For SSLv3, the call to ssl3_GatherAppDataRecord may encounter handshake
-** messages from a subsequent handshake.
-**
-** This code is similar to, and easily confused with,
-** ssl_GatherRecord1stHandshake() in sslcon.c
-*/
-static int
-DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
-{
- sslGather * gs;
- int rv;
- int amount;
- int available;
-
- ssl_GetRecvBufLock(ss);
- PORT_Assert((ss->sec != 0) && (ss->gather != 0));
- gs = ss->gather;
-
- available = gs->writeOffset - gs->readOffset;
- if (available == 0) {
- /* Get some more data */
- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
- /* Wait for application data to arrive. */
- rv = ssl3_GatherAppDataRecord(ss, 0);
- } else {
- /* See if we have a complete record */
- rv = ssl2_GatherRecord(ss, 0);
- }
- if (rv <= 0) {
- if (rv == 0) {
- /* EOF */
- SSL_TRC(10, ("%d: SSL[%d]: ssl_recv EOF",
- SSL_GETPID(), ss->fd));
- goto done;
- }
- if ((rv != SECWouldBlock) &&
- (PR_GetError() != PR_WOULD_BLOCK_ERROR)) {
- /* Some random error */
- goto done;
- }
-
- /*
- ** Gather record is blocked waiting for more record data to
- ** arrive. Try to process what we have already received
- */
- } else {
- /* Gather record has finished getting a complete record */
- }
-
- /* See if any clear data is now available */
- available = gs->writeOffset - gs->readOffset;
- if (available == 0) {
- /*
- ** No partial data is available. Force error code to
- ** EWOULDBLOCK so that caller will try again later. Note
- ** that the error code is probably EWOULDBLOCK already,
- ** but if it isn't (for example, if we received a zero
- ** length record) then this will force it to be correct.
- */
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- rv = SECFailure;
- goto done;
- }
- SSL_TRC(30, ("%d: SSL[%d]: partial data ready, available=%d",
- SSL_GETPID(), ss->fd, available));
- }
-
- /* Dole out clear data to reader */
- amount = PR_MIN(len, available);
- PORT_Memcpy(out, gs->buf.buf + gs->readOffset, amount);
- if (!(flags & MSG_PEEK)) {
- gs->readOffset += amount;
- }
- rv = amount;
-
- SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d",
- SSL_GETPID(), ss->fd, amount, available));
- PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount));
-
-done:
- ssl_ReleaseRecvBufLock(ss);
- return rv;
-}
-
-/************************************************************************/
-
-SSLKEAType
-ssl_FindCertKEAType(CERTCertificate * cert)
-{
- SSLKEAType keaType = kt_null;
- int tag;
-
- if (!cert) goto loser;
-
- tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
-
- switch (tag) {
- case SEC_OID_X500_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- keaType = kt_rsa;
- break;
- case SEC_OID_MISSI_KEA_DSS_OLD:
- case SEC_OID_MISSI_KEA_DSS:
- case SEC_OID_MISSI_DSS_OLD:
- case SEC_OID_MISSI_DSS:
- keaType = kt_fortezza;
- break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- keaType = kt_dh;
- break;
- default:
- keaType = kt_null;
- }
-
- loser:
-
- return keaType;
-
-}
-
-
-/* XXX need to protect the data that gets changed here.!! */
-
-SECStatus
-SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert,
- SECKEYPrivateKey *key, SSL3KEAType kea)
-{
- int rv;
- sslSocket *ss;
- sslSecurityInfo *sec;
-
- ss = ssl_FindSocket(fd);
-
- if ((rv = ssl_CreateSecurityInfo(ss)) != 0) {
- return((SECStatus)rv);
- }
-
- sec = ss->sec;
- if (sec == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* Both key and cert must have a value or be NULL */
- /* Passing a value of NULL will turn off key exchange algorithms that were
- * previously turned on */
- if (!cert != !key) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* make sure the key exchange is recognized */
- if ((kea > kt_kea_size) || (kea < kt_null)) {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- return SECFailure;
- }
-
- if (kea != ssl_FindCertKEAType(cert)) {
- PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH);
- return SECFailure;
- }
-
- /* load the server certificate */
- if (ss->serverCert[kea] != NULL)
- CERT_DestroyCertificate(ss->serverCert[kea]);
- if (cert) {
- ss->serverCert[kea] = CERT_DupCertificate(cert);
- if (ss->serverCert[kea] == NULL)
- goto loser;
- } else ss->serverCert[kea] = NULL;
-
-
- /* load the server cert chain */
- if (ss->serverCertChain[kea] != NULL)
- CERT_DestroyCertificateList(ss->serverCertChain[kea]);
- if (cert) {
- ss->serverCertChain[kea] = CERT_CertChainFromCert(
- ss->serverCert[kea], certUsageSSLServer, PR_TRUE);
- if (ss->serverCertChain[kea] == NULL)
- goto loser;
- } else ss->serverCertChain[kea] = NULL;
-
-
- /* Only do this once because it's global. */
- if (ssl3_server_ca_list == NULL)
- ssl3_server_ca_list = CERT_GetSSLCACerts(ss->dbHandle);
-
- /* load the private key */
- if (ss->serverKey[kea] != NULL)
- SECKEY_DestroyPrivateKey(ss->serverKey[kea]);
- if (key) {
- ss->serverKey[kea] = SECKEY_CopyPrivateKey(key);
- if (ss->serverKey[kea] == NULL)
- goto loser;
- } else ss->serverKey[kea] = NULL;
-
- if (kea == kt_rsa) {
- rv = ssl3_CreateRSAStepDownKeys(ss);
- if (rv != SECSuccess) {
- return SECFailure; /* err set by ssl3_CreateRSAStepDownKeys */
- }
- }
-
- return SECSuccess;
-
-loser:
- if (ss->serverCert[kea] != NULL) {
- CERT_DestroyCertificate(ss->serverCert[kea]);
- ss->serverCert[kea] = NULL;
- }
- if (ss->serverCertChain != NULL) {
- CERT_DestroyCertificateList(ss->serverCertChain[kea]);
- ss->serverCertChain[kea] = NULL;
- }
- if (ss->serverKey[kea] != NULL) {
- SECKEY_DestroyPrivateKey(ss->serverKey[kea]);
- ss->serverKey[kea] = NULL;
- }
- return SECFailure;
-}
-
-/************************************************************************/
-
-SECStatus
-ssl_CreateSecurityInfo(sslSocket *ss)
-{
- sslSecurityInfo * sec = (sslSecurityInfo *)0;
- sslGather * gs = (sslGather * )0;
- int rv;
-
- unsigned char padbuf[MAX_BLOCK_CYPHER_SIZE];
-
- if (ss->sec) {
- return SECSuccess;
- }
-
- /* Force the global RNG to generate some random data that we never use */
- PK11_GenerateRandom(padbuf, sizeof padbuf);
-
- ss->sec = sec = (sslSecurityInfo*) PORT_ZAlloc(sizeof(sslSecurityInfo));
- if (!sec) {
- goto loser;
- }
-
- /* initialize sslv2 socket to send data in the clear. */
- ssl2_UseClearSendFunc(ss);
-
- sec->blockSize = 1;
- sec->blockShift = 0;
-
- ssl_GetRecvBufLock(ss);
- if ((gs = ss->gather) == 0) {
- ss->gather = gs = ssl_NewGather();
- if (!gs) {
- goto loser;
- }
- }
-
- rv = sslBuffer_Grow(&gs->buf, 4096);
- if (rv) {
- goto loser;
- }
- ssl_ReleaseRecvBufLock(ss);
-
- ssl_GetXmitBufLock(ss);
- rv = sslBuffer_Grow(&sec->writeBuf, 4096);
- if (rv) {
- goto loser;
- }
- ssl_ReleaseXmitBufLock(ss);
-
- SSL_TRC(5, ("%d: SSL[%d]: security info created", SSL_GETPID(), ss->fd));
- return SECSuccess;
-
- loser:
- if (sec) {
- PORT_Free(sec);
- ss->sec = sec = (sslSecurityInfo *)0;
- }
- if (gs) {
- ssl_DestroyGather(gs);
- ss->gather = gs = (sslGather *)0;
- }
- return SECFailure;
-}
-
-/* XXX We should handle errors better in this function. */
-/* This function assumes that none of the pointers in ss need to be
-** freed.
-*/
-SECStatus
-ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os)
-{
- sslSecurityInfo *sec, *osec;
- int rv;
-
- rv = ssl_CreateSecurityInfo(ss);
- if (rv < 0) {
- goto loser;
- }
- sec = ss->sec;
- osec = os->sec;
-
- sec->send = osec->send;
- sec->isServer = osec->isServer;
- sec->keyBits = osec->keyBits;
- sec->secretKeyBits = osec->secretKeyBits;
-
- sec->peerCert = CERT_DupCertificate(osec->peerCert);
-
- sec->cache = osec->cache;
- sec->uncache = osec->uncache;
-
- /* we don't dup the connection info. */
-
- sec->sendSequence = osec->sendSequence;
- sec->rcvSequence = osec->rcvSequence;
-
- if (osec->hash && osec->hashcx) {
- sec->hash = osec->hash;
- sec->hashcx = osec->hash->clone(osec->hashcx);
- } else {
- sec->hash = NULL;
- sec->hashcx = NULL;
- }
-
- SECITEM_CopyItem(0, &sec->sendSecret, &osec->sendSecret);
- SECITEM_CopyItem(0, &sec->rcvSecret, &osec->rcvSecret);
-
- PORT_Assert(osec->readcx == 0);
- sec->readcx = osec->readcx; /* XXX wrong if readcx != 0 */
- PORT_Assert(osec->writecx == 0);
- sec->writecx = osec->writecx; /* XXX wrong if writecx != 0 */
- sec->destroy = 0; /* XXX wrong if either cx != 0*/
-
- sec->enc = osec->enc;
- sec->dec = osec->dec;
-
- sec->blockShift = osec->blockShift;
- sec->blockSize = osec->blockSize;
-
- return SECSuccess;
-
-loser:
- return SECFailure;
-}
-
-/*
-** Called from SSL_ResetHandshake (above), and
-** from ssl_FreeSocket in sslsock.c
-*/
-void
-ssl_DestroySecurityInfo(sslSecurityInfo *sec)
-{
- if (sec != 0) {
- /* Destroy MAC */
- if (sec->hash && sec->hashcx) {
- (*sec->hash->destroy)(sec->hashcx, PR_TRUE);
- sec->hashcx = 0;
- }
- SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE);
- SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE);
-
- /* Destroy ciphers */
- if (sec->destroy) {
- (*sec->destroy)(sec->readcx, PR_TRUE);
- (*sec->destroy)(sec->writecx, PR_TRUE);
- } else {
- PORT_Assert(sec->readcx == 0);
- PORT_Assert(sec->writecx == 0);
- }
- sec->readcx = 0;
- sec->writecx = 0;
-
- /* etc. */
- PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space);
- sec->writeBuf.buf = 0;
-
- CERT_DestroyCertificate(sec->peerCert);
- sec->peerCert = NULL;
-
- PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space);
- if (sec->ci.sid != NULL) {
- ssl_FreeSID(sec->ci.sid);
- }
-
- PORT_ZFree(sec, sizeof *sec);
- }
-}
-
-/************************************************************************/
-
-int
-ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa)
-{
- PRFileDesc *osfd = ss->fd->lower;
- int rv;
-
- PORT_Assert(ss->sec != 0);
-
- /* First connect to server */
- rv = osfd->methods->connect(osfd, sa, ss->cTimeout);
- if (rv < 0) {
- int olderrno = PR_GetError();
- SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d",
- SSL_GETPID(), ss->fd, olderrno));
- if ((olderrno == PR_IS_CONNECTED_ERROR) ||
- (olderrno == PR_IN_PROGRESS_ERROR)) {
- /*
- ** Connected or trying to connect. Caller is Using a non-blocking
- ** connect. Go ahead and set things up.
- */
- } else {
- return rv;
- }
- }
-
- SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, setting up handshake",
- SSL_GETPID(), ss->fd));
-
- if ( ss->handshakeAsServer ) {
- ss->securityHandshake = ssl2_BeginServerHandshake;
- } else {
- ss->securityHandshake = ssl2_BeginClientHandshake;
- }
-
- return rv;
-}
-
-int
-ssl_SecureSocksConnect(sslSocket *ss, const PRNetAddr *sa)
-{
- int rv;
-
- PORT_Assert((ss->socks != 0) && (ss->sec != 0));
-
- /* First connect to socks daemon */
- rv = ssl_SocksConnect(ss, sa);
- if (rv < 0) {
- return rv;
- }
-
- if ( ss->handshakeAsServer ) {
- ss->securityHandshake = ssl2_BeginServerHandshake;
- } else {
- ss->securityHandshake = ssl2_BeginClientHandshake;
- }
-
- return 0;
-}
-
-PRFileDesc *
-ssl_SecureSocksAccept(sslSocket *ss, PRNetAddr *addr)
-{
-#if 0
- sslSocket *ns;
- int rv;
- PRFileDesc *newfd, *fd;
-
- newfd = ssl_SocksAccept(ss, addr);
- if (newfd == NULL) {
- return newfd;
- }
-
- /* Create new socket */
- ns = ssl_FindSocket(newfd);
- PORT_Assert(ns != NULL);
-
- /* Make an NSPR socket to give back to app */
- fd = ssl_NewPRSocket(ns, newfd);
- if (fd == NULL) {
- ssl_FreeSocket(ns);
- PR_Close(newfd);
- return NULL;
- }
-
- if ( ns->handshakeAsClient ) {
- ns->handshake = ssl2_BeginClientHandshake;
- } else {
- ns->handshake = ssl2_BeginServerHandshake;
- }
-
- return fd;
-#else
- return NULL;
-#endif
-}
-
-int
-ssl_SecureClose(sslSocket *ss)
-{
- int rv;
-
- if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
- ss->connected &&
- !(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
- (ss->ssl3 != NULL)) {
-
- (void) SSL3_SendAlert(ss, alert_warning, close_notify);
- }
- rv = ssl_DefClose(ss);
- return rv;
-}
-
-/* Caller handles all locking */
-int
-ssl_SecureShutdown(sslSocket *ss, int nsprHow)
-{
- PRFileDesc *osfd = ss->fd->lower;
- int rv;
- PRIntn sslHow = nsprHow + 1;
-
- if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return PR_FAILURE;
- }
-
- if ((sslHow & ssl_SHUTDOWN_SEND) != 0 &&
- !(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
- (ss->version >= SSL_LIBRARY_VERSION_3_0) &&
- ss->connected &&
- (ss->ssl3 != NULL)) {
-
- (void) SSL3_SendAlert(ss, alert_warning, close_notify);
- }
-
- rv = osfd->methods->shutdown(osfd, nsprHow);
-
- ss->shutdownHow |= sslHow;
-
- return rv;
-}
-
-/************************************************************************/
-
-
-int
-ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
-{
- sslSecurityInfo *sec;
- int rv = 0;
-
- PORT_Assert(ss->sec != 0);
- sec = ss->sec;
-
- if (ss->shutdownHow & ssl_SHUTDOWN_RCV) {
- PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
- return PR_FAILURE;
- }
- if (flags & ~MSG_PEEK) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return PR_FAILURE;
- }
-
- if (!ssl_SocketIsBlocking(ss) && !ss->fdx) {
- ssl_GetXmitBufLock(ss);
- if (ss->pendingBuf.len != 0) {
- rv = ssl_SendSavedWriteData(ss, &ss->pendingBuf, ssl_DefSend);
- if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) {
- ssl_ReleaseXmitBufLock(ss);
- return SECFailure;
- }
- /* XXX short write? */
- }
- ssl_ReleaseXmitBufLock(ss);
- }
-
- rv = 0;
- /* If any of these is non-zero, the initial handshake is not done. */
- if (!ss->connected) {
- ssl_Get1stHandshakeLock(ss);
- if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {
- rv = ssl_Do1stHandshake(ss);
- }
- ssl_Release1stHandshakeLock(ss);
- }
- if (rv < 0) {
- return rv;
- }
-
- if (len == 0) return 0;
-
- rv = DoRecv(ss, (unsigned char*) buf, len, flags);
- SSL_TRC(2, ("%d: SSL[%d]: recving %d bytes securely (errno=%d)",
- SSL_GETPID(), ss->fd, rv, PORT_GetError()));
- return rv;
-}
-
-int
-ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len)
-{
- return ssl_SecureRecv(ss, buf, len, 0);
-}
-
-int
-ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
-{
- sslSecurityInfo *sec;
- int rv = 0;
-
- PORT_Assert(ss->sec != 0);
- sec = ss->sec;
-
- if (ss->shutdownHow & ssl_SHUTDOWN_SEND) {
- PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
- return PR_FAILURE;
- }
- if (flags) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return PR_FAILURE;
- }
-
- ssl_GetXmitBufLock(ss);
- if (ss->pendingBuf.len != 0) {
- PORT_Assert(ss->pendingBuf.len > 0);
- rv = ssl_SendSavedWriteData(ss, &ss->pendingBuf, ssl_DefSend);
- if (ss->pendingBuf.len != 0) {
- PORT_Assert(ss->pendingBuf.len > 0);
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- rv = SECFailure;
- }
- }
- ssl_ReleaseXmitBufLock(ss);
- if (rv < 0) {
- return rv;
- }
-
- /* If any of these is non-zero, the initial handshake is not done. */
- if (!ss->connected) {
- ssl_Get1stHandshakeLock(ss);
- if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {
- rv = ssl_Do1stHandshake(ss);
- }
- ssl_Release1stHandshakeLock(ss);
- }
- if (rv < 0) {
- return rv;
- }
-
- /* Check for zero length writes after we do housekeeping so we make forward
- * progress.
- */
- if (len == 0) return 0;
- PORT_Assert(buf != NULL);
-
- SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
- SSL_GETPID(), ss->fd, len));
-
- /* Send out the data using one of these functions:
- * ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock,
- * ssl3_SendApplicationData
- */
- ssl_GetXmitBufLock(ss);
- rv = (*sec->send)(ss, buf, len, flags);
- ssl_ReleaseXmitBufLock(ss);
- return rv;
-}
-
-int
-ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len)
-{
- return ssl_SecureSend(ss, buf, len, 0);
-}
-
-int
-SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if ((rv = ssl_CreateSecurityInfo(ss)) != 0) {
- return(rv);
- }
- ss->handleBadCert = f;
- ss->badCertArg = arg;
-
- return(0);
-}
-
-/*
- * Allow the application to pass the url or hostname into the SSL library
- * so that we can do some checking on it.
- */
-int
-SSL_SetURL(PRFileDesc *fd, const char *url)
-{
- sslSocket * ss = ssl_FindSocket(fd);
- int rv = SECSuccess;
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- if ( ss->url ) {
- PORT_Free((void *)ss->url); /* CONST */
- }
-
- ss->url = (const char *)PORT_Strdup(url);
- if ( ss->url == NULL ) {
- rv = SECFailure;
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- return rv;
-}
-
-/*
-** Returns Negative number on error, zero or greater on success.
-** Returns the amount of data immediately available to be read.
-*/
-int
-SSL_DataPending(PRFileDesc *fd)
-{
- sslSocket *ss;
- int rv = 0;
-
- ss = ssl_FindSocket(fd);
-
-
- if (ss && ss->useSecurity) {
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- /* Create ss->sec if it doesn't already exist. */
- rv = ssl_CreateSecurityInfo(ss);
- if (rv == SECSuccess) {
- ssl_GetRecvBufLock(ss);
- rv = ss->gather->writeOffset - ss->gather->readOffset;
- ssl_ReleaseRecvBufLock(ss);
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
- }
-
- return rv;
-}
-
-int
-SSL_InvalidateSession(PRFileDesc *fd)
-{
- sslSocket * ss = ssl_FindSocket(fd);
- int rv = SECFailure;
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- if (ss && ss->sec && ss->sec->ci.sid) {
- ss->sec->uncache(ss->sec->ci.sid);
- rv = SECSuccess;
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- return rv;
-}
-
-SECItem *
-SSL_GetSessionID(PRFileDesc *fd)
-{
- sslSocket * ss;
- SECItem * item = NULL;
- sslSessionID * sid;
-
- ss = ssl_FindSocket(fd);
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- if (ss && ss->useSecurity && ss->connected && ss->sec && ss->sec->ci.sid) {
- sid = ss->sec->ci.sid;
- item = (SECItem *)PORT_Alloc(sizeof(SECItem));
- if (sid->version < SSL_LIBRARY_VERSION_3_0) {
- item->len = SSL_SESSIONID_BYTES;
- item->data = (unsigned char*)PORT_Alloc(item->len);
- PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len);
- } else {
- item->len = sid->u.ssl3.sessionIDLength;
- item->data = (unsigned char*)PORT_Alloc(item->len);
- PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len);
- }
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- return item;
-}
-
-SECStatus
-SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle)
-{
- sslSocket * ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss)
- return SECFailure;
- if (!dbHandle) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- ss->dbHandle = dbHandle;
- return SECSuccess;
-}
-
-/*
- * attempt to restart the handshake after asynchronously handling
- * a request for the client's certificate.
- *
- * inputs:
- * cert Client cert chosen by application.
- * Note: ssl takes this reference, and does not bump the
- * reference count. The caller should drop its reference
- * without calling CERT_DestroyCert after calling this function.
- *
- * key Private key associated with cert. This function makes a
- * copy of the private key, so the caller remains responsible
- * for destroying its copy after this function returns.
- *
- * certChain Chain of signers for cert.
- * Note: ssl takes this reference, and does not copy the chain.
- * The caller should drop its reference without destroying the
- * chain. SSL will free the chain when it is done with it.
- *
- * Return value: XXX
- *
- * XXX This code only works on the initial handshake on a connection, XXX
- * It does not work on a subsequent handshake (redo).
- */
-int
-SSL_RestartHandshakeAfterCertReq(sslSocket * ss,
- CERTCertificate * cert,
- SECKEYPrivateKey * key,
- CERTCertificateList *certChain)
-{
- int ret;
-
- ssl_Get1stHandshakeLock(ss); /************************************/
-
- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
- ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain);
- } else {
- ret = ssl2_RestartHandshakeAfterCertReq(ss, cert, key);
- }
-
- ssl_Release1stHandshakeLock(ss); /************************************/
- return ret;
-}
-
-
-/* restart an SSL connection that we stopped to run certificate dialogs
-** XXX Need to document here how an application marks a cert to show that
-** the application has accepted it (overridden CERT_VerifyCert).
- *
- * XXX This code only works on the initial handshake on a connection, XXX
- * It does not work on a subsequent handshake (redo).
- *
- * Return value: XXX
-*/
-int
-SSL_RestartHandshakeAfterServerCert(sslSocket *ss)
-{
- int rv = SECSuccess;
-
- ssl_Get1stHandshakeLock(ss);
-
- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
- rv = ssl3_RestartHandshakeAfterServerCert(ss);
- } else {
- rv = ssl2_RestartHandshakeAfterServerCert(ss);
- }
-
- ssl_Release1stHandshakeLock(ss);
- return rv;
-}
diff --git a/security/nss/lib/ssl/sslsnce.c b/security/nss/lib/ssl/sslsnce.c
deleted file mode 100644
index bf58c954d..000000000
--- a/security/nss/lib/ssl/sslsnce.c
+++ /dev/null
@@ -1,1905 +0,0 @@
-/* This file implements the SERVER Session ID cache.
- * NOTE: The contents of this file are NOT used by the client.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-/* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server
- * cache sids!
- *
- * About record locking among different server processes:
- *
- * All processes that are part of the same conceptual server (serving on
- * the same address and port) MUST share a common SSL session cache.
- * This code makes the content of the shared cache accessible to all
- * processes on the same "server". This code works on Unix and Win32 only,
- * and is platform specific.
- *
- * Unix: Multiple processes share a single (inherited) FD for a disk
- * file all share one single file position. If one lseeks, the position for
- * all processes is changed. Since the set of platforms we support do not
- * all share portable lseek-and-read or lseek-and-write functions, a global
- * lock must be used to make the lseek call and the subsequent read or write
- * call be one atomic operation. It is no longer necessary for cache element
- * sizes to be a power of 2, or a multiple of a sector size.
- *
- * For Win32, where (a) disk I/O is not atomic, and (b) we use memory-mapped
- * files and move data to & from memory instead of calling read or write,
- * we must do explicit locking of the records for all reads and writes.
- * We have just one lock, for the entire file, using an NT semaphore.
- * We avoid blocking on "local threads" since it's bad to block on a local
- * thread - If NSPR offered portable semaphores, it would handle this itself.
- *
- * Since this file has to do lots of platform specific I/O, the system
- * dependent error codes need to be mapped back into NSPR error codes.
- * Since NSPR's error mapping functions are private, the code is necessarily
- * duplicated in libSSL.
- *
- * Note, now that NSPR provides portable anonymous shared memory, for all
- * platforms except Mac, the implementation below should be replaced with
- * one that uses anonymous shared memory ASAP. This will eliminate most
- * platform dependent code in this file, and improve performance big time.
- *
- * Now that NSPR offers portable cross-process locking (semaphores) on Unix
- * and Win32, semaphores should be used here for all platforms.
- */
-#include "seccomon.h"
-
-#if defined(XP_UNIX) || defined(XP_WIN32)
-#ifndef NADA_VERISON
-
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "pk11func.h"
-#include "base64.h"
-
-#include <stdio.h>
-
-#ifdef XP_UNIX
-
-#include <syslog.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "unix_err.h"
-
-#else /* XP_WIN32 */
-#ifdef MC_HTTPD
-#include <ereport.h>
-#endif /* MC_HTTPD */
-#include <wtypes.h>
-#include "win32err.h"
-#endif /* XP_WIN32 */
-#include <sys/types.h>
-
-#define SET_ERROR_CODE /* reminder */
-
-#include "nspr.h"
-#include "nsslocks.h"
-
-static PRLock *cacheLock;
-
-/*
-** The server session-id cache uses a simple flat cache. The cache is
-** sized during initialization. We hash the ip-address + session-id value
-** into an index into the cache and do the lookup. No buckets, nothing
-** fancy.
-*/
-
-static PRBool isMultiProcess = PR_FALSE;
-
-static PRUint32 numSIDCacheEntries = 10000;
-static PRUint32 sidCacheFileSize;
-static PRUint32 sidCacheWrapOffset;
-
-static PRUint32 numCertCacheEntries = 250;
-static PRUint32 certCacheFileSize;
-
-#define MIN_CERT_CACHE_ENTRIES 125 /* the effective size in old releases. */
-
-
-/*
-** Format of a cache entry.
-*/
-typedef struct SIDCacheEntryStr SIDCacheEntry;
-struct SIDCacheEntryStr {
- PRUint32 addr;
- PRUint32 time;
-
- union {
- struct {
- /* This is gross. We have to have version and valid in both arms
- * of the union for alignment reasons. This probably won't work
- * on a 64-bit machine. XXXX
- */
-/* 2 */ uint16 version;
-/* 1 */ unsigned char valid;
-/* 1 */ unsigned char cipherType;
-
-/* 16 */ unsigned char sessionID[SSL_SESSIONID_BYTES];
-/* 64 */ unsigned char masterKey[SSL_MAX_MASTER_KEY_BYTES];
-/* 32 */ unsigned char cipherArg[SSL_MAX_CYPHER_ARG_BYTES];
-
-/* 1 */ unsigned char masterKeyLen;
-/* 1 */ unsigned char keyBits;
-
-/* 1 */ unsigned char secretKeyBits;
-/* 1 */ unsigned char cipherArgLen;
-/*120 */} ssl2;
-
- struct {
-/* 2 */ uint16 version;
-/* 1 */ unsigned char valid;
-/* 1 */ uint8 sessionIDLength;
-
-/* 32 */ unsigned char sessionID[SSL3_SESSIONID_BYTES];
-
-/* 2 */ ssl3CipherSuite cipherSuite;
-/* 2 */ uint16 compression; /* SSL3CompressionMethod */
-
-/*122 */ ssl3SidKeys keys; /* keys and ivs, wrapped as needed. */
-/* 4 */ PRUint32 masterWrapMech;
-/* 4 */ SSL3KEAType exchKeyType;
-
-/* 2 */ int16 certIndex;
-/* 1 */ uint8 hasFortezza;
-/* 1 */ uint8 resumable;
- } ssl3;
- /* We can't make this struct fit in 128 bytes
- * so, force the struct size up to the next power of two.
- */
- struct {
- unsigned char filler[248]; /* 248 + 4 + 4 == 256 */
- } force256;
- } u;
-};
-
-
-typedef struct CertCacheEntryStr CertCacheEntry;
-
-/* The length of this struct is supposed to be a power of 2, e.g. 4KB */
-struct CertCacheEntryStr {
- uint16 certLength; /* 2 */
- uint16 sessionIDLength; /* 2 */
- unsigned char sessionID[SSL3_SESSIONID_BYTES]; /* 32 */
- unsigned char cert[SSL_MAX_CACHED_CERT_LEN]; /* 4060 */
-}; /* total 4096 */
-
-
-static void IOError(int rv, char *type);
-static PRUint32 Offset(PRUint32 addr, unsigned char *s, unsigned nl);
-static void Invalidate(SIDCacheEntry *sce);
-
-/************************************************************************/
-
-static const char envVarName[] = { SSL_ENV_VAR_NAME };
-
-#ifdef _WIN32
-
-struct winInheritanceStr {
- PRUint32 numSIDCacheEntries;
- PRUint32 sidCacheFileSize;
- PRUint32 sidCacheWrapOffset;
- PRUint32 numCertCacheEntries;
- PRUint32 certCacheFileSize;
-
- DWORD parentProcessID;
- HANDLE parentProcessHandle;
- HANDLE SIDCacheFDMAP;
- HANDLE certCacheFDMAP;
- HANDLE svrCacheSem;
-};
-
-typedef struct winInheritanceStr winInheritance;
-
-static HANDLE svrCacheSem = INVALID_HANDLE_VALUE;
-
-static char * SIDCacheData = NULL;
-static HANDLE SIDCacheFD = INVALID_HANDLE_VALUE;
-static HANDLE SIDCacheFDMAP = INVALID_HANDLE_VALUE;
-
-static char * certCacheData = NULL;
-static HANDLE certCacheFD = INVALID_HANDLE_VALUE;
-static HANDLE certCacheFDMAP = INVALID_HANDLE_VALUE;
-
-static PRUint32 myPid;
-
-/* The presence of the TRUE element in this struct makes the semaphore
- * inheritable. The NULL means use process's default security descriptor.
- */
-static SECURITY_ATTRIBUTES semaphoreAttributes =
- { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
-
-static SECURITY_ATTRIBUTES sidCacheFDMapAttributes =
- { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
-
-static SECURITY_ATTRIBUTES certCacheFDMapAttributes =
- { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
-
-#define DEFAULT_CACHE_DIRECTORY "\\temp"
-
-static SECStatus
-createServerCacheSemaphore(void)
-{
- PR_ASSERT(svrCacheSem == INVALID_HANDLE_VALUE);
-
- /* inheritable, starts signalled, 1 signal max, no file name. */
- svrCacheSem = CreateSemaphore(&semaphoreAttributes, 1, 1, NULL);
- if (svrCacheSem == NULL) {
- svrCacheSem = INVALID_HANDLE_VALUE;
- /* We could get the error code, but what could be do with it ? */
- nss_MD_win32_map_default_error(GetLastError());
- return SECFailure;
- }
- return SECSuccess;
-}
-
-static SECStatus
-_getServerCacheSemaphore(void)
-{
- DWORD event;
- DWORD lastError;
- SECStatus rv;
-
- PR_ASSERT(svrCacheSem != INVALID_HANDLE_VALUE);
- if (svrCacheSem == INVALID_HANDLE_VALUE &&
- SECSuccess != createServerCacheSemaphore()) {
- return SECFailure; /* what else ? */
- }
- event = WaitForSingleObject(svrCacheSem, INFINITE);
- switch (event) {
- case WAIT_OBJECT_0:
- case WAIT_ABANDONED:
- rv = SECSuccess;
- break;
-
- case WAIT_TIMEOUT:
- case WAIT_IO_COMPLETION:
- default: /* should never happen. nothing we can do. */
- PR_ASSERT(("WaitForSingleObject returned invalid value.", 0));
- /* fall thru */
-
- case WAIT_FAILED: /* failure returns this */
- rv = SECFailure;
- lastError = GetLastError(); /* for debugging */
- nss_MD_win32_map_default_error(lastError);
- break;
- }
- return rv;
-}
-
-static void
-_doGetServerCacheSemaphore(void * arg)
-{
- SECStatus * rv = (SECStatus *)arg;
- *rv = _getServerCacheSemaphore();
-}
-
-static SECStatus
-getServerCacheSemaphore(void)
-{
- PRThread * selectThread;
- PRThread * me = PR_GetCurrentThread();
- PRThreadScope scope = PR_GetThreadScope(me);
- SECStatus rv = SECFailure;
-
- if (scope == PR_GLOBAL_THREAD) {
- rv = _getServerCacheSemaphore();
- } else {
- selectThread = PR_CreateThread(PR_USER_THREAD,
- _doGetServerCacheSemaphore, &rv,
- PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
- PR_JOINABLE_THREAD, 0);
- if (selectThread != NULL) {
- /* rv will be set by _doGetServerCacheSemaphore() */
- PR_JoinThread(selectThread);
- }
- }
- return rv;
-}
-
-static SECStatus
-releaseServerCacheSemaphore(void)
-{
- BOOL success = FALSE;
-
- PR_ASSERT(svrCacheSem != INVALID_HANDLE_VALUE);
- if (svrCacheSem != INVALID_HANDLE_VALUE) {
- /* Add 1, don't want previous value. */
- success = ReleaseSemaphore(svrCacheSem, 1, NULL);
- }
- if (!success) {
- nss_MD_win32_map_default_error(GetLastError());
- return SECFailure;
- }
- return SECSuccess;
-}
-
-static void
-destroyServerCacheSemaphore(void)
-{
- PR_ASSERT(svrCacheSem != INVALID_HANDLE_VALUE);
- if (svrCacheSem != INVALID_HANDLE_VALUE) {
- CloseHandle(svrCacheSem);
- /* ignore error */
- svrCacheSem = INVALID_HANDLE_VALUE;
- }
-}
-
-#define GET_SERVER_CACHE_READ_LOCK(fd, offset, size) \
- if (isMultiProcess) getServerCacheSemaphore();
-
-#define GET_SERVER_CACHE_WRITE_LOCK(fd, offset, size) \
- if (isMultiProcess) getServerCacheSemaphore();
-
-#define RELEASE_SERVER_CACHE_LOCK(fd, offset, size) \
- if (isMultiProcess) releaseServerCacheSemaphore();
-
-#endif /* _win32 */
-
-/************************************************************************/
-
-#ifdef XP_UNIX
-static int SIDCacheFD = -1;
-static int certCacheFD = -1;
-
-static pid_t myPid;
-
-struct unixInheritanceStr {
- PRUint32 numSIDCacheEntries;
- PRUint32 sidCacheFileSize;
- PRUint32 sidCacheWrapOffset;
- PRUint32 numCertCacheEntries;
- PRUint32 certCacheFileSize;
-
- PRInt32 SIDCacheFD;
- PRInt32 certCacheFD;
-};
-
-typedef struct unixInheritanceStr unixInheritance;
-
-
-#define DEFAULT_CACHE_DIRECTORY "/tmp"
-
-#ifdef TRACE
-static void
-fcntlFailed(struct flock *lock)
-{
- fprintf(stderr,
- "fcntl failed, errno = %d, PR_GetError = %d, lock.l_type = %d\n",
- errno, PR_GetError(), lock->l_type);
- fflush(stderr);
-}
-#define FCNTL_FAILED(lock) fcntlFailed(lock)
-#else
-#define FCNTL_FAILED(lock)
-#endif
-
-/* NOTES: Because there are no atomic seek-and-read and seek-and-write
-** functions that are supported on all our UNIX platforms, we need
-** to prevent all simultaeous seek-and-read operations. For that reason,
-** we use mutually exclusive (write) locks for read and write operations,
-** and use them all at the same offset (zero).
-*/
-static SECStatus
-_getServerCacheLock(int fd, short type, PRUint32 offset, PRUint32 size)
-{
- int result;
- struct flock lock;
-
- memset(&lock, 0, sizeof lock);
- lock.l_type = /* type */ F_WRLCK;
- lock.l_whence = SEEK_SET; /* absolute file offsets. */
- lock.l_start = 0;
- lock.l_len = 128;
-
-#ifdef TRACE
- if (ssl_trace) {
- fprintf(stderr, "%d: %s lock, offset %8x, size %4d\n", myPid,
- (type == F_RDLCK) ? "read " : "write", offset, size);
- fflush(stderr);
- }
-#endif
- result = fcntl(fd, F_SETLKW, &lock);
- if (result == -1) {
- nss_MD_unix_map_default_error(errno);
- FCNTL_FAILED(&lock);
- return SECFailure;
- }
-#ifdef TRACE
- if (ssl_trace) {
- fprintf(stderr, "%d: got lock, offset %8x, size %4d\n",
- myPid, offset, size);
- fflush(stderr);
- }
-#endif
- return SECSuccess;
-}
-
-typedef struct sslLockArgsStr {
- PRUint32 offset;
- PRUint32 size;
- PRErrorCode err;
- SECStatus rv;
- int fd;
- short type;
-} sslLockArgs;
-
-static void
-_doGetServerCacheLock(void * arg)
-{
- sslLockArgs * args = (sslLockArgs *)arg;
- args->rv = _getServerCacheLock(args->fd, args->type, args->offset,
- args->size );
- if (args->rv != SECSuccess) {
- args->err = PR_GetError();
- }
-}
-
-static SECStatus
-getServerCacheLock(int fd, short type, PRUint32 offset, PRUint32 size)
-{
- PRThread * selectThread;
- PRThread * me = PR_GetCurrentThread();
- PRThreadScope scope = PR_GetThreadScope(me);
- SECStatus rv = SECFailure;
-
- if (scope == PR_GLOBAL_THREAD) {
- rv = _getServerCacheLock(fd, type, offset, size);
- } else {
- /* Ib some platforms, one thread cannot read local/automatic
- ** variables from another thread's stack. So, get this space
- ** from the heap, not the stack.
- */
- sslLockArgs * args = PORT_New(sslLockArgs);
-
- if (!args)
- return rv;
-
- args->offset = offset;
- args->size = size;
- args->rv = SECFailure;
- args->fd = fd;
- args->type = type;
- selectThread = PR_CreateThread(PR_USER_THREAD,
- _doGetServerCacheLock, args,
- PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
- PR_JOINABLE_THREAD, 0);
- if (selectThread != NULL) {
- /* rv will be set by _doGetServerCacheLock() */
- PR_JoinThread(selectThread);
- rv = args->rv;
- if (rv != SECSuccess) {
- PORT_SetError(args->err);
- }
- }
- PORT_Free(args);
- }
- return rv;
-}
-
-static SECStatus
-releaseServerCacheLock(int fd, PRUint32 offset, PRUint32 size)
-{
- int result;
- struct flock lock;
-
- memset(&lock, 0, sizeof lock);
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET; /* absolute file offsets. */
- lock.l_start = 0;
- lock.l_len = 128;
-
-#ifdef TRACE
- if (ssl_trace) {
- fprintf(stderr, "%d: unlock, offset %8x, size %4d\n",
- myPid, offset, size);
- fflush(stderr);
- }
-#endif
- result = fcntl(fd, F_SETLK, &lock);
- if (result == -1) {
- nss_MD_unix_map_default_error(errno);
- FCNTL_FAILED(&lock);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-
-/* these defines take the arguments needed to do record locking,
- * however the present implementation does only file locking.
- */
-
-#define GET_SERVER_CACHE_READ_LOCK( fd, offset, size) \
- if (isMultiProcess) getServerCacheLock(fd, F_RDLCK, offset, size);
-
-#define GET_SERVER_CACHE_WRITE_LOCK(fd, offset, size) \
- if (isMultiProcess) getServerCacheLock(fd, F_WRLCK, offset, size);
-
-#define RELEASE_SERVER_CACHE_LOCK( fd, offset, size) \
- if (isMultiProcess) releaseServerCacheLock(fd, offset, size);
-
-/*
-** Zero a file out to nb bytes
-*/
-static SECStatus
-ZeroFile(int fd, int nb)
-{
- off_t off;
- int amount, rv;
- char buf[16384];
-
- PORT_Memset(buf, 0, sizeof(buf));
- off = lseek(fd, 0, SEEK_SET);
- if (off != 0) {
- if (off == -1)
- nss_MD_unix_map_lseek_error(errno);
- else
- PORT_SetError(PR_FILE_SEEK_ERROR);
- return SECFailure;
- }
-
- while (nb > 0) {
- amount = (nb > sizeof buf) ? sizeof buf : nb;
- rv = write(fd, buf, amount);
- if (rv <= 0) {
- if (!rv)
- PORT_SetError(PR_IO_ERROR);
- else
- nss_MD_unix_map_write_error(errno);
- IOError(rv, "zero-write");
- return SECFailure;
- }
- nb -= rv;
- }
- return SECSuccess;
-}
-
-#endif /* XP_UNIX */
-
-
-/************************************************************************/
-
-/*
-** Reconstitute a cert from the cache
-** This is only called from ConvertToSID().
-** Caller must hold the cache lock before calling this.
-*/
-static CERTCertificate *
-GetCertFromCache(SIDCacheEntry *sce, CERTCertDBHandle *dbHandle)
-{
- CERTCertificate *cert;
- PRUint32 offset;
- int rv;
-#ifdef XP_UNIX
- off_t off;
-#endif
- SECItem derCert;
- CertCacheEntry cce;
-
- offset = (PRUint32)sce->u.ssl3.certIndex * sizeof(CertCacheEntry);
- GET_SERVER_CACHE_READ_LOCK(certCacheFD, offset, sizeof(CertCacheEntry));
-#ifdef XP_UNIX
- off = lseek(certCacheFD, offset, SEEK_SET);
- rv = -1;
- if (off != offset) {
- if (off == -1)
- nss_MD_unix_map_lseek_error(errno);
- else
- PORT_SetError(PR_FILE_SEEK_ERROR);
- } else {
- rv = read(certCacheFD, &cce, sizeof(CertCacheEntry));
- if (rv != sizeof(CertCacheEntry)) {
- if (rv == -1)
- nss_MD_unix_map_read_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- }
- }
-#else /* XP_WIN32 */
- /* Use memory mapped I/O and just memcpy() the data */
- CopyMemory(&cce, &certCacheData[offset], sizeof(CertCacheEntry));
- rv = sizeof cce;
-#endif /* XP_WIN32 */
- RELEASE_SERVER_CACHE_LOCK(certCacheFD, offset, sizeof(CertCacheEntry))
-
- if (rv != sizeof(CertCacheEntry)) {
- IOError(rv, "read"); /* error set above */
- return NULL;
- }
-
- /* See if the session ID matches with that in the sce cache. */
- if((cce.sessionIDLength != sce->u.ssl3.sessionIDLength) ||
- PORT_Memcmp(cce.sessionID, sce->u.ssl3.sessionID, cce.sessionIDLength)) {
- /* this is a cache miss, not an error */
- PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND);
- return NULL;
- }
-
- derCert.len = cce.certLength;
- derCert.data = cce.cert;
-
- cert = CERT_NewTempCertificate(dbHandle, &derCert, NULL,
- PR_FALSE, PR_TRUE);
-
- return cert;
-}
-
-/* Put a certificate in the cache. We assume that the certIndex in
-** sid is valid.
-*/
-static void
-CacheCert(CERTCertificate *cert, SIDCacheEntry *sce)
-{
- PRUint32 offset;
- CertCacheEntry cce;
-#ifdef XP_UNIX
- off_t off;
- int rv;
-#endif
-
- offset = (PRUint32)sce->u.ssl3.certIndex * sizeof(CertCacheEntry);
- if (cert->derCert.len > SSL_MAX_CACHED_CERT_LEN)
- return;
-
- cce.sessionIDLength = sce->u.ssl3.sessionIDLength;
- PORT_Memcpy(cce.sessionID, sce->u.ssl3.sessionID, cce.sessionIDLength);
-
- cce.certLength = cert->derCert.len;
- PORT_Memcpy(cce.cert, cert->derCert.data, cce.certLength);
-
- GET_SERVER_CACHE_WRITE_LOCK(certCacheFD, offset, sizeof cce);
-#ifdef XP_UNIX
- off = lseek(certCacheFD, offset, SEEK_SET);
- if (off != offset) {
- if (off == -1)
- nss_MD_unix_map_lseek_error(errno);
- else
- PORT_SetError(PR_FILE_SEEK_ERROR);
- } else {
- rv = write(certCacheFD, &cce, sizeof cce);
- if (rv != sizeof(CertCacheEntry)) {
- if (rv == -1)
- nss_MD_unix_map_write_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- IOError(rv, "cert-write");
- Invalidate(sce);
- }
- }
-#else /* WIN32 */
- /* Use memory mapped I/O and just memcpy() the data */
- CopyMemory(&certCacheData[offset], &cce, sizeof cce);
-#endif /* XP_UNIX */
-
- RELEASE_SERVER_CACHE_LOCK(certCacheFD, offset, sizeof cce);
- return;
-}
-
-/*
-** Convert memory based SID to file based one
-*/
-static void
-ConvertFromSID(SIDCacheEntry *to, sslSessionID *from)
-{
- to->u.ssl2.valid = 1;
- to->u.ssl2.version = from->version;
- to->addr = from->addr;
- to->time = from->time;
-
- if (from->version < SSL_LIBRARY_VERSION_3_0) {
- if ((from->u.ssl2.masterKey.len > SSL_MAX_MASTER_KEY_BYTES) ||
- (from->u.ssl2.cipherArg.len > SSL_MAX_CYPHER_ARG_BYTES)) {
- SSL_DBG(("%d: SSL: masterKeyLen=%d cipherArgLen=%d",
- myPid, from->u.ssl2.masterKey.len,
- from->u.ssl2.cipherArg.len));
- to->u.ssl2.valid = 0;
- return;
- }
-
- to->u.ssl2.cipherType = from->u.ssl2.cipherType;
- to->u.ssl2.masterKeyLen = from->u.ssl2.masterKey.len;
- to->u.ssl2.cipherArgLen = from->u.ssl2.cipherArg.len;
- to->u.ssl2.keyBits = from->u.ssl2.keyBits;
- to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits;
- PORT_Memcpy(to->u.ssl2.sessionID, from->u.ssl2.sessionID,
- sizeof(to->u.ssl2.sessionID));
- PORT_Memcpy(to->u.ssl2.masterKey, from->u.ssl2.masterKey.data,
- from->u.ssl2.masterKey.len);
- PORT_Memcpy(to->u.ssl2.cipherArg, from->u.ssl2.cipherArg.data,
- from->u.ssl2.cipherArg.len);
-#ifdef DEBUG
- PORT_Memset(to->u.ssl2.masterKey+from->u.ssl2.masterKey.len, 0,
- sizeof(to->u.ssl2.masterKey) - from->u.ssl2.masterKey.len);
- PORT_Memset(to->u.ssl2.cipherArg+from->u.ssl2.cipherArg.len, 0,
- sizeof(to->u.ssl2.cipherArg) - from->u.ssl2.cipherArg.len);
-#endif
- SSL_TRC(8, ("%d: SSL: ConvertSID: masterKeyLen=%d cipherArgLen=%d "
- "time=%d addr=0x%x cipherType=%d", myPid,
- to->u.ssl2.masterKeyLen, to->u.ssl2.cipherArgLen,
- to->time, to->addr, to->u.ssl2.cipherType));
- } else {
- /* This is an SSL v3 session */
-
- to->u.ssl3.sessionIDLength = from->u.ssl3.sessionIDLength;
- to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
- to->u.ssl3.compression = (uint16)from->u.ssl3.compression;
- to->u.ssl3.resumable = from->u.ssl3.resumable;
- to->u.ssl3.hasFortezza = from->u.ssl3.hasFortezza;
- to->u.ssl3.keys = from->u.ssl3.keys;
- to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
- to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
-
- PORT_Memcpy(to->u.ssl3.sessionID,
- from->u.ssl3.sessionID,
- from->u.ssl3.sessionIDLength);
-
- SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%x cipherSuite=%d",
- myPid, to->time, to->addr, to->u.ssl3.cipherSuite));
- }
-}
-
-/*
-** Convert file based cache-entry to memory based one
-** This is only called from ServerSessionIDLookup().
-** Caller must hold cache lock when calling this.
-*/
-static sslSessionID *
-ConvertToSID(SIDCacheEntry *from, CERTCertDBHandle * dbHandle)
-{
- sslSessionID *to;
- uint16 version = from->u.ssl2.version;
-
- to = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
- if (!to) {
- return 0;
- }
-
- if (version < SSL_LIBRARY_VERSION_3_0) {
- /* This is an SSL v2 session */
- to->u.ssl2.masterKey.data =
- (unsigned char*) PORT_Alloc(from->u.ssl2.masterKeyLen);
- if (!to->u.ssl2.masterKey.data) {
- goto loser;
- }
- if (from->u.ssl2.cipherArgLen) {
- to->u.ssl2.cipherArg.data = (unsigned char*)
- PORT_Alloc(from->u.ssl2.cipherArgLen);
- if (!to->u.ssl2.cipherArg.data) {
- goto loser;
- }
- PORT_Memcpy(to->u.ssl2.cipherArg.data, from->u.ssl2.cipherArg,
- from->u.ssl2.cipherArgLen);
- }
-
- to->u.ssl2.cipherType = from->u.ssl2.cipherType;
- to->u.ssl2.masterKey.len = from->u.ssl2.masterKeyLen;
- to->u.ssl2.cipherArg.len = from->u.ssl2.cipherArgLen;
- to->u.ssl2.keyBits = from->u.ssl2.keyBits;
- to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits;
- PORT_Memcpy(to->u.ssl2.sessionID, from->u.ssl2.sessionID,
- sizeof from->u.ssl2.sessionID);
- PORT_Memcpy(to->u.ssl2.masterKey.data, from->u.ssl2.masterKey,
- from->u.ssl2.masterKeyLen);
-
- SSL_TRC(8, ("%d: SSL: ConvertToSID: masterKeyLen=%d cipherArgLen=%d "
- "time=%d addr=0x%x cipherType=%d",
- myPid, to->u.ssl2.masterKey.len,
- to->u.ssl2.cipherArg.len, to->time, to->addr,
- to->u.ssl2.cipherType));
- } else {
- /* This is an SSL v3 session */
-
- to->u.ssl3.sessionIDLength = from->u.ssl3.sessionIDLength;
- to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
- to->u.ssl3.compression = (SSL3CompressionMethod)from->u.ssl3.compression;
- to->u.ssl3.resumable = from->u.ssl3.resumable;
- to->u.ssl3.hasFortezza = from->u.ssl3.hasFortezza;
- to->u.ssl3.keys = from->u.ssl3.keys;
- to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
- to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
-
- PORT_Memcpy(to->u.ssl3.sessionID,
- from->u.ssl3.sessionID,
- from->u.ssl3.sessionIDLength);
-
- /* the portions of the SID that are only restored on the client
- * are set to invalid values on the server.
- */
- to->u.ssl3.clientWriteKey = NULL;
- to->u.ssl3.serverWriteKey = NULL;
- to->u.ssl3.tek = NULL;
- to->urlSvrName = NULL;
-
- to->u.ssl3.masterModuleID = (SECMODModuleID)-1; /* invalid value */
- to->u.ssl3.masterSlotID = (CK_SLOT_ID)-1; /* invalid value */
- to->u.ssl3.masterWrapIndex = 0;
- to->u.ssl3.masterWrapSeries = 0;
- to->u.ssl3.masterValid = PR_FALSE;
-
- to->u.ssl3.clAuthModuleID = (SECMODModuleID)-1; /* invalid value */
- to->u.ssl3.clAuthSlotID = (CK_SLOT_ID)-1; /* invalid value */
- to->u.ssl3.clAuthSeries = 0;
- to->u.ssl3.clAuthValid = PR_FALSE;
-
- to->u.ssl3.clientWriteSaveLen = 0;
-
- if (from->u.ssl3.certIndex != -1) {
- to->peerCert = GetCertFromCache(from, dbHandle);
- if (to->peerCert == NULL)
- goto loser;
- }
- }
-
- to->version = from->u.ssl2.version;
- to->time = from->time;
- to->cached = in_server_cache;
- to->addr = from->addr;
- to->references = 1;
-
- return to;
-
- loser:
- Invalidate(from);
- if (to) {
- if (version < SSL_LIBRARY_VERSION_3_0) {
- if (to->u.ssl2.masterKey.data)
- PORT_Free(to->u.ssl2.masterKey.data);
- if (to->u.ssl2.cipherArg.data)
- PORT_Free(to->u.ssl2.cipherArg.data);
- }
- PORT_Free(to);
- }
- return NULL;
-}
-
-
-/* Invalidate a SID cache entry.
- * Called from CacheCert, ConvertToSid, and ServerSessionIDUncache.
- */
-static void
-Invalidate(SIDCacheEntry *sce)
-{
- PRUint32 offset;
-#ifdef XP_UNIX
- off_t off;
- int rv;
-#endif
-
- if (sce == NULL) return;
-
- if (sce->u.ssl2.version < SSL_LIBRARY_VERSION_3_0) {
- offset = Offset(sce->addr, sce->u.ssl2.sessionID,
- sizeof sce->u.ssl2.sessionID);
- } else {
- offset = Offset(sce->addr, sce->u.ssl3.sessionID,
- sce->u.ssl3.sessionIDLength);
- }
-
- sce->u.ssl2.valid = 0;
- SSL_TRC(7, ("%d: SSL: uncaching session-id at offset %ld",
- myPid, offset));
-
- GET_SERVER_CACHE_WRITE_LOCK(SIDCacheFD, offset, sizeof *sce);
-
-#ifdef XP_UNIX
- off = lseek(SIDCacheFD, offset, SEEK_SET);
- if (off != offset) {
- if (off == -1)
- nss_MD_unix_map_lseek_error(errno);
- else
- PORT_SetError(PR_FILE_SEEK_ERROR);
- } else {
- rv = write(SIDCacheFD, sce, sizeof *sce);
- if (rv != sizeof *sce) {
- if (rv == -1)
- nss_MD_unix_map_write_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- IOError(rv, "invalidate-write");
- }
- }
-#else /* WIN32 */
- /* Use memory mapped I/O and just memcpy() the data */
- CopyMemory(&SIDCacheData[offset], sce, sizeof *sce);
-#endif /* XP_UNIX */
-
- RELEASE_SERVER_CACHE_LOCK(SIDCacheFD, offset, sizeof *sce);
-}
-
-
-static void
-IOError(int rv, char *type)
-{
-#ifdef XP_UNIX
- syslog(LOG_ALERT,
- "SSL: %s error with session-id cache, pid=%d, rv=%d, error='%m'",
- type, myPid, rv);
-#else /* XP_WIN32 */
-#ifdef MC_HTTPD
- ereport(LOG_FAILURE, "%s error with session-id cache rv=%d\n",type, rv);
-#endif /* MC_HTTPD */
-#endif /* XP_UNIX */
-}
-
-static void
-lock_cache(void)
-{
- PR_Lock(cacheLock);
-}
-
-static void
-unlock_cache(void)
-{
- PR_Unlock(cacheLock);
-}
-
-/*
-** Perform some mumbo jumbo on the ip-address and the session-id value to
-** compute a hash value.
-*/
-static PRUint32
-Offset(PRUint32 addr, unsigned char *s, unsigned nl)
-{
- PRUint32 rv;
-
- rv = addr ^ (((PRUint32)s[0] << 24) | ((PRUint32)s[1] << 16)
- | (s[2] << 8) | s[nl-1]);
- return (rv % numSIDCacheEntries) * sizeof(SIDCacheEntry);
-}
-
-
-
-/*
-** Look something up in the cache. This will invalidate old entries
-** in the process. Caller has locked the cache!
-** Returns PR_TRUE if found a valid match. PR_FALSE otherwise.
-*/
-static PRBool
-FindSID(PRUint32 addr, unsigned char *sessionID,
- unsigned sessionIDLength, SIDCacheEntry *sce)
-{
- PRUint32 offset;
- PRUint32 now;
- int rv;
-#ifdef XP_UNIX
- off_t off;
-#endif
-
- /* Read in cache entry after hashing ip address and session-id value */
- offset = Offset(addr, sessionID, sessionIDLength);
- now = ssl_Time();
- GET_SERVER_CACHE_READ_LOCK(SIDCacheFD, offset, sizeof *sce);
-#ifdef XP_UNIX
- off = lseek(SIDCacheFD, offset, SEEK_SET);
- rv = -1;
- if (off != offset) {
- if (off == -1)
- nss_MD_unix_map_lseek_error(errno);
- else
- PORT_SetError(PR_FILE_SEEK_ERROR);
- } else {
- rv = read(SIDCacheFD, sce, sizeof *sce);
- if (rv != sizeof *sce) {
- if (rv == -1)
- nss_MD_unix_map_read_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- }
- }
-#else /* XP_WIN32 */
- /* Use memory mapped I/O and just memcpy() the data */
- CopyMemory(sce, &SIDCacheData[offset], sizeof *sce);
- rv = sizeof *sce;
-#endif /* XP_WIN32 */
- RELEASE_SERVER_CACHE_LOCK(SIDCacheFD, offset, sizeof *sce);
-
- if (rv != sizeof *sce) {
- IOError(rv, "server sid cache read");
- return PR_FALSE;
- }
-
- if (!sce->u.ssl2.valid) {
- /* Entry is not valid */
- PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND);
- return PR_FALSE;
- }
-
- if (((sce->u.ssl2.version < SSL_LIBRARY_VERSION_3_0) &&
- (now > sce->time + ssl_sid_timeout)) ||
- ((sce->u.ssl2.version >= SSL_LIBRARY_VERSION_3_0) &&
- (now > sce->time + ssl3_sid_timeout))) {
- /* SessionID has timed out. Invalidate the entry. */
- SSL_TRC(7, ("%d: timed out sid entry addr=%08x now=%x time+=%x",
- myPid, sce->addr, now, sce->time + ssl_sid_timeout));
- sce->u.ssl2.valid = 0;
-
- GET_SERVER_CACHE_WRITE_LOCK(SIDCacheFD, offset, sizeof *sce);
-#ifdef XP_UNIX
- off = lseek(SIDCacheFD, offset, SEEK_SET);
- rv = -1;
- if (off != offset) {
- if (off == -1)
- nss_MD_unix_map_lseek_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- } else {
- rv = write(SIDCacheFD, sce, sizeof *sce);
- if (rv != sizeof *sce) {
- if (rv == -1)
- nss_MD_unix_map_write_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- IOError(rv, "timeout-write");
- }
- }
-#else /* WIN32 */
- /* Use memory mapped I/O and just memcpy() the data */
- CopyMemory(&SIDCacheData[offset], sce, sizeof *sce);
- rv = sizeof *sce;
-#endif /* XP_UNIX */
- RELEASE_SERVER_CACHE_LOCK(SIDCacheFD, offset, sizeof *sce);
- if (rv == sizeof *sce)
- PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND);
- return PR_FALSE;
- }
-
- /*
- ** Finally, examine specific session-id/addr data to see if the cache
- ** entry matches our addr+session-id value
- */
- if ((sce->addr == addr) &&
- (PORT_Memcmp(sce->u.ssl2.sessionID, sessionID, sessionIDLength) == 0)) {
- /* Found it */
- return PR_TRUE;
- }
- PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND);
- return PR_FALSE;
-}
-
-/************************************************************************/
-
-/* This is the primary function for finding entries in the server's sid cache.
- * Although it is static, this function is called via the global function
- * pointer ssl_sid_lookup.
- */
-static sslSessionID *
-ServerSessionIDLookup( PRUint32 addr,
- unsigned char *sessionID,
- unsigned int sessionIDLength,
- CERTCertDBHandle * dbHandle)
-{
- SIDCacheEntry sce;
- sslSessionID *sid;
-
- sid = 0;
- lock_cache();
- if (FindSID(addr, sessionID, sessionIDLength, &sce)) {
- /* Found it. Convert file format to internal format */
- sid = ConvertToSID(&sce, dbHandle);
- }
- unlock_cache();
- return sid;
-}
-
-/*
-** Place an sid into the cache, if it isn't already there. Note that if
-** some other server process has replaced a session-id cache entry that has
-** the same cache index as this sid, then all is ok. Somebody has to lose
-** when this condition occurs, so it might as well be this sid.
-*/
-static void
-ServerSessionIDCache(sslSessionID *sid)
-{
- SIDCacheEntry sce;
- PRUint32 offset;
-#ifdef XP_UNIX
- off_t off;
- int rv;
-#endif
- uint16 version = sid->version;
-
- if ((version >= SSL_LIBRARY_VERSION_3_0) &&
- (sid->u.ssl3.sessionIDLength == 0)) {
- return;
- }
-
- if (sid->cached == never_cached || sid->cached == invalid_cache) {
- lock_cache();
-
- sid->time = ssl_Time();
- if (version < SSL_LIBRARY_VERSION_3_0) {
- SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x time=%x "
- "cipher=%d", myPid, sid->cached, sid->addr,
- sid->time, sid->u.ssl2.cipherType));
- PRINT_BUF(8, (0, "sessionID:", sid->u.ssl2.sessionID,
- sizeof(sid->u.ssl2.sessionID)));
- PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data,
- sid->u.ssl2.masterKey.len));
- PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data,
- sid->u.ssl2.cipherArg.len));
-
- /* Write out new cache entry */
- offset = Offset(sid->addr, sid->u.ssl2.sessionID,
- sizeof(sid->u.ssl2.sessionID));
- } else {
- SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x time=%x "
- "cipherSuite=%d", myPid, sid->cached, sid->addr,
- sid->time, sid->u.ssl3.cipherSuite));
- PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID,
- sid->u.ssl3.sessionIDLength));
-
- offset = Offset(sid->addr, sid->u.ssl3.sessionID,
- sid->u.ssl3.sessionIDLength);
-
- }
-
- ConvertFromSID(&sce, sid);
- if (version >= SSL_LIBRARY_VERSION_3_0) {
- if (sid->peerCert == NULL) {
- sce.u.ssl3.certIndex = -1;
- } else {
- sce.u.ssl3.certIndex = (int16)
- ((offset / sizeof(SIDCacheEntry)) % numCertCacheEntries);
- }
- }
-
- GET_SERVER_CACHE_WRITE_LOCK(SIDCacheFD, offset, sizeof sce);
-#ifdef XP_UNIX
- off = lseek(SIDCacheFD, offset, SEEK_SET);
- if (off != offset) {
- if (off == -1)
- nss_MD_unix_map_lseek_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- } else {
- rv = write(SIDCacheFD, &sce, sizeof sce);
- if (rv != sizeof(sce)) {
- if (rv == -1)
- nss_MD_unix_map_write_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- IOError(rv, "update-write");
- }
- }
-#else /* WIN32 */
- CopyMemory(&SIDCacheData[offset], &sce, sizeof sce);
-#endif /* XP_UNIX */
- RELEASE_SERVER_CACHE_LOCK(SIDCacheFD, offset, sizeof sce);
-
- if ((version >= SSL_LIBRARY_VERSION_3_0) &&
- (sid->peerCert != NULL)) {
- CacheCert(sid->peerCert, &sce);
- }
-
- sid->cached = in_server_cache;
- unlock_cache();
- }
-}
-
-static void
-ServerSessionIDUncache(sslSessionID *sid)
-{
- SIDCacheEntry sce;
- int rv;
-
- if (sid == NULL) return;
-
- lock_cache();
- if (sid->version < SSL_LIBRARY_VERSION_3_0) {
- SSL_TRC(8, ("%d: SSL: UncacheMT: valid=%d addr=0x%08x time=%x "
- "cipher=%d", myPid, sid->cached, sid->addr,
- sid->time, sid->u.ssl2.cipherType));
- PRINT_BUF(8, (0, "sessionID:", sid->u.ssl2.sessionID,
- sizeof(sid->u.ssl2.sessionID)));
- PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data,
- sid->u.ssl2.masterKey.len));
- PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data,
- sid->u.ssl2.cipherArg.len));
- rv = FindSID(sid->addr, sid->u.ssl2.sessionID,
- sizeof(sid->u.ssl2.sessionID), &sce);
- } else {
- SSL_TRC(8, ("%d: SSL3: UncacheMT: valid=%d addr=0x%08x time=%x "
- "cipherSuite=%d", myPid, sid->cached, sid->addr,
- sid->time, sid->u.ssl3.cipherSuite));
- PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID,
- sid->u.ssl3.sessionIDLength));
- rv = FindSID(sid->addr, sid->u.ssl3.sessionID,
- sid->u.ssl3.sessionIDLength, &sce);
- }
-
- if (rv) {
- Invalidate(&sce);
- }
- sid->cached = invalid_cache;
- unlock_cache();
-}
-
-static SECStatus
-InitSessionIDCache(int maxCacheEntries, PRUint32 timeout,
- PRUint32 ssl3_timeout, const char *directory)
-{
- char *cfn;
-#ifdef XP_UNIX
- int rv;
- if (SIDCacheFD >= 0) {
- /* Already done */
- return SECSuccess;
- }
-#else /* WIN32 */
- if(SIDCacheFDMAP != INVALID_HANDLE_VALUE) {
- /* Already done */
- return SECSuccess;
- }
-#endif /* XP_UNIX */
-
-
- if (maxCacheEntries) {
- numSIDCacheEntries = maxCacheEntries;
- }
- sidCacheWrapOffset = numSIDCacheEntries * sizeof(SIDCacheEntry);
- sidCacheFileSize = sidCacheWrapOffset +
- (kt_kea_size * SSL_NUM_WRAP_MECHS * sizeof(SSLWrappedSymWrappingKey));
-
- /* Create file names */
- cfn = (char*) PORT_Alloc(PORT_Strlen(directory) + 100);
- if (!cfn) {
- return SECFailure;
- }
-#ifdef XP_UNIX
- sprintf(cfn, "%s/.sslsidc.%d", directory, getpid());
-#else /* XP_WIN32 */
- sprintf(cfn, "%s\\ssl.sidc.%d.%d", directory,
- GetCurrentProcessId(), GetCurrentThreadId());
-#endif /* XP_WIN32 */
-
- /* Create session-id cache file */
-#ifdef XP_UNIX
- do {
- (void) unlink(cfn);
- SIDCacheFD = open(cfn, O_EXCL|O_CREAT|O_RDWR, 0600);
- } while (SIDCacheFD < 0 && errno == EEXIST);
- if (SIDCacheFD < 0) {
- nss_MD_unix_map_open_error(errno);
- IOError(SIDCacheFD, "create");
- goto loser;
- }
- rv = unlink(cfn);
- if (rv < 0) {
- nss_MD_unix_map_unlink_error(errno);
- IOError(rv, "unlink");
- goto loser;
- }
-#else /* WIN32 */
- SIDCacheFDMAP =
- CreateFileMapping(INVALID_HANDLE_VALUE, /* allocate in swap file */
- &sidCacheFDMapAttributes, /* inheritable. */
- PAGE_READWRITE,
- 0, /* size, high word. */
- sidCacheFileSize, /* size, low word. */
- NULL); /* no map name in FS */
- if(! SIDCacheFDMAP) {
- nss_MD_win32_map_default_error(GetLastError());
- goto loser;
- }
- SIDCacheData = (char *)MapViewOfFile(SIDCacheFDMAP,
- FILE_MAP_ALL_ACCESS, /* R/W */
- 0, 0, /* offset */
- sidCacheFileSize); /* size */
- if (! SIDCacheData) {
- nss_MD_win32_map_default_error(GetLastError());
- goto loser;
- }
-#endif /* XP_UNIX */
-
- if (!cacheLock)
- nss_InitLock(&cacheLock);
- if (!cacheLock) {
- SET_ERROR_CODE
- goto loser;
- }
-#ifdef _WIN32
- if (isMultiProcess && (SECSuccess != createServerCacheSemaphore())) {
- SET_ERROR_CODE
- goto loser;
- }
-#endif
-
- if (timeout) {
- if (timeout > 100) {
- timeout = 100;
- }
- if (timeout < 5) {
- timeout = 5;
- }
- ssl_sid_timeout = timeout;
- }
-
- if (ssl3_timeout) {
- if (ssl3_timeout > 86400L) {
- ssl3_timeout = 86400L;
- }
- if (ssl3_timeout < 5) {
- ssl3_timeout = 5;
- }
- ssl3_sid_timeout = ssl3_timeout;
- }
-
- GET_SERVER_CACHE_WRITE_LOCK(SIDCacheFD, 0, sidCacheFileSize);
-#ifdef XP_UNIX
- /* Initialize the files */
- if (ZeroFile(SIDCacheFD, sidCacheFileSize)) {
- /* Bummer */
- close(SIDCacheFD);
- SIDCacheFD = -1;
- goto loser;
- }
-#else /* XP_WIN32 */
- ZeroMemory(SIDCacheData, sidCacheFileSize);
-#endif /* XP_UNIX */
- RELEASE_SERVER_CACHE_LOCK(SIDCacheFD, 0, sidCacheFileSize);
- PORT_Free(cfn);
- return SECSuccess;
-
- loser:
-#ifdef _WIN32
- if (svrCacheSem)
- destroyServerCacheSemaphore();
-#endif
- if (cacheLock) {
- PR_DestroyLock(cacheLock);
- cacheLock = NULL;
- }
- PORT_Free(cfn);
- return SECFailure;
-}
-
-static SECStatus
-InitCertCache(const char *directory)
-{
- char *cfn;
-#ifdef XP_UNIX
- int rv;
- if (certCacheFD >= 0) {
- /* Already done */
- return SECSuccess;
- }
-#else /* WIN32 */
- if(certCacheFDMAP != INVALID_HANDLE_VALUE) {
- /* Already done */
- return SECSuccess;
- }
-#endif /* XP_UNIX */
-
- numCertCacheEntries = sidCacheFileSize / sizeof(CertCacheEntry);
- if (numCertCacheEntries < MIN_CERT_CACHE_ENTRIES)
- numCertCacheEntries = MIN_CERT_CACHE_ENTRIES;
- certCacheFileSize = numCertCacheEntries * sizeof(CertCacheEntry);
-
- /* Create file names */
- cfn = (char*) PORT_Alloc(PORT_Strlen(directory) + 100);
- if (!cfn) {
- return SECFailure;
- }
-#ifdef XP_UNIX
- sprintf(cfn, "%s/.sslcertc.%d", directory, getpid());
-#else /* XP_WIN32 */
- sprintf(cfn, "%s\\ssl.certc.%d.%d", directory,
- GetCurrentProcessId(), GetCurrentThreadId());
-#endif /* XP_WIN32 */
-
- /* Create certificate cache file */
-#ifdef XP_UNIX
- do {
- (void) unlink(cfn);
- certCacheFD = open(cfn, O_EXCL|O_CREAT|O_RDWR, 0600);
- } while (certCacheFD < 0 && errno == EEXIST);
- if (certCacheFD < 0) {
- nss_MD_unix_map_open_error(errno);
- IOError(certCacheFD, "create");
- goto loser;
- }
- rv = unlink(cfn);
- if (rv < 0) {
- nss_MD_unix_map_unlink_error(errno);
- IOError(rv, "unlink");
- goto loser;
- }
-#else /* WIN32 */
- certCacheFDMAP =
- CreateFileMapping(INVALID_HANDLE_VALUE, /* allocate in swap file */
- &certCacheFDMapAttributes, /* inheritable. */
- PAGE_READWRITE,
- 0, /* size, high word. */
- certCacheFileSize, /* size, low word. */
- NULL); /* no map name in FS */
- if (! certCacheFDMAP) {
- nss_MD_win32_map_default_error(GetLastError());
- goto loser;
- }
- certCacheData = (char *) MapViewOfFile(certCacheFDMAP,
- FILE_MAP_ALL_ACCESS, /* R/W */
- 0, 0, /* offset */
- certCacheFileSize); /* size */
- if (! certCacheData) {
- nss_MD_win32_map_default_error(GetLastError());
- goto loser;
- }
-#endif /* XP_UNIX */
-
-/* GET_SERVER_CACHE_WRITE_LOCK(certCacheFD, 0, certCacheFileSize); */
-#ifdef XP_UNIX
- /* Initialize the files */
- if (ZeroFile(certCacheFD, certCacheFileSize)) {
- /* Bummer */
- close(certCacheFD);
- certCacheFD = -1;
- goto loser;
- }
-#else /* XP_WIN32 */
- ZeroMemory(certCacheData, certCacheFileSize);
-#endif /* XP_UNIX */
-/* RELEASE_SERVER_CACHE_LOCK(certCacheFD, 0, certCacheFileSize); */
- PORT_Free(cfn);
- return SECSuccess;
-
- loser:
- PORT_Free(cfn);
- return SECFailure;
-}
-
-int
-SSL_ConfigServerSessionIDCache( int maxCacheEntries,
- PRUint32 timeout,
- PRUint32 ssl3_timeout,
- const char * directory)
-{
- SECStatus rv;
-
- PORT_Assert(sizeof(SIDCacheEntry) == 256);
- PORT_Assert(sizeof(CertCacheEntry) == 4096);
-
- myPid = SSL_GETPID();
- if (!directory) {
- directory = DEFAULT_CACHE_DIRECTORY;
- }
- rv = InitSessionIDCache(maxCacheEntries, timeout, ssl3_timeout, directory);
- if (rv) {
- SET_ERROR_CODE
- return SECFailure;
- }
- rv = InitCertCache(directory);
- if (rv) {
- SET_ERROR_CODE
- return SECFailure;
- }
-
- ssl_sid_lookup = ServerSessionIDLookup;
- ssl_sid_cache = ServerSessionIDCache;
- ssl_sid_uncache = ServerSessionIDUncache;
- return SECSuccess;
-}
-
-/* Use this function, instead of SSL_ConfigServerSessionIDCache,
- * if the cache will be shared by multiple processes.
- */
-int
-SSL_ConfigMPServerSIDCache( int maxCacheEntries,
- PRUint32 timeout,
- PRUint32 ssl3_timeout,
- const char * directory)
-{
- char * envValue;
- int result;
- SECStatus putEnvFailed;
-
- isMultiProcess = PR_TRUE;
- result = SSL_ConfigServerSessionIDCache(maxCacheEntries, timeout,
- ssl3_timeout, directory);
- if (result == SECSuccess) {
-#ifdef _WIN32
- winInheritance winherit;
-
- winherit.numSIDCacheEntries = numSIDCacheEntries;
- winherit.sidCacheFileSize = sidCacheFileSize;
- winherit.sidCacheWrapOffset = sidCacheWrapOffset;
- winherit.numCertCacheEntries = numCertCacheEntries;
- winherit.certCacheFileSize = certCacheFileSize;
- winherit.SIDCacheFDMAP = SIDCacheFDMAP;
- winherit.certCacheFDMAP = certCacheFDMAP;
- winherit.svrCacheSem = svrCacheSem;
- winherit.parentProcessID = GetCurrentProcessId();
- winherit.parentProcessHandle =
- OpenProcess(PROCESS_DUP_HANDLE, TRUE, winherit.parentProcessID);
- if (winherit.parentProcessHandle == NULL) {
- SET_ERROR_CODE
- return SECFailure;
- }
- envValue = BTOA_DataToAscii((unsigned char *)&winherit,
- sizeof winherit);
- if (!envValue) {
- SET_ERROR_CODE
- return SECFailure;
- }
-#else
- unixInheritance uinherit;
-
- uinherit.numSIDCacheEntries = numSIDCacheEntries;
- uinherit.sidCacheFileSize = sidCacheFileSize;
- uinherit.sidCacheWrapOffset = sidCacheWrapOffset;
- uinherit.numCertCacheEntries = numCertCacheEntries;
- uinherit.certCacheFileSize = certCacheFileSize;
- uinherit.SIDCacheFD = SIDCacheFD;
- uinherit.certCacheFD = certCacheFD;
-
- envValue = BTOA_DataToAscii((unsigned char *)&uinherit,
- sizeof uinherit);
- if (!envValue) {
- SET_ERROR_CODE
- return SECFailure;
- }
-#endif
- }
- putEnvFailed = (SECStatus)NSS_PutEnv(envVarName, envValue);
- PORT_Free(envValue);
- if (putEnvFailed) {
- SET_ERROR_CODE
- result = SECFailure;
- }
- return result;
-}
-
-SECStatus
-SSL_InheritMPServerSIDCache(const char * envString)
-{
- unsigned char * decoString = NULL;
- unsigned int decoLen;
-#ifdef _WIN32
- winInheritance inherit;
-#else
- unixInheritance inherit;
-#endif
-
- myPid = SSL_GETPID();
- if (isMultiProcess)
- return SECSuccess; /* already done. */
-
- ssl_sid_lookup = ServerSessionIDLookup;
- ssl_sid_cache = ServerSessionIDCache;
- ssl_sid_uncache = ServerSessionIDUncache;
-
- if (!envString) {
- envString = getenv(envVarName);
- if (!envString) {
- SET_ERROR_CODE
- return SECFailure;
- }
- }
-
- decoString = ATOB_AsciiToData(envString, &decoLen);
- if (!decoString) {
- SET_ERROR_CODE
- return SECFailure;
- }
- if (decoLen != sizeof inherit) {
- SET_ERROR_CODE
- goto loser;
- }
-
- PORT_Memcpy(&inherit, decoString, sizeof inherit);
- PORT_Free(decoString);
-
- numSIDCacheEntries = inherit.numSIDCacheEntries;
- sidCacheFileSize = inherit.sidCacheFileSize;
- sidCacheWrapOffset = inherit.sidCacheWrapOffset;
- numCertCacheEntries = inherit.numCertCacheEntries;
- certCacheFileSize = inherit.certCacheFileSize;
-
-#ifdef _WIN32
- SIDCacheFDMAP = inherit.SIDCacheFDMAP;
- certCacheFDMAP = inherit.certCacheFDMAP;
- svrCacheSem = inherit.svrCacheSem;
-
-#if 0
- /* call DuplicateHandle ?? */
- inherit.parentProcessID;
- inherit.parentProcessHandle;
-#endif
-
- if(!SIDCacheFDMAP) {
- SET_ERROR_CODE
- goto loser;
- }
- SIDCacheData = (char *)MapViewOfFile(SIDCacheFDMAP,
- FILE_MAP_ALL_ACCESS, /* R/W */
- 0, 0, /* offset */
- sidCacheFileSize); /* size */
- if(!SIDCacheData) {
- nss_MD_win32_map_default_error(GetLastError());
- goto loser;
- }
-
- if(!certCacheFDMAP) {
- SET_ERROR_CODE
- goto loser;
- }
- certCacheData = (char *) MapViewOfFile(certCacheFDMAP,
- FILE_MAP_ALL_ACCESS, /* R/W */
- 0, 0, /* offset */
- certCacheFileSize); /* size */
- if(!certCacheData) {
- nss_MD_win32_map_default_error(GetLastError());
- goto loser;
- }
-
-#else /* must be unix */
- SIDCacheFD = inherit.SIDCacheFD;
- certCacheFD = inherit.certCacheFD;
- if (SIDCacheFD < 0 || certCacheFD < 0) {
- SET_ERROR_CODE
- goto loser;
- }
-#endif
-
- if (!cacheLock) {
- nss_InitLock(&cacheLock);
- if (!cacheLock)
- goto loser;
- }
- isMultiProcess = PR_TRUE;
- return SECSuccess;
-
-loser:
- if (decoString)
- PORT_Free(decoString);
-#if _WIN32
- if (SIDCacheFDMAP) {
- CloseHandle(SIDCacheFDMAP);
- SIDCacheFDMAP = NULL;
- }
- if (certCacheFDMAP) {
- CloseHandle(certCacheFDMAP);
- certCacheFDMAP = NULL;
- }
-#else
- if (SIDCacheFD >= 0) {
- close(SIDCacheFD);
- SIDCacheFD = -1;
- }
- if (certCacheFD >= 0) {
- close(certCacheFD);
- certCacheFD = -1;
- }
-#endif
- return SECFailure;
-
-}
-
-/************************************************************************
- * Code dealing with shared wrapped symmetric wrapping keys below *
- ************************************************************************/
-
-
-static PRBool
-getWrappingKey(PRInt32 symWrapMechIndex,
- SSL3KEAType exchKeyType,
- SSLWrappedSymWrappingKey *wswk,
- PRBool grabSharedLock)
-{
- PRUint32 offset = sidCacheWrapOffset +
- ((exchKeyType * SSL_NUM_WRAP_MECHS + symWrapMechIndex) *
- sizeof(SSLWrappedSymWrappingKey));
- PRBool rv = PR_TRUE;
-#ifdef XP_UNIX
- off_t lrv;
- ssize_t rrv;
-#endif
-
- if (grabSharedLock) {
- GET_SERVER_CACHE_READ_LOCK(SIDCacheFD, offset, sizeof *wswk);
- }
-
-#ifdef XP_UNIX
- lrv = lseek(SIDCacheFD, offset, SEEK_SET);
- if (lrv != offset) {
- if (lrv == -1)
- nss_MD_unix_map_lseek_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- IOError(rv, "wrapping-read");
- rv = PR_FALSE;
- } else {
- rrv = read(SIDCacheFD, wswk, sizeof *wswk);
- if (rrv != sizeof *wswk) {
- if (rrv == -1)
- nss_MD_unix_map_read_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- IOError(rv, "wrapping-read");
- rv = PR_FALSE;
- }
- }
-#else /* XP_WIN32 */
- /* Use memory mapped I/O and just memcpy() the data */
- CopyMemory(wswk, &SIDCacheData[offset], sizeof *wswk);
-#endif /* XP_WIN32 */
- if (grabSharedLock) {
- RELEASE_SERVER_CACHE_LOCK(SIDCacheFD, offset, sizeof *wswk);
- }
- if (rv) {
- if (wswk->exchKeyType != exchKeyType ||
- wswk->symWrapMechIndex != symWrapMechIndex ||
- wswk->wrappedSymKeyLen == 0) {
- memset(wswk, 0, sizeof *wswk);
- rv = PR_FALSE;
- }
- }
- return rv;
-}
-
-PRBool
-ssl_GetWrappingKey( PRInt32 symWrapMechIndex,
- SSL3KEAType exchKeyType,
- SSLWrappedSymWrappingKey *wswk)
-{
- PRBool rv;
-
- lock_cache();
-
- PORT_Assert( (unsigned)exchKeyType < kt_kea_size);
- PORT_Assert( (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
- if ((unsigned)exchKeyType < kt_kea_size &&
- (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS) {
- rv = getWrappingKey(symWrapMechIndex, exchKeyType, wswk, PR_TRUE);
- } else {
- rv = PR_FALSE;
- }
- unlock_cache();
- return rv;
-}
-
-/* The caller passes in the new value it wants
- * to set. This code tests the wrapped sym key entry in the file on disk.
- * If it is uninitialized, this function writes the caller's value into
- * the disk entry, and returns false.
- * Otherwise, it overwrites the caller's wswk with the value obtained from
- * the disk, and returns PR_TRUE.
- * This is all done while holding the locks/semaphores necessary to make
- * the operation atomic.
- */
-PRBool
-ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
-{
- PRBool rv;
- SSL3KEAType exchKeyType = wswk->exchKeyType;
- /* type of keys used to wrap SymWrapKey*/
- PRInt32 symWrapMechIndex = wswk->symWrapMechIndex;
- PRUint32 offset;
- SSLWrappedSymWrappingKey myWswk;
-
- PORT_Assert( (unsigned)exchKeyType < kt_kea_size);
- if ((unsigned)exchKeyType >= kt_kea_size)
- return 0;
-
- PORT_Assert( (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
- if ((unsigned)symWrapMechIndex >= SSL_NUM_WRAP_MECHS)
- return 0;
-
- offset = sidCacheWrapOffset +
- ((exchKeyType * SSL_NUM_WRAP_MECHS + symWrapMechIndex) *
- sizeof(SSLWrappedSymWrappingKey));
- PORT_Memset(&myWswk, 0, sizeof myWswk); /* eliminate UMRs. */
- lock_cache();
- GET_SERVER_CACHE_WRITE_LOCK(SIDCacheFD, offset, sizeof *wswk);
-
- rv = getWrappingKey(wswk->symWrapMechIndex, wswk->exchKeyType, &myWswk,
- PR_FALSE);
- if (rv) {
- /* we found it on disk, copy it out to the caller. */
- PORT_Memcpy(wswk, &myWswk, sizeof *wswk);
- } else {
- /* Wasn't on disk, and we're still holding the lock, so write it. */
-
-#ifdef XP_UNIX
- off_t lrv;
- ssize_t rrv;
-
- lrv = lseek(SIDCacheFD, offset, SEEK_SET);
- if (lrv != offset) {
- if (lrv == -1)
- nss_MD_unix_map_lseek_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- IOError(rv, "wrapping-read");
- rv = PR_FALSE;
- } else {
- rrv = write(SIDCacheFD, wswk, sizeof *wswk);
- if (rrv != sizeof *wswk) {
- if (rrv == -1)
- nss_MD_unix_map_read_error(errno);
- else
- PORT_SetError(PR_IO_ERROR);
- IOError(rv, "wrapping-read");
- rv = PR_FALSE;
- }
- }
-#else /* XP_WIN32 */
- /* Use memory mapped I/O and just memcpy() the data */
- CopyMemory(&SIDCacheData[offset], wswk, sizeof *wswk);
-#endif /* XP_WIN32 */
- }
- RELEASE_SERVER_CACHE_LOCK(SIDCacheFD, offset, sizeof *wswk);
- unlock_cache();
- return rv;
-}
-
-
-#endif /* NADA_VERISON */
-#else
-
-#include "seccomon.h"
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-
-PRBool
-ssl_GetWrappingKey( PRInt32 symWrapMechIndex,
- SSL3KEAType exchKeyType,
- SSLWrappedSymWrappingKey *wswk)
-{
- PRBool rv = PR_FALSE;
- PR_ASSERT(!"SSL servers are not supported on the Mac. (ssl_GetWrappingKey)");
- return rv;
-}
-
-/* This is a kind of test-and-set. The caller passes in the new value it wants
- * to set. This code tests the wrapped sym key entry in the file on disk.
- * If it is uninitialized, this function writes the caller's value into
- * the disk entry, and returns false.
- * Otherwise, it overwrites the caller's wswk with the value obtained from
- * the disk, and returns PR_TRUE.
- * This is all done while holding the locks/semaphores necessary to make
- * the operation atomic.
- */
-PRBool
-ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
-{
- PRBool rv = PR_FALSE;
- PR_ASSERT(!"SSL servers are not supported on the Mac. (ssl_SetWrappingKey)");
- return rv;
-}
-
-#endif /* XP_UNIX || XP_WIN32 */
diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
deleted file mode 100644
index 2921e3b6c..000000000
--- a/security/nss/lib/ssl/sslsock.c
+++ /dev/null
@@ -1,1816 +0,0 @@
-/*
- * vtables (and methods that call through them) for the 4 types of
- * SSLSockets supported. Only one type is still supported.
- * Various other functions.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-#include "seccomon.h"
-#include "cert.h"
-#include "keyhi.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "nspr.h"
-
-#define SET_ERROR_CODE /* reminder */
-
-struct cipherPolicyStr {
- int cipher;
- unsigned char export; /* policy value for export policy */
- unsigned char france; /* policy value for france policy */
-};
-
-typedef struct cipherPolicyStr cipherPolicy;
-
-/* this table reflects Netscape's browser policies. */
-static cipherPolicy ssl_ciphers[] = { /* Export France */
- { SSL_EN_RC4_128_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_EN_RC4_128_EXPORT40_WITH_MD5, SSL_ALLOWED, SSL_ALLOWED },
- { SSL_EN_RC2_128_CBC_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_ALLOWED, SSL_ALLOWED },
- { SSL_EN_DES_64_CBC_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_EN_DES_192_EDE3_CBC_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_RSA_WITH_RC4_128_MD5, SSL_RESTRICTED, SSL_NOT_ALLOWED },
- { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RESTRICTED, SSL_NOT_ALLOWED },
- { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_ALLOWED, SSL_ALLOWED },
- { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_ALLOWED, SSL_ALLOWED },
- { SSL_FORTEZZA_DMS_WITH_NULL_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_RSA_WITH_NULL_MD5, SSL_ALLOWED, SSL_ALLOWED },
- { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED },
- { 0, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }
-};
-
-static
-sslSocketOps ssl_default_ops = { /* No SSL, No Socks. */
- ssl_DefConnect,
- NULL,
- ssl_DefBind,
- ssl_DefListen,
- ssl_DefShutdown,
- ssl_DefClose,
- ssl_DefRecv,
- ssl_DefSend,
- ssl_DefRead,
- ssl_DefWrite,
- ssl_DefGetpeername,
- ssl_DefGetsockname
-};
-
-static
-sslSocketOps ssl_socks_ops = { /* No SSL, has socks. */
- ssl_SocksConnect,
- ssl_SocksAccept,
- ssl_SocksBind,
- ssl_SocksListen,
- ssl_DefShutdown,
- ssl_DefClose,
- ssl_SocksRecv,
- ssl_SocksSend,
- ssl_SocksRead,
- ssl_SocksWrite,
- ssl_DefGetpeername,
- ssl_SocksGetsockname
-};
-
-static
-sslSocketOps ssl_secure_ops = { /* SSL, no socks. */
- ssl_SecureConnect,
- NULL,
- ssl_DefBind,
- ssl_DefListen,
- ssl_SecureShutdown,
- ssl_SecureClose,
- ssl_SecureRecv,
- ssl_SecureSend,
- ssl_SecureRead,
- ssl_SecureWrite,
- ssl_DefGetpeername,
- ssl_DefGetsockname
-};
-
-static
-sslSocketOps ssl_secure_socks_ops = { /* Both SSL and Socks. */
- ssl_SecureSocksConnect,
- ssl_SecureSocksAccept,
- ssl_SocksBind,
- ssl_SocksListen,
- ssl_SecureShutdown,
- ssl_SecureClose,
- ssl_SecureRecv,
- ssl_SecureSend,
- ssl_SecureRead,
- ssl_SecureWrite,
- ssl_DefGetpeername,
- ssl_SocksGetsockname
-};
-
-/*
-** default settings for socket enables
-*/
-static sslOptions ssl_defaults = {
- PR_TRUE, /* useSecurity */
- PR_FALSE, /* useSocks */
- PR_FALSE, /* requestCertificate */
- 2, /* requireCertificate */
- PR_FALSE, /* handshakeAsClient */
- PR_FALSE, /* handshakeAsServer */
- PR_TRUE, /* enableSSL2 */
- PR_TRUE, /* enableSSL3 */
- PR_TRUE, /* enableTLS */ /* now defaults to on in NSS 3.0 */
- PR_FALSE, /* noCache */
- PR_FALSE, /* fdx */
- PR_TRUE, /* v2CompatibleHello */
- PR_TRUE, /* detectRollBack */
-};
-
-sslSessionIDLookupFunc ssl_sid_lookup;
-sslSessionIDCacheFunc ssl_sid_cache;
-sslSessionIDUncacheFunc ssl_sid_uncache;
-
-static ssl_inited = PR_FALSE;
-static PRDescIdentity ssl_layer_id;
-
-int ssl_lock_readers = 1; /* default true. */
-char ssl_debug;
-char ssl_trace;
-
-
-/* forward declarations. */
-static sslSocket *ssl_NewSocket(void);
-static PRStatus ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack,
- PRDescIdentity id);
-
-/************************************************************************/
-
-/*
-** Lookup a socket structure from a file descriptor.
-*/
-static sslSocket *
-ssl_GetPrivate(PRFileDesc *fd)
-{
- sslSocket *ss;
-
- PORT_Assert(fd != NULL);
- PORT_Assert(fd->methods->file_type == PR_DESC_LAYERED);
- PORT_Assert(fd->identity == ssl_layer_id);
-
- ss = (sslSocket *)fd->secret;
- ss->fd = fd;
- return ss;
-}
-
-sslSocket *
-ssl_FindSocket(PRFileDesc *fd)
-{
- PRFileDesc *layer;
- sslSocket *ss;
-
- PORT_Assert(fd != NULL);
- PORT_Assert(ssl_layer_id != 0);
-
- layer = PR_GetIdentitiesLayer(fd, ssl_layer_id);
- if (layer == NULL)
- return NULL;
-
- ss = (sslSocket *)layer->secret;
- ss->fd = layer;
- return ss;
-}
-
-#if 0 /* dead code. */
-PRFileDesc *
-ssl_FindTop(sslSocket *ss)
-{
- PRFileDesc *fd = ss->fd;
-
- while (fd->higher != NULL)
- fd = fd->higher;
-
- return fd;
-}
-#endif
-
-sslSocket *
-ssl_DupSocket(sslSocket *os)
-{
- sslSocket *ss;
- SECStatus rv;
-
- ss = ssl_NewSocket();
- if (ss) {
- ss->useSocks = os->useSocks;
- ss->useSecurity = os->useSecurity;
- ss->requestCertificate = os->requestCertificate;
- ss->requireCertificate = os->requireCertificate;
- ss->handshakeAsClient = os->handshakeAsClient;
- ss->handshakeAsServer = os->handshakeAsServer;
- ss->enableSSL2 = os->enableSSL2;
- ss->enableSSL3 = os->enableSSL3;
- ss->enableTLS = os->enableTLS;
- ss->noCache = os->noCache;
- ss->fdx = os->fdx;
- ss->v2CompatibleHello = os->v2CompatibleHello;
- ss->detectRollBack = os->detectRollBack;
- ss->peerID = !os->peerID ? NULL : PORT_Strdup(os->peerID);
- ss->url = !os->url ? NULL : PORT_Strdup(os->url);
-
- ss->ops = os->ops;
- ss->peer = os->peer;
- ss->port = os->port;
- ss->rTimeout = os->rTimeout;
- ss->wTimeout = os->wTimeout;
- ss->cTimeout = os->cTimeout;
- ss->dbHandle = os->dbHandle;
-
- /* copy ssl2&3 policy & prefs, even if it's not selected (yet) */
- ss->allowedByPolicy = os->allowedByPolicy;
- ss->maybeAllowedByPolicy= os->maybeAllowedByPolicy;
- ss->chosenPreference = os->chosenPreference;
- PORT_Memcpy(ss->cipherSuites, os->cipherSuites, sizeof os->cipherSuites);
-
- if (os->cipherSpecs) {
- ss->cipherSpecs = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs);
- if (ss->cipherSpecs)
- PORT_Memcpy(ss->cipherSpecs, os->cipherSpecs,
- os->sizeCipherSpecs);
- ss->sizeCipherSpecs = os->sizeCipherSpecs;
- ss->preferredCipher = os->preferredCipher;
- } else {
- ss->cipherSpecs = NULL; /* produced lazily */
- ss->sizeCipherSpecs = 0;
- ss->preferredCipher = NULL;
- }
- if (ss->useSecurity) {
- /* This int should be SSLKEAType, but CC on Irix complains,
- * during the for loop.
- */
- int i;
-
- for (i=kt_null; i < kt_kea_size; i++) {
- if (os->serverCert[i]) {
- ss->serverCert[i] = CERT_DupCertificate(os->serverCert[i]);
- ss->serverCertChain[i] = CERT_CertChainFromCert
- (ss->serverCert[i], certUsageSSLServer,
- PR_TRUE);
- } else {
- ss->serverCert[i] = NULL;
- ss->serverCertChain[i] = NULL;
- }
- ss->serverKey[i] = os->serverKey[i] ?
- SECKEY_CopyPrivateKey(os->serverKey[i]) : NULL;
- }
- ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL :
- ssl3_GetKeyPairRef(os->stepDownKeyPair);
-/*
- * XXX the preceeding CERT_ and SECKEY_ functions can fail and return NULL.
- * XXX We should detect this, and not just march on with NULL pointers.
- */
- ss->authCertificate = os->authCertificate;
- ss->authCertificateArg = os->authCertificateArg;
- ss->getClientAuthData = os->getClientAuthData;
- ss->getClientAuthDataArg = os->getClientAuthDataArg;
- ss->handleBadCert = os->handleBadCert;
- ss->badCertArg = os->badCertArg;
- ss->handshakeCallback = os->handshakeCallback;
- ss->handshakeCallbackData = os->handshakeCallbackData;
- ss->pkcs11PinArg = os->pkcs11PinArg;
-
- /* Create security data */
- rv = ssl_CopySecurityInfo(ss, os);
- if (rv != SECSuccess) {
- goto losage;
- }
- }
- if (ss->useSocks) {
- /* Create security data */
- rv = ssl_CopySocksInfo(ss, os);
- if (rv != SECSuccess) {
- goto losage;
- }
- }
- }
- return ss;
-
- losage:
- return NULL;
-}
-
-/*
- * free an sslSocket struct, and all the stuff that hangs off of it
- */
-void
-ssl_FreeSocket(sslSocket *ss)
-{
- /* "i" should be of type SSLKEAType, but CC on IRIX complains during
- * the for loop.
- */
- int i;
-
- sslSocket *fs;
- sslSocket lSock;
-
-/* Get every lock you can imagine!
-** Caller already holds these:
-** SSL_LOCK_READER(ss);
-** SSL_LOCK_WRITER(ss);
-*/
- ssl_Get1stHandshakeLock(ss);
- ssl_GetRecvBufLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
- ssl_GetXmitBufLock(ss);
- ssl_GetSpecWriteLock(ss);
-
-#ifdef DEBUG
- fs = &lSock;
- *fs = *ss; /* Copy the old socket structure, */
- PORT_Memset(ss, 0x1f, sizeof *ss); /* then blast the old struct ASAP. */
-#else
- fs = ss;
-#endif
-
- /* Free up socket */
- ssl_DestroySocksInfo(fs->socks);
- ssl_DestroySecurityInfo(fs->sec);
- ssl3_DestroySSL3Info(fs->ssl3);
- PORT_Free(fs->saveBuf.buf);
- PORT_Free(fs->pendingBuf.buf);
- if (fs->gather) {
- ssl_DestroyGather(fs->gather);
- }
- if (fs->peerID != NULL)
- PORT_Free(fs->peerID);
- if (fs->url != NULL)
- PORT_Free((void *)fs->url); /* CONST */
-
- /* Clean up server configuration */
- for (i=kt_null; i < kt_kea_size; i++) {
- if (fs->serverCert[i] != NULL)
- CERT_DestroyCertificate(fs->serverCert[i]);
- if (fs->serverCertChain[i] != NULL)
- CERT_DestroyCertificateList(fs->serverCertChain[i]);
- if (fs->serverKey[i] != NULL)
- SECKEY_DestroyPrivateKey(fs->serverKey[i]);
- }
- if (fs->stepDownKeyPair) {
- ssl3_FreeKeyPair(fs->stepDownKeyPair);
- fs->stepDownKeyPair = NULL;
- }
-
-
- /* Release all the locks acquired above. */
- SSL_UNLOCK_READER(fs);
- SSL_UNLOCK_WRITER(fs);
- ssl_Release1stHandshakeLock(fs);
- ssl_ReleaseRecvBufLock(fs);
- ssl_ReleaseSSL3HandshakeLock(fs);
- ssl_ReleaseXmitBufLock(fs);
- ssl_ReleaseSpecWriteLock(fs);
-
- /* Destroy locks. */
- if (fs->firstHandshakeLock) {
- PR_DestroyMonitor(fs->firstHandshakeLock);
- fs->firstHandshakeLock = NULL;
- }
- if (fs->ssl3HandshakeLock) {
- PR_DestroyMonitor(fs->ssl3HandshakeLock);
- fs->ssl3HandshakeLock = NULL;
- }
- if (fs->specLock) {
- NSSRWLock_Destroy(fs->specLock);
- fs->specLock = NULL;
- }
-
- if (fs->recvLock) {
- PR_DestroyLock(fs->recvLock);
- fs->recvLock = NULL;
- }
- if (fs->sendLock) {
- PR_DestroyLock(fs->sendLock);
- fs->sendLock = NULL;
- }
- if (fs->xmitBufLock) {
- PR_DestroyMonitor(fs->xmitBufLock);
- fs->xmitBufLock = NULL;
- }
- if (fs->recvBufLock) {
- PR_DestroyMonitor(fs->recvBufLock);
- fs->recvBufLock = NULL;
- }
- if (fs->cipherSpecs) {
- PORT_Free(fs->cipherSpecs);
- fs->cipherSpecs = NULL;
- fs->sizeCipherSpecs = 0;
- }
-
- PORT_Free(ss); /* free the caller's copy, not ours. */
- return;
-}
-
-/************************************************************************/
-
-static void
-ssl_ChooseOps(sslSocket *ss)
-{
- if (ss->useSocks) {
- ss->ops = ss->useSecurity ? &ssl_secure_socks_ops : &ssl_socks_ops ;
- } else {
- ss->ops = ss->useSecurity ? &ssl_secure_ops : &ssl_default_ops;
- }
-}
-
-/* Called from SSL_Enable (immediately below) */
-static SECStatus
-PrepareSocket(sslSocket *ss)
-{
- SECStatus rv = SECSuccess;
-
- if (ss->useSocks) {
- rv = ssl_CreateSocksInfo(ss);
- if (rv != SECSuccess) {
- return rv;
- }
- }
- if (ss->useSecurity) {
- rv = ssl_CreateSecurityInfo(ss);
- if (rv != SECSuccess) {
- return rv;
- }
- }
-
- ssl_ChooseOps(ss);
- return rv;
-}
-
-SECStatus
-SSL_Enable(PRFileDesc *fd, int which, PRBool on)
-{
- return SSL_OptionSet(fd, which, on);
-}
-
-SECStatus
-SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
-{
- sslSocket *ss = ssl_FindSocket(fd);
- SECStatus rv = SECSuccess;
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
- PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
- return SECFailure;
- }
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- switch (which) {
- case SSL_SOCKS:
- ss->useSocks = on;
- rv = PrepareSocket(ss);
- break;
-
- case SSL_SECURITY:
- ss->useSecurity = on;
- rv = PrepareSocket(ss);
- break;
-
- case SSL_REQUEST_CERTIFICATE:
- ss->requestCertificate = on;
- break;
-
- case SSL_REQUIRE_CERTIFICATE:
- ss->requireCertificate = on;
- break;
-
- case SSL_HANDSHAKE_AS_CLIENT:
- if ( ss->handshakeAsServer && on ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- break;
- }
- ss->handshakeAsClient = on;
- break;
-
- case SSL_HANDSHAKE_AS_SERVER:
- if ( ss->handshakeAsClient && on ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- break;
- }
- ss->handshakeAsServer = on;
- break;
-
- case SSL_ENABLE_TLS:
- ss->enableTLS = on;
- ss->preferredCipher = NULL;
- if (ss->cipherSpecs) {
- PORT_Free(ss->cipherSpecs);
- ss->cipherSpecs = NULL;
- ss->sizeCipherSpecs = 0;
- }
- break;
-
- case SSL_ENABLE_SSL3:
- ss->enableSSL3 = on;
- ss->preferredCipher = NULL;
- if (ss->cipherSpecs) {
- PORT_Free(ss->cipherSpecs);
- ss->cipherSpecs = NULL;
- ss->sizeCipherSpecs = 0;
- }
- break;
-
- case SSL_ENABLE_SSL2:
- ss->enableSSL2 = on;
- if (on) {
- ss->v2CompatibleHello = on;
- }
- ss->preferredCipher = NULL;
- if (ss->cipherSpecs) {
- PORT_Free(ss->cipherSpecs);
- ss->cipherSpecs = NULL;
- ss->sizeCipherSpecs = 0;
- }
- break;
-
- case SSL_NO_CACHE:
- ss->noCache = on;
- break;
-
- case SSL_ENABLE_FDX:
- ss->fdx = on;
- break;
-
- case SSL_V2_COMPATIBLE_HELLO:
- ss->v2CompatibleHello = on;
- if (!on) {
- ss->enableSSL2 = on;
- }
- break;
-
- case SSL_ROLLBACK_DETECTION:
- ss->detectRollBack = on;
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- return rv;
-}
-
-SECStatus
-SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
-{
- sslSocket *ss = ssl_FindSocket(fd);
- SECStatus rv = SECSuccess;
- PRBool on = PR_FALSE;
-
- if (!pOn) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
- PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
- *pOn = PR_FALSE;
- return SECFailure;
- }
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- switch (which) {
- case SSL_SOCKS: on = ss->useSocks; break;
- case SSL_SECURITY: on = ss->useSecurity; break;
- case SSL_REQUEST_CERTIFICATE: on = ss->requestCertificate; break;
- case SSL_REQUIRE_CERTIFICATE: on = ss->requireCertificate; break;
- case SSL_HANDSHAKE_AS_CLIENT: on = ss->handshakeAsClient; break;
- case SSL_HANDSHAKE_AS_SERVER: on = ss->handshakeAsServer; break;
- case SSL_ENABLE_TLS: on = ss->enableTLS; break;
- case SSL_ENABLE_SSL3: on = ss->enableSSL3; break;
- case SSL_ENABLE_SSL2: on = ss->enableSSL2; break;
- case SSL_NO_CACHE: on = ss->noCache; break;
- case SSL_ENABLE_FDX: on = ss->fdx; break;
- case SSL_V2_COMPATIBLE_HELLO: on = ss->v2CompatibleHello; break;
- case SSL_ROLLBACK_DETECTION: on = ss->detectRollBack; break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- *pOn = on;
- return rv;
-}
-
-SECStatus
-SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
-{
- SECStatus rv = SECSuccess;
- PRBool on = PR_FALSE;
-
- if (!pOn) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- switch (which) {
- case SSL_SOCKS: on = ssl_defaults.useSocks; break;
- case SSL_SECURITY: on = ssl_defaults.useSecurity; break;
- case SSL_REQUEST_CERTIFICATE: on = ssl_defaults.requestCertificate; break;
- case SSL_REQUIRE_CERTIFICATE: on = ssl_defaults.requireCertificate; break;
- case SSL_HANDSHAKE_AS_CLIENT: on = ssl_defaults.handshakeAsClient; break;
- case SSL_HANDSHAKE_AS_SERVER: on = ssl_defaults.handshakeAsServer; break;
- case SSL_ENABLE_TLS: on = ssl_defaults.enableTLS; break;
- case SSL_ENABLE_SSL3: on = ssl_defaults.enableSSL3; break;
- case SSL_ENABLE_SSL2: on = ssl_defaults.enableSSL2; break;
- case SSL_NO_CACHE: on = ssl_defaults.noCache; break;
- case SSL_ENABLE_FDX: on = ssl_defaults.fdx; break;
- case SSL_V2_COMPATIBLE_HELLO: on = ssl_defaults.v2CompatibleHello; break;
- case SSL_ROLLBACK_DETECTION: on = ssl_defaults.detectRollBack; break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
-
- *pOn = on;
- return rv;
-}
-
-/* XXX Use Global Lock to protect this stuff. */
-SECStatus
-SSL_EnableDefault(int which, PRBool on)
-{
- return SSL_OptionSetDefault(which, on);
-}
-
-SECStatus
-SSL_OptionSetDefault(PRInt32 which, PRBool on)
-{
- switch (which) {
- case SSL_SOCKS:
- ssl_defaults.useSocks = on;
- break;
-
- case SSL_SECURITY:
- ssl_defaults.useSecurity = on;
- break;
-
- case SSL_REQUEST_CERTIFICATE:
- ssl_defaults.requestCertificate = on;
- break;
-
- case SSL_REQUIRE_CERTIFICATE:
- ssl_defaults.requireCertificate = on;
- break;
-
- case SSL_HANDSHAKE_AS_CLIENT:
- if ( ssl_defaults.handshakeAsServer && on ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- ssl_defaults.handshakeAsClient = on;
- break;
-
- case SSL_HANDSHAKE_AS_SERVER:
- if ( ssl_defaults.handshakeAsClient && on ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- ssl_defaults.handshakeAsServer = on;
- break;
-
- case SSL_ENABLE_TLS:
- ssl_defaults.enableTLS = on;
- break;
-
- case SSL_ENABLE_SSL3:
- ssl_defaults.enableSSL3 = on;
- break;
-
- case SSL_ENABLE_SSL2:
- ssl_defaults.enableSSL2 = on;
- if (on) {
- ssl_defaults.v2CompatibleHello = on;
- }
- break;
-
- case SSL_NO_CACHE:
- ssl_defaults.noCache = on;
- break;
-
- case SSL_ENABLE_FDX:
- ssl_defaults.fdx = on;
-
- case SSL_V2_COMPATIBLE_HELLO:
- ssl_defaults.v2CompatibleHello = on;
- if (!on) {
- ssl_defaults.enableSSL2 = on;
- }
- break;
-
- case SSL_ROLLBACK_DETECTION:
- ssl_defaults.detectRollBack = on;
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/* Part of the public NSS API.
- * Since this is a global (not per-socket) setting, we cannot use the
- * HandshakeLock to protect this. Probably want a global lock.
- */
-SECStatus
-SSL_SetPolicy(long which, int policy)
-{
- if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
- /* one of the two old FIPS ciphers */
- if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA)
- which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
- else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
- which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
- }
- return SSL_CipherPolicySet(which, policy);
-}
-
-SECStatus
-SSL_CipherPolicySet(PRInt32 which, PRInt32 policy)
-{
- SECStatus rv;
-
- if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_SetPolicy(which, policy);
- } else {
- rv = ssl3_SetPolicy((ssl3CipherSuite)which, policy);
- }
- return rv;
-}
-
-SECStatus
-SSL_CipherPolicyGet(PRInt32 which, PRInt32 *oPolicy)
-{
- SECStatus rv;
-
- if (!oPolicy) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_GetPolicy(which, oPolicy);
- } else {
- rv = ssl3_GetPolicy((ssl3CipherSuite)which, oPolicy);
- }
- return rv;
-}
-
-/* Part of the public NSS API.
- * Since this is a global (not per-socket) setting, we cannot use the
- * HandshakeLock to protect this. Probably want a global lock.
- * These changes have no effect on any sslSockets already created.
- */
-SECStatus
-SSL_EnableCipher(long which, PRBool enabled)
-{
- if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
- /* one of the two old FIPS ciphers */
- if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA)
- which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
- else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
- which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
- }
- return SSL_CipherPrefSetDefault(which, enabled);
-}
-
-SECStatus
-SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
-{
- SECStatus rv;
-
- if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_CipherPrefSetDefault(which, enabled);
- } else {
- rv = ssl3_CipherPrefSetDefault((ssl3CipherSuite)which, enabled);
- }
- return rv;
-}
-
-SECStatus
-SSL_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
-{
- SECStatus rv;
-
- if (!enabled) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_CipherPrefGetDefault(which, enabled);
- } else {
- rv = ssl3_CipherPrefGetDefault((ssl3CipherSuite)which, enabled);
- }
- return rv;
-}
-
-SECStatus
-SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
-{
- SECStatus rv;
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefSet", SSL_GETPID(), fd));
- PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
- return SECFailure;
- }
- if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_CipherPrefSet(ss, which, enabled);
- } else {
- rv = ssl3_CipherPrefSet(ss, (ssl3CipherSuite)which, enabled);
- }
- return rv;
-}
-
-SECStatus
-SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
-{
- SECStatus rv;
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!enabled) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefGet", SSL_GETPID(), fd));
- PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
- *enabled = PR_FALSE;
- return SECFailure;
- }
- if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_CipherPrefGet(ss, which, enabled);
- } else {
- rv = ssl3_CipherPrefGet(ss, (ssl3CipherSuite)which, enabled);
- }
- return rv;
-}
-
-SECStatus
-NSS_SetDomesticPolicy(void)
-{
-#ifndef EXPORT_VERSION
- SECStatus status = SECSuccess;
- cipherPolicy * policy;
-
- for (policy = ssl_ciphers; policy->cipher != 0; ++policy) {
- status = SSL_SetPolicy(policy->cipher, SSL_ALLOWED);
- if (status != SECSuccess)
- break;
- }
- return status;
-#else
- return NSS_SetExportPolicy();
-#endif
-}
-
-SECStatus
-NSS_SetExportPolicy(void)
-{
- SECStatus status = SECSuccess;
- cipherPolicy * policy;
-
- for (policy = ssl_ciphers; policy->cipher != 0; ++policy) {
- status = SSL_SetPolicy(policy->cipher, policy->export);
- if (status != SECSuccess)
- break;
- }
- return status;
-}
-
-SECStatus
-NSS_SetFrancePolicy(void)
-{
- SECStatus status = SECSuccess;
- cipherPolicy * policy;
-
- for (policy = ssl_ciphers; policy->cipher != 0; ++policy) {
- status = SSL_SetPolicy(policy->cipher, policy->france);
- if (status != SECSuccess)
- break;
- }
- return status;
-}
-
-
-
-/* LOCKS ??? XXX */
-PRFileDesc *
-SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
-{
- sslSocket * ns = NULL;
- PRStatus rv;
-
- if (model == NULL) {
- /* Just create a default socket if we're given NULL for the model */
- ns = ssl_NewSocket();
- } else {
- sslSocket * ss = ssl_FindSocket(model);
- if (ss == NULL) {
- SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ImportFD",
- SSL_GETPID(), model));
- SET_ERROR_CODE
- return NULL;
- }
- ns = ssl_DupSocket(ss);
- }
- if (ns == NULL)
- return NULL;
-
- rv = ssl_PushIOLayer(ns, fd, PR_TOP_IO_LAYER);
- if (rv != PR_SUCCESS) {
- ssl_FreeSocket(ns);
- SET_ERROR_CODE
- return NULL;
- }
-#ifdef _WIN32
- PR_Sleep(PR_INTERVAL_NO_WAIT); /* workaround NT winsock connect bug. */
-#endif
- return fd;
-}
-
-/************************************************************************/
-/* The following functions are the TOP LEVEL SSL functions.
-** They all get called through the NSPRIOMethods table below.
-*/
-
-static PRFileDesc * PR_CALLBACK
-ssl_Accept(PRFileDesc *fd, PRNetAddr *sockaddr, PRIntervalTime timeout)
-{
- sslSocket *ss;
- sslSocket *ns = NULL;
- PRFileDesc *newfd = NULL;
- PRFileDesc *layer = NULL;
- PRFileDesc *osfd;
- PRStatus status;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in accept", SSL_GETPID(), fd));
- return NULL;
- }
-
- /* IF this is a listen socket, there shouldn't be any I/O going on */
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- ss->cTimeout = timeout;
-
- osfd = ss->fd->lower;
-
- /* First accept connection */
- newfd = osfd->methods->accept(osfd, sockaddr, timeout);
- if (newfd == NULL) {
- SSL_DBG(("%d: SSL[%d]: accept failed, errno=%d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- } else {
- /* Create ssl module */
- ns = ssl_DupSocket(ss);
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
- SSL_UNLOCK_WRITER(ss);
- SSL_UNLOCK_READER(ss); /* ss isn't used below here. */
-
- if (ns == NULL)
- goto loser;
-
- /* push ssl module onto the new socket */
- status = ssl_PushIOLayer(ns, newfd, PR_TOP_IO_LAYER);
- if (status != PR_SUCCESS)
- goto loser;
-
- /* Now start server connection handshake with client.
- ** Don't need locks here because nobody else has a reference to ns yet.
- */
- if ( ns->useSecurity ) {
- if ( ns->handshakeAsClient ) {
- ns->handshake = ssl2_BeginClientHandshake;
- } else {
- ns->handshake = ssl2_BeginServerHandshake;
- }
- }
- return newfd;
-
-loser:
- if (ns != NULL)
- ssl_FreeSocket(ns);
- if (newfd != NULL)
- PR_Close(newfd);
- return NULL;
-}
-
-static PRStatus PR_CALLBACK
-ssl_Connect(PRFileDesc *fd, const PRNetAddr *sockaddr, PRIntervalTime timeout)
-{
- sslSocket *ss;
- PRStatus rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in connect", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
-
- /* IF this is a listen socket, there shouldn't be any I/O going on */
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
-
- ss->cTimeout = timeout;
- rv = (PRStatus)(*ss->ops->connect)(ss, sockaddr);
-#ifdef _WIN32
- PR_Sleep(PR_INTERVAL_NO_WAIT); /* workaround NT winsock connect bug. */
-#endif
-
- SSL_UNLOCK_WRITER(ss);
- SSL_UNLOCK_READER(ss);
-
- return rv;
-}
-
-static PRStatus PR_CALLBACK
-ssl_Bind(PRFileDesc *fd, const PRNetAddr *addr)
-{
- sslSocket * ss = ssl_GetPrivate(fd);
- PRStatus rv;
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in bind", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
-
- rv = (PRStatus)(*ss->ops->bind)(ss, addr);
-
- SSL_UNLOCK_WRITER(ss);
- SSL_UNLOCK_READER(ss);
- return rv;
-}
-
-static PRStatus PR_CALLBACK
-ssl_Listen(PRFileDesc *fd, PRIntn backlog)
-{
- sslSocket * ss = ssl_GetPrivate(fd);
- PRStatus rv;
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in listen", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
-
- rv = (PRStatus)(*ss->ops->listen)(ss, backlog);
-
- SSL_UNLOCK_WRITER(ss);
- SSL_UNLOCK_READER(ss);
- return rv;
-}
-
-static PRStatus PR_CALLBACK
-ssl_Shutdown(PRFileDesc *fd, PRIntn how)
-{
- sslSocket * ss = ssl_GetPrivate(fd);
- PRStatus rv;
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in shutdown", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
- if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
- SSL_LOCK_READER(ss);
- }
- if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
- SSL_LOCK_WRITER(ss);
- }
-
- rv = (PRStatus)(*ss->ops->shutdown)(ss, how);
-
- if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
- SSL_UNLOCK_WRITER(ss);
- }
- if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
- SSL_UNLOCK_READER(ss);
- }
- return rv;
-}
-
-static PRStatus PR_CALLBACK
-ssl_Close(PRFileDesc *fd)
-{
- sslSocket *ss;
- PRStatus rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in close", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
-
- /* There must not be any I/O going on */
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
-
- /* By the time this function returns,
- ** ss is an invalid pointer, and the locks to which it points have
- ** been unlocked and freed. So, this is the ONE PLACE in all of SSL
- ** where the LOCK calls and the corresponding UNLOCK calls are not in
- ** the same function scope. The unlock calls are in ssl_FreeSocket().
- */
- rv = (PRStatus)(*ss->ops->close)(ss);
-
- return rv;
-}
-
-static int PR_CALLBACK
-ssl_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags,
- PRIntervalTime timeout)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in recv", SSL_GETPID(), fd));
- return SECFailure;
- }
- SSL_LOCK_READER(ss);
- ss->rTimeout = timeout;
- rv = (*ss->ops->recv)(ss, (unsigned char*)buf, len, flags);
- SSL_UNLOCK_READER(ss);
- return rv;
-}
-
-static int PR_CALLBACK
-ssl_Send(PRFileDesc *fd, const void *buf, PRInt32 len, PRIntn flags,
- PRIntervalTime timeout)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in send", SSL_GETPID(), fd));
- return SECFailure;
- }
- SSL_LOCK_WRITER(ss);
- ss->wTimeout = timeout;
- rv = (*ss->ops->send)(ss, (const unsigned char*)buf, len, flags);
- SSL_UNLOCK_WRITER(ss);
- return rv;
-}
-
-static int PR_CALLBACK
-ssl_Read(PRFileDesc *fd, void *buf, PRInt32 len)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in read", SSL_GETPID(), fd));
- return SECFailure;
- }
- SSL_LOCK_READER(ss);
- ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
- rv = (*ss->ops->read)(ss, (unsigned char*)buf, len);
- SSL_UNLOCK_READER(ss);
- return rv;
-}
-
-static int PR_CALLBACK
-ssl_Write(PRFileDesc *fd, const void *buf, PRInt32 len)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in write", SSL_GETPID(), fd));
- return SECFailure;
- }
- SSL_LOCK_WRITER(ss);
- ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
- rv = (*ss->ops->write)(ss, (const unsigned char*)buf, len);
- SSL_UNLOCK_WRITER(ss);
- return rv;
-}
-
-static PRStatus PR_CALLBACK
-ssl_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
-{
- sslSocket *ss;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in getpeername", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
- return (PRStatus)(*ss->ops->getpeername)(ss, addr);
-}
-
-/*
-** XXX this code doesn't work properly inside a Socks server.
-*/
-SECStatus
-ssl_GetPeerInfo(sslSocket *ss)
-{
- sslConnectInfo * ci;
- PRNetAddr sin;
- int rv;
- PRFileDesc * osfd;
-
- PORT_Assert((ss->sec != 0));
-
- osfd = ss->fd->lower;
- ci = &ss->sec->ci;
-
- /* If ssl_SocksConnect() has previously recorded the peer's IP & port,
- * use that.
- */
- if ((ss->peer != 0) && (ss->port != 0)) {
- /* SOCKS code has already recorded the peer's IP addr and port.
- * (NOT the proxy's addr and port) in ss->peer & port.
- */
- ci->peer = ss->peer;
- ci->port = ss->port;
- return SECSuccess;
- }
-
- PORT_Memset(&sin, 0, sizeof(sin));
- rv = osfd->methods->getpeername(osfd, &sin);
- if (rv < 0) {
- return SECFailure;
- }
- /* we have to mask off the high byte because AIX is lame */
- PORT_Assert((sin.inet.family & 0xff) == PR_AF_INET);
- ci->peer = sin.inet.ip;
- ci->port = sin.inet.port;
- return SECSuccess;
-}
-
-static PRStatus PR_CALLBACK
-ssl_GetSockName(PRFileDesc *fd, PRNetAddr *name)
-{
- sslSocket *ss;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in getsockname", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
- return (PRStatus)(*ss->ops->getsockname)(ss, name);
-}
-
-int PR_CALLBACK
-SSL_SetSockPeerID(PRFileDesc *fd, char *peerID)
-{
- sslSocket *ss;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCacheIndex",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- ss->peerID = PORT_Strdup(peerID);
- return 0;
-}
-
-static PRInt16 PR_CALLBACK
-ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *out_flags)
-{
- sslSocket *ss;
- PRInt16 ret_flags = how_flags; /* should select on these flags. */
-
- *out_flags = 0;
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_Poll",
- SSL_GETPID(), fd));
- return 0; /* don't poll on this socket */
- }
-
- if ((ret_flags & PR_POLL_WRITE) &&
- ( (ss->useSocks && ss->handshake) ||
- (ss->useSecurity && !ss->connected &&
- /* XXX There needs to be a better test than the following. */
- /* Don't check ss->securityHandshake. */
- (ss->handshake || ss->nextHandshake)))) {
- /* The user is trying to write, but the handshake is blocked waiting
- * to read, so tell NSPR NOT to poll on write.
- */
- ret_flags ^= PR_POLL_WRITE; /* don't select on write. */
- ret_flags |= PR_POLL_READ; /* do select on read. */
- }
-
- if ((ret_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
- *out_flags = PR_POLL_READ; /* it's ready already. */
-
- } else if (ret_flags && (fd->lower->methods->poll != NULL)) {
- ret_flags = fd->lower->methods->poll(fd->lower, ret_flags, out_flags);
- }
-
- return ret_flags;
-}
-
-
-PRBool
-ssl_FdIsBlocking(PRFileDesc *fd)
-{
- PRSocketOptionData opt;
- PRStatus status;
-
- opt.option = PR_SockOpt_Nonblocking;
- opt.value.non_blocking = PR_FALSE;
- status = PR_GetSocketOption(fd, &opt);
- if (status != PR_SUCCESS)
- return PR_FALSE;
- return (PRBool)!opt.value.non_blocking;
-}
-
-PRBool
-ssl_SocketIsBlocking(sslSocket *ss)
-{
- return ssl_FdIsBlocking(ss->fd);
-}
-
-PRInt32 sslFirstBufSize = 8 * 1024;
-PRInt32 sslCopyLimit = 1024;
-
-static PRInt32 PR_CALLBACK
-ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors,
- PRIntervalTime timeout)
-{
- PRInt32 bufLen;
- PRInt32 left;
- PRInt32 rv;
- PRInt32 sent = 0;
- const PRInt32 first_len = sslFirstBufSize;
- const PRInt32 limit = sslCopyLimit;
- PRBool blocking;
- PRIOVec myIov = { 0, 0 };
- char buf[MAX_FRAGMENT_LENGTH];
-
- if (vectors > PR_MAX_IOVECTOR_SIZE) {
- PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
- return -1;
- }
- blocking = ssl_FdIsBlocking(fd);
-
-#define K16 sizeof(buf)
-#define KILL_VECTORS while (vectors && !iov->iov_len) { ++iov; --vectors; }
-#define GET_VECTOR do { myIov = *iov++; --vectors; KILL_VECTORS } while (0)
-#define HANDLE_ERR(rv, len) \
- if (rv != len) { \
- if (rv < 0) { \
- if (blocking \
- && (PR_GetError() == PR_WOULD_BLOCK_ERROR) \
- && (sent > 0)) { \
- return sent; \
- } else { \
- return -1; \
- } \
- } \
- /* Only a nonblocking socket can have partial sends */ \
- PR_ASSERT(blocking); \
- return sent; \
- }
-#define SEND(bfr, len) \
- do { \
- rv = ssl_Send(fd, bfr, len, 0, timeout); \
- HANDLE_ERR(rv, len) \
- sent += len; \
- } while (0)
-
- /* Make sure the first write is at least 8 KB, if possible. */
- KILL_VECTORS
- if (!vectors)
- return 0;
- GET_VECTOR;
- if (!vectors) {
- return ssl_Send(fd, myIov.iov_base, myIov.iov_len, 0, timeout);
- }
- if (myIov.iov_len < first_len) {
- PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
- bufLen = myIov.iov_len;
- left = first_len - bufLen;
- while (vectors && left) {
- int toCopy;
- GET_VECTOR;
- toCopy = PR_MIN(left, myIov.iov_len);
- PORT_Memcpy(buf + bufLen, myIov.iov_base, toCopy);
- bufLen += toCopy;
- left -= toCopy;
- myIov.iov_base += toCopy;
- myIov.iov_len -= toCopy;
- }
- SEND( buf, bufLen );
- }
-
- while (vectors || myIov.iov_len) {
- PRInt32 addLen;
- if (!myIov.iov_len) {
- GET_VECTOR;
- }
- while (myIov.iov_len >= K16) {
- SEND(myIov.iov_base, K16);
- myIov.iov_base += K16;
- myIov.iov_len -= K16;
- }
- if (!myIov.iov_len)
- continue;
-
- if (!vectors || myIov.iov_len > limit) {
- addLen = 0;
- } else if ((addLen = iov->iov_len % K16) + myIov.iov_len <= limit) {
- /* Addlen is already computed. */;
- } else if (vectors > 1 &&
- iov[1].iov_len % K16 + addLen + myIov.iov_len <= 2 * limit) {
- addLen = limit - myIov.iov_len;
- } else
- addLen = 0;
-
- if (!addLen) {
- SEND( myIov.iov_base, myIov.iov_len );
- myIov.iov_len = 0;
- continue;
- }
- PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
- bufLen = myIov.iov_len;
- do {
- GET_VECTOR;
- PORT_Memcpy(buf + bufLen, myIov.iov_base, addLen);
- myIov.iov_base += addLen;
- myIov.iov_len -= addLen;
- bufLen += addLen;
-
- left = PR_MIN( limit, K16 - bufLen);
- if (!vectors /* no more left */
- || myIov.iov_len > 0 /* we didn't use that one all up */
- || bufLen >= K16 /* it's full. */
- ) {
- addLen = 0;
- } else if ((addLen = iov->iov_len % K16) <= left) {
- /* Addlen is already computed. */;
- } else if (vectors > 1 &&
- iov[1].iov_len % K16 + addLen <= left + limit) {
- addLen = left;
- } else
- addLen = 0;
-
- } while (addLen);
- SEND( buf, bufLen );
- }
- return sent;
-}
-
-/*
- * These functions aren't implemented.
- */
-
-static PRInt32 PR_CALLBACK
-ssl_Available(PRFileDesc *fd)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return SECFailure;
-}
-
-static PRInt64 PR_CALLBACK
-ssl_Available64(PRFileDesc *fd)
-{
- PRInt64 res;
-
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- LL_I2L(res, -1L);
- return res;
-}
-
-static PRStatus PR_CALLBACK
-ssl_FSync(PRFileDesc *fd)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return PR_FAILURE;
-}
-
-static PRInt32 PR_CALLBACK
-ssl_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence how) {
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return SECFailure;
-}
-
-static PRInt64 PR_CALLBACK
-ssl_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence how) {
- PRInt64 res;
-
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- LL_I2L(res, -1L);
- return res;
-}
-
-static PRStatus PR_CALLBACK
-ssl_FileInfo(PRFileDesc *fd, PRFileInfo *info)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return PR_FAILURE;
-}
-
-static PRStatus PR_CALLBACK
-ssl_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return PR_FAILURE;
-}
-
-static PRInt32 PR_CALLBACK
-ssl_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
- PRNetAddr *addr, PRIntervalTime timeout)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return SECFailure;
-}
-
-static PRInt32 PR_CALLBACK
-ssl_SendTo(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
- const PRNetAddr *addr, PRIntervalTime timeout)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return SECFailure;
-}
-
-static PRIOMethods ssl_methods = {
- PR_DESC_LAYERED,
- ssl_Close, /* close */
- ssl_Read, /* read */
- ssl_Write, /* write */
- ssl_Available, /* available */
- ssl_Available64, /* available64 */
- ssl_FSync, /* fsync */
- ssl_Seek, /* seek */
- ssl_Seek64, /* seek64 */
- ssl_FileInfo, /* fileInfo */
- ssl_FileInfo64, /* fileInfo64 */
- ssl_WriteV, /* writev */
- ssl_Connect, /* connect */
- ssl_Accept, /* accept */
- ssl_Bind, /* bind */
- ssl_Listen, /* listen */
- ssl_Shutdown, /* shutdown */
- ssl_Recv, /* recv */
- ssl_Send, /* send */
- ssl_RecvFrom, /* recvfrom */
- ssl_SendTo, /* sendto */
- ssl_Poll, /* poll */
- ssl_EmulateAcceptRead, /* acceptread */
- ssl_EmulateTransmitFile, /* transmitfile */
- ssl_GetSockName, /* getsockname */
- ssl_GetPeerName, /* getpeername */
- NULL, /* getsockopt OBSOLETE */
- NULL, /* setsockopt OBSOLETE */
- NULL, /* getsocketoption */
- NULL, /* setsocketoption */
- ssl_EmulateSendFile, /* Send a (partial) file with header/trailer*/
- NULL, /* reserved for future use */
- NULL, /* reserved for future use */
- NULL, /* reserved for future use */
- NULL, /* reserved for future use */
- NULL /* reserved for future use */
-};
-
-static void
-ssl_SetupIOMethods(PRIOMethods *ssl_methods)
-{
- const PRIOMethods *default_methods;
-
- default_methods = PR_GetDefaultIOMethods();
-
- ssl_methods->reserved_fn_6 = default_methods->reserved_fn_6;
- ssl_methods->reserved_fn_5 = default_methods->reserved_fn_5;
- ssl_methods->getsocketoption = default_methods->getsocketoption;
- ssl_methods->setsocketoption = default_methods->setsocketoption;
- ssl_methods->reserved_fn_4 = default_methods->reserved_fn_4;
- ssl_methods->reserved_fn_3 = default_methods->reserved_fn_3;
- ssl_methods->reserved_fn_2 = default_methods->reserved_fn_2;
- ssl_methods->reserved_fn_1 = default_methods->reserved_fn_1;
- ssl_methods->reserved_fn_0 = default_methods->reserved_fn_0;
-
-}
-
-static PRStatus
-ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id)
-{
- PRFileDesc *layer = NULL;
- PRStatus status;
-
- if (ssl_inited != PR_TRUE) {
- ssl_layer_id = PR_GetUniqueIdentity("SSL");
- ssl_SetupIOMethods(&ssl_methods);
- ssl_inited = PR_TRUE;
- }
-
- if (ns == NULL)
- goto loser;
-
- layer = PR_CreateIOLayerStub(ssl_layer_id, &ssl_methods);
- if (layer == NULL)
- goto loser;
- layer->secret = (PRFilePrivate *)ns;
-
- /* Here, "stack" points to the PRFileDesc on the top of the stack.
- ** "layer" points to a new FD that is to be inserted into the stack.
- ** If layer is being pushed onto the top of the stack, then
- ** PR_PushIOLayer switches the contents of stack and layer, and then
- ** puts stack on top of layer, so that after it is done, the top of
- ** stack is the same "stack" as it was before, and layer is now the
- ** FD for the former top of stack.
- ** After this call, stack always points to the top PRFD on the stack.
- ** If this function fails, the contents of stack and layer are as
- ** they were before the call.
- */
- status = PR_PushIOLayer(stack, id, layer);
- if (status != PR_SUCCESS)
- goto loser;
-
- ns->fd = (id == PR_TOP_IO_LAYER) ? stack : layer;
- return PR_SUCCESS;
-
-loser:
- if (layer) {
- layer->dtor(layer); /* free layer */
- }
- return PR_FAILURE;
-}
-
-/*
-** Create a newsocket structure for a file descriptor.
-*/
-static sslSocket *
-ssl_NewSocket(void)
-{
- sslSocket *ss;
-#ifdef DEBUG
- static int firsttime = 1;
-#endif
-
-#ifdef DEBUG
-#if defined(XP_UNIX) || defined(XP_WIN32)
- if (firsttime) {
- firsttime = 0;
-
- {
- char *ev = getenv("SSLDEBUG");
- if (ev && ev[0]) {
- ssl_debug = atoi(ev);
- SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
- }
- }
-#ifdef TRACE
- {
- char *ev = getenv("SSLTRACE");
- if (ev && ev[0]) {
- ssl_trace = atoi(ev);
- SSL_TRACE(("SSL: tracing set to %d", ssl_trace));
- }
- }
-#endif /* TRACE */
- }
-#endif /* XP_UNIX || XP_WIN32 */
-#endif /* DEBUG */
-
- /* Make a new socket and get it ready */
- ss = (sslSocket*) PORT_ZAlloc(sizeof(sslSocket));
- if (ss) {
- /* This should be of type SSLKEAType, but CC on IRIX
- * complains during the for loop.
- */
- int i;
-
- ss->useSecurity = ssl_defaults.useSecurity;
- ss->useSocks = ssl_defaults.useSocks;
- ss->requestCertificate = ssl_defaults.requestCertificate;
- ss->requireCertificate = ssl_defaults.requireCertificate;
- ss->handshakeAsClient = ssl_defaults.handshakeAsClient;
- ss->handshakeAsServer = ssl_defaults.handshakeAsServer;
- ss->enableSSL2 = ssl_defaults.enableSSL2;
- ss->enableSSL3 = ssl_defaults.enableSSL3;
- ss->enableTLS = ssl_defaults.enableTLS ;
- ss->fdx = ssl_defaults.fdx;
- ss->v2CompatibleHello = ssl_defaults.v2CompatibleHello;
- ss->detectRollBack = ssl_defaults.detectRollBack;
- ss->peer = 0;
- ss->port = 0;
- ss->noCache = ssl_defaults.noCache;
- ss->peerID = NULL;
- ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
- ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
- ss->cTimeout = PR_INTERVAL_NO_TIMEOUT;
- ss->cipherSpecs = NULL;
- ss->sizeCipherSpecs = 0; /* produced lazily */
- ss->preferredCipher = NULL;
- ss->url = NULL;
-
- for (i=kt_null; i < kt_kea_size; i++) {
- ss->serverCert[i] = NULL;
- ss->serverCertChain[i] = NULL;
- ss->serverKey[i] = NULL;
- }
- ss->stepDownKeyPair = NULL;
- ss->dbHandle = CERT_GetDefaultCertDB();
-
- /* Provide default implementation of hooks */
- ss->authCertificate = SSL_AuthCertificate;
- ss->authCertificateArg = (void *)ss->dbHandle;
- ss->getClientAuthData = NULL;
- ss->handleBadCert = NULL;
- ss->badCertArg = NULL;
- ss->pkcs11PinArg = NULL;
-
- ssl_ChooseOps(ss);
- ssl2_InitSocketPolicy(ss);
- ssl3_InitSocketPolicy(ss);
-
- ss->firstHandshakeLock = PR_NewMonitor();
- ss->ssl3HandshakeLock = PR_NewMonitor();
- ss->specLock = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL);
- ss->recvBufLock = PR_NewMonitor();
- ss->xmitBufLock = PR_NewMonitor();
- if (ssl_lock_readers) {
- ss->recvLock = PR_NewLock();
- ss->sendLock = PR_NewLock();
- }
- }
- return ss;
-}
-
diff --git a/security/nss/lib/ssl/sslsocks.c b/security/nss/lib/ssl/sslsocks.c
deleted file mode 100644
index 787d448d6..000000000
--- a/security/nss/lib/ssl/sslsocks.c
+++ /dev/null
@@ -1,1147 +0,0 @@
-/*
- * Implementation of Socks protocol.
- * None of this code is supported any longer.
- * NSS officially does NOT support Socks.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-#include "prtypes.h"
-#include "prnetdb.h"
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "prsystem.h"
-#include <stdio.h>
-#include "nspr.h"
-
-#ifdef XP_UNIX
-#include "prprf.h"
-#endif
-
-#ifdef XP_UNIX
-#define SOCKS_FILE "/etc/socks.conf"
-#endif
-#ifdef XP_MAC
-#define SOCKS_FILE NULL
-#endif
-#ifdef XP_WIN
-#define SOCKS_FILE NULL
-#endif
-#ifdef XP_OS2
-#define SOCKS_FILE NULL
-#endif
-
-#define SOCKS_VERSION 4
-
-#define DEF_SOCKD_PORT 1080
-
-#define SOCKS_CONNECT 1
-#define SOCKS_BIND 2
-
-#define SOCKS_RESULT 90
-#define SOCKS_FAIL 91
-#define SOCKS_NO_IDENTD 92 /* Failed to connect to Identd on client machine */
-#define SOCKS_BAD_ID 93 /* Client's Identd reported a different user-id */
-
-#define MAKE_IN_ADDR(a,b,c,d) \
- PR_htonl(((PRUint32)(a) << 24) | ((PRUint32)(b) << 16) | ((c) << 8) | (d))
-
-struct sslSocksInfoStr {
- PRUint32 sockdHost;
- PRUint16 sockdPort;
-
- char direct;
- char didBind;
-
- PRNetAddr bindAddr;
-
- /* Data returned by sockd. */
- PRUint32 destHost;
- PRUint16 destPort;
-};
-
-typedef enum {
- OP_LESS = 1,
- OP_EQUAL = 2,
- OP_LEQUAL = 3,
- OP_GREATER = 4,
- OP_NOTEQUAL = 5,
- OP_GEQUAL = 6,
- OP_ALWAYS = 7
-} SocksOp;
-
-typedef struct SocksConfItemStr SocksConfItem;
-
-struct SocksConfItemStr {
- SocksConfItem *next;
- PRUint32 daddr; /* host IP addr, in network byte order. */
- PRUint32 dmask; /* mask for IP, in network byte order. */
- PRUint16 port; /* port number, in host byte order. */
- SocksOp op;
- char direct;
-};
-
-static PRUint32 ourHost; /* network byte order. */
-static SocksConfItem *ssl_socks_confs;
-
-SECStatus
-ssl_CreateSocksInfo(sslSocket *ss)
-{
- sslSocksInfo *si;
-
- if (ss->socks) {
- /* Already been done */
- return SECSuccess;
- }
-
- si = (sslSocksInfo*) PORT_ZAlloc(sizeof(sslSocksInfo));
- if (si) {
- ss->socks = si;
- if (!ss->gather) {
- ss->gather = ssl_NewGather();
- if (!ss->gather) {
- return SECFailure;
- }
- }
- return SECSuccess;
- }
- return SECFailure;
-}
-
-SECStatus
-ssl_CopySocksInfo(sslSocket *ss, sslSocket *os)
-{
- SECStatus rv;
-
-#ifdef __cplusplus
- os = os;
-#endif
- rv = ssl_CreateSocksInfo(ss);
- return rv;
-}
-
-void
-ssl_DestroySocksInfo(sslSocksInfo *si)
-{
- if (si) {
- PORT_Memset(si, 0x2f, sizeof *si);
- PORT_Free(si);
- }
-}
-
-/* Sets the global variable ourHost to the IP address returned from
- * calling GetHostByName on our system's name.
- * Called from SSL_ReadSocksConfFile().
- */
-static SECStatus
-GetOurHost(void)
-{
- PRStatus rv;
- PRHostEnt hpbuf;
- char name[100];
- char dbbuf[PR_NETDB_BUF_SIZE];
-
- PR_GetSystemInfo(PR_SI_HOSTNAME, name, sizeof name);
-
- rv = PR_GetHostByName(name, dbbuf, sizeof dbbuf, &hpbuf);
- if (rv != PR_SUCCESS)
- return SECFailure;
-
-#undef h_addr
-#define h_addr h_addr_list[0] /* address, in network byte order. */
-
- PORT_Memcpy(&ourHost, hpbuf.h_addr, hpbuf.h_length);
- return SECSuccess;
-}
-
-/*
-** Setup default SocksConfItem list so that loopback is direct, things to the
-** same subnet (?) address are direct, everything else uses sockd
-*/
-static void
-BuildDefaultConfList(void)
-{
- SocksConfItem *ci;
- SocksConfItem **lp;
-
- /* Put loopback onto direct list */
- lp = &ssl_socks_confs;
- ci = (SocksConfItem*) PORT_ZAlloc(sizeof(SocksConfItem));
- if (!ci) {
- return;
- }
- ci->direct = 1;
- ci->daddr = MAKE_IN_ADDR(127,0,0,1);
- ci->dmask = MAKE_IN_ADDR(255,255,255,255);
- ci->op = OP_ALWAYS;
- *lp = ci;
- lp = &ci->next;
-
- /* Put our hosts's subnet onto direct list */
- ci = (SocksConfItem*) PORT_ZAlloc(sizeof(SocksConfItem));
- if (!ci) {
- return;
- }
- ci->direct = 1;
- ci->daddr = ourHost;
- ci->dmask = MAKE_IN_ADDR(255,255,255,0);
- ci->op = OP_ALWAYS;
- *lp = ci;
- lp = &ci->next;
-
- /* Everything else goes to sockd */
- ci = (SocksConfItem*) PORT_ZAlloc(sizeof(SocksConfItem));
- if (!ci) {
- return;
- }
- ci->daddr = MAKE_IN_ADDR(255,255,255,255);
- ci->op = OP_ALWAYS;
- *lp = ci;
-}
-
-static int
-FragmentLine(char *cp, char **argv, int maxargc)
-{
- int argc = 0;
- char *save;
- char ch;
-
- save = cp;
- for (; (ch = *cp) != 0; cp++) {
- if ((ch == '#') || (ch == '\n')) {
- /* Done */
- break;
- }
- if (ch == ':') {
- break;
- }
- if ((ch == ' ') || (ch == '\t')) {
- /* Seperator. see if it seperated anything */
- if (cp - save > 0) {
- /* Put a null at the end of the word */
- *cp = 0;
- argc++;
- *argv++ = save;
- SSL_TRC(20, ("%d: SSL: argc=%d word=\"%s\"",
- SSL_GETPID(), argc, save));
- if (argc == maxargc) {
- return argc;
- }
- }
- save = cp + 1;
- }
- }
- if (cp - save > 0) {
- *cp = 0;
- argc++;
- *argv = save;
- SSL_TRC(20, ("%d: SSL: argc=%d word=\"%s\"",
- SSL_GETPID(), argc, save));
- }
- return argc;
-}
-
-/* XXX inet_addr? */
-static char *
-ConvertOne(char *cp, unsigned char *rvp)
-{
- char *s = PORT_Strchr(cp, '.');
- if (s) {
- *s = 0;
- }
- *rvp = PORT_Atoi(cp) & 0xff;
- return s ? s+1 : cp;
-}
-
-/* returns host address in network byte order. */
-static PRUint32
-ConvertAddr(char *buf)
-{
- unsigned char b0, b1, b2, b3;
- PRUint32 addr;
-
- buf = ConvertOne(buf, &b0);
- buf = ConvertOne(buf, &b1);
- buf = ConvertOne(buf, &b2);
- buf = ConvertOne(buf, &b3);
- addr = ((PRUint32)b0 << 24) |
- ((PRUint32)b1 << 16) |
- ((PRUint32)b2 << 8) |
- (PRUint32)b3; /* host byte order. */
-
- return PR_htonl(addr); /* network byte order. */
-}
-
-static char *
-ReadLine(char *buf, int len, PRFileDesc *fd)
-{
- char c, *p = buf;
- PRInt32 n;
-
- while(len > 0) {
- n = PR_Read(fd, &c, 1);
- if (n < 0)
- return NULL;
- if (n == 0) {
- if (p == buf) {
- return NULL;
- }
- *p = '\0';
- return buf;
- }
- if (c == '\n') {
- *p = '\0';
- return buf;
- }
- *p++ = c;
- len--;
- }
- *p = '\0';
- return buf;
-}
-
-int
-SSL_ReadSocksConfFile(PRFileDesc *fp)
-{
- SocksConfItem * ci;
- SocksConfItem **lp;
- char * file = "socks file"; /* XXX Move to nav */
- SocksOp op;
- int direct;
- int port = 0;
- int lineNumber = 0;
- int rv = GetOurHost();
-
- if (rv < 0) {
- /* If we can't figure out our host id, use socks. Loser! */
- return SECFailure;
- }
-
-#if 0 /* XXX Move to nav */
- fp = XP_FileOpen(file, xpSocksConfig, XP_FILE_READ);
-#endif
- if (!fp) {
- BuildDefaultConfList();
- return SECSuccess;
- }
-
- /* Parse config file and generate config item list */
- lp = &ssl_socks_confs;
- for (;;) {
- char * s;
- char * argv[10];
- int argc;
- PRUint32 daddr;
- PRUint32 dmask;
- char buf[1000];
-
- s = ReadLine(buf, sizeof buf, fp);
- if (!s) {
- break;
- }
- lineNumber++;
- argc = FragmentLine(buf, argv, 10);
- if (argc < 3) {
- if (argc == 0) {
- /* must be a comment/empty line */
- continue;
- }
-#ifdef XP_UNIX
- PR_fprintf(PR_STDERR, "%s:%d: bad config line\n",
- file, lineNumber);
-#endif
- continue;
- }
- if (PORT_Strcmp(argv[0], "direct") == 0) {
- direct = 1;
- } else if (PORT_Strcmp(argv[0], "sockd") == 0) {
- direct = 0;
- } else {
-#ifdef XP_UNIX
- PR_fprintf(PR_STDERR, "%s:%d: bad command: \"%s\"\n",
- file, lineNumber, argv[0]);
-#endif
- continue;
- }
-
- /* Look for port spec */
- op = OP_ALWAYS;
- if (argc > 4) {
- if (PORT_Strcmp(argv[3], "lt") == 0) {
- op = OP_LESS;
- } else if (PORT_Strcmp(argv[3], "eq") == 0) {
- op = OP_EQUAL;
- } else if (PORT_Strcmp(argv[3], "le") == 0) {
- op = OP_LEQUAL;
- } else if (PORT_Strcmp(argv[3], "gt") == 0) {
- op = OP_GREATER;
- } else if (PORT_Strcmp(argv[3], "neq") == 0) {
- op = OP_NOTEQUAL;
- } else if (PORT_Strcmp(argv[3], "ge") == 0) {
- op = OP_GEQUAL;
- } else {
-#ifdef XP_UNIX
- PR_fprintf(PR_STDERR, "%s:%d: bad comparison op: \"%s\"\n",
- file, lineNumber, argv[3]);
-#endif
- continue;
- }
- port = PORT_Atoi(argv[4]);
- }
-
- ci = (SocksConfItem*) PORT_ZAlloc(sizeof(SocksConfItem));
- if (!ci) {
- break;
- }
- daddr = ConvertAddr(argv[1]); /* net byte order. */
- dmask = ConvertAddr(argv[2]); /* net byte order. */
- ci->daddr = daddr; /* net byte order. */
- ci->dmask = dmask; /* net byte order. */
- ci->direct = direct;
- ci->op = op;
- ci->port = port; /* host byte order. */
- daddr = PR_ntohl(daddr); /* host byte order. */
- dmask = PR_ntohl(dmask); /* host byte order. */
- SSL_TRC(10, (
-"%d: SSL: line=%d direct=%d addr=%d.%d.%d.%d mask=%d.%d.%d.%d op=%d port=%d",
- SSL_GETPID(), lineNumber, ci->direct,
- (daddr >> 24) & 0xff,
- (daddr >> 16) & 0xff,
- (daddr >> 8) & 0xff,
- (daddr >> 0) & 0xff,
- (dmask >> 24) & 0xff,
- (dmask >> 16) & 0xff,
- (dmask >> 8) & 0xff,
- (dmask >> 0) & 0xff,
- ci->op, ci->port));
- *lp = ci;
- lp = &ci->next;
- }
-
-
- if (!ssl_socks_confs) {
- /* Empty file. Fix it for the user */
- BuildDefaultConfList();
- }
- return SECSuccess;
-}
-
-static int
-ChooseAddress(sslSocket *ss, const PRNetAddr *direct)
-{
- PRUint32 dstAddr;
- PRUint16 dstPort;
- SocksConfItem *ci;
- int rv;
-
- if (!ssl_socks_confs) {
- rv = SSL_ReadSocksConfFile(NULL);
- if (rv) {
- return rv;
- }
- }
-
- /*
- ** Scan socks config info and look for a direct match or a force to
- ** use the sockd. Bail on first hit.
- */
- dstAddr = direct->inet.ip;
- dstPort = PR_ntohs(direct->inet.port);
- ci = ssl_socks_confs;
- while (ci) {
- SSL_TRC(10, (
- "%d: SSL[%d]: match, direct=%d daddr=0x%x mask=0x%x op=%d port=%d",
- SSL_GETPID(), ss->fd, ci->direct, PR_ntohl(ci->daddr),
- PR_ntohl(ci->dmask), ci->op, ci->port));
- if ((ci->daddr & ci->dmask) == (dstAddr & ci->dmask)) {
- int portMatch = 0;
- switch (ci->op) {
- case OP_LESS: portMatch = dstPort < ci->port; break;
- case OP_EQUAL: portMatch = dstPort == ci->port; break;
- case OP_LEQUAL: portMatch = dstPort <= ci->port; break;
- case OP_GREATER: portMatch = dstPort > ci->port; break;
- case OP_NOTEQUAL: portMatch = dstPort != ci->port; break;
- case OP_GEQUAL: portMatch = dstPort >= ci->port; break;
- case OP_ALWAYS: portMatch = 1; break;
- }
- if (portMatch) {
- SSL_TRC(10, ("%d: SSL[%d]: socks config match",
- SSL_GETPID(), ss->fd));
- return ci->direct;
- }
- }
- ci = ci->next;
- }
- SSL_TRC(10, ("%d: SSL[%d]: socks config: no match",
- SSL_GETPID(), ss->fd));
- return 0;
-}
-
-/*
-** Find port # and host # of socks daemon. Use info in ss->socks struct
-** when valid. If not valid, try to figure it all out.
-*/
-static int
-FindDaemon(sslSocket *ss, PRNetAddr *out)
-{
- sslSocksInfo *si;
- PRUint32 host; /* network byte order. */
- PRUint16 port; /* host byte order. */
-
- PORT_Assert(ss->socks != 0);
- si = ss->socks;
-
- /* For now, assume we are using the socks daemon */
- host = si->sockdHost;
- port = si->sockdPort;
-#ifdef XP_UNIX
- if (!port) {
- static char firstTime = 1;
- static PRUint16 sockdPort;
-
- if (firstTime) {
- struct servent *sp;
-
- firstTime = 0;
- sp = getservbyname("socks", "tcp");
- if (sp) {
- sockdPort = sp->s_port;
- } else {
- SSL_TRC(10, ("%d: SSL[%d]: getservbyname of (socks,tcp) fails",
- SSL_GETPID(), ss->fd));
- }
- }
- port = sockdPort;
- }
-#endif
- if (!port) {
- port = DEF_SOCKD_PORT;
- }
- if (host == 0) {
- SSL_TRC(10, ("%d: SSL[%d]: no socks server found",
- SSL_GETPID(), ss->fd));
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
-
- /* We know the ip addr of the socks server */
- out->inet.family = PR_AF_INET;
- out->inet.port = PR_htons(port);
- out->inet.ip = host;
- host = PR_ntohl(host); /* now host byte order. */
- SSL_TRC(10, ("%d: SSL[%d]: socks server at %d.%d.%d.%d:%d",
- SSL_GETPID(), ss->fd,
- (host >> 24) & 0xff,
- (host >> 16) & 0xff,
- (host >> 8) & 0xff,
- (host >> 0) & 0xff,
- port));
- return SECSuccess;
-}
-
-/*
-** Send our desired address and our user name to the socks daemon.
-** cmd is either SOCKS_CONNECT (client) or SOCKS_BIND (server).
-*/
-static int
-SayHello(sslSocket *ss, int cmd, const PRNetAddr *sa, char *user)
-{
- int rv, len;
- unsigned char msg[8];
- PRUint16 port;
- PRUint32 host;
-
- /* Send dst message to sockd */
- port = sa->inet.port;
- host = sa->inet.ip;
- msg[0] = SOCKS_VERSION;
- msg[1] = cmd;
- PORT_Memcpy(msg+2, &port, 2);
- PORT_Memcpy(msg+4, &host, 4);
- SSL_TRC(10, ("%d: SSL[%d]: socks real dest=%d.%d.%d.%d:%d",
- SSL_GETPID(), ss->fd, msg[4], msg[5], msg[6], msg[7],
- port));
-
- rv = ssl_DefSend(ss, msg, sizeof(msg), 0);
- if (rv < 0) {
- goto io_error;
- }
- /* XXX Deal with short write !! */
-
- /* Send src-user message to sockd */
- len = strlen(user)+1;
- rv = ssl_DefSend(ss, (unsigned char *)user, len, 0);
- if (rv < 0) {
- goto io_error;
- }
- /* XXX Deal with short write !! */
-
- return SECSuccess;
-
- io_error:
- SSL_TRC(10, ("%d: SSL[%d]: socks, io error saying hello to sockd errno=%d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- return SECFailure;
-}
-
-/* Handle the reply from the socks proxy/daemon.
-** Called from ssl_Do1stHandshake().
-*/
-static SECStatus
-SocksHandleReply(sslSocket *ss)
-{
- unsigned char *msg;
- unsigned char cmd;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
-
- ssl_GetRecvBufLock(ss);
- PORT_Assert(ss->gather != 0);
-
- msg = ss->gather->buf.buf;
- cmd = msg[1];
- SSL_TRC(10, ("%d: SSL[%d]: socks result: cmd=%d",
- SSL_GETPID(), ss->fd, cmd));
-
- /* This is Bogus. The socks spec says these fields are undefined in
- * the reply from the socks daemon/proxy. No point in saving garbage.
- */
- PORT_Memcpy(&ss->socks->destPort, msg+2, 2);
- PORT_Memcpy(&ss->socks->destHost, msg+4, 4);
-
- ss->gather->recordLen = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- /* Check status back from sockd */
- switch (cmd) {
- case SOCKS_FAIL:
- case SOCKS_NO_IDENTD:
- case SOCKS_BAD_ID:
- SSL_DBG(("%d: SSL[%d]: sockd returns an error: %d",
- SSL_GETPID(), ss->fd, cmd));
- PORT_SetError(PR_CONNECT_REFUSED_ERROR);
- return SECFailure;
-
- default:
- break;
- }
-
- /* All done */
- SSL_TRC(1, ("%d: SSL[%d]: using sockd at %d.%d.%d.%d",
- SSL_GETPID(), ss->fd,
- (PR_ntohl(ss->socks->sockdHost) >> 24) & 0xff,
- (PR_ntohl(ss->socks->sockdHost) >> 16) & 0xff,
- (PR_ntohl(ss->socks->sockdHost) >> 8) & 0xff,
- (PR_ntohl(ss->socks->sockdHost) >> 0) & 0xff));
- ss->handshake = 0;
- ss->nextHandshake = 0;
- return SECSuccess;
-}
-
-static SECStatus
-SocksGatherRecord(sslSocket *ss)
-{
- int rv;
-
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- ssl_GetRecvBufLock(ss);
- rv = ssl2_GatherRecord(ss, 0);
- ssl_ReleaseRecvBufLock(ss);
- if (rv <= 0) {
- if (rv == 0)
- /* Unexpected EOF */
- PORT_SetError(PR_END_OF_FILE_ERROR);
- return SECFailure;
- }
- ss->handshake = 0;
- return SECSuccess;
-}
-
-static SECStatus
-SocksStartGather(sslSocket *ss)
-{
- int rv;
-
- ss->handshake = SocksGatherRecord;
- ss->nextHandshake = SocksHandleReply;
- rv = ssl2_StartGatherBytes(ss, ss->gather, 8);
- if (rv <= 0) {
- if (rv == 0) {
- /* Unexpected EOF */
- PORT_SetError(PR_END_OF_FILE_ERROR);
- return SECFailure;
- }
- return (SECStatus)rv;
- }
- ss->handshake = 0;
- return SECSuccess;
-}
-
-/************************************************************************/
-
-
-/* BSDI ain't got no cuserid() */
-#ifdef __386BSD__
-#include <pwd.h>
-char *
-bsdi_cuserid(char *b)
-{
- struct passwd *pw = getpwuid(getuid());
-
- if (!b)
- return pw ? pw->pw_name : NULL;
-
- if (!pw || !pw->pw_name)
- b[0] = '\0';
- else
- strcpy(b, pw->pw_name);
- return b;
-}
-#endif
-
-
-/* sa identifies the server to which we want to connect.
- * First determine whether or not to use socks.
- * If not, connect directly to server.
- * If so, connect to socks proxy, and send SOCKS_CONNECT cmd, but
- * Does NOT wait for reply from socks proxy.
- */
-int
-ssl_SocksConnect(sslSocket *ss, const PRNetAddr *sa)
-{
- int rv, err, direct;
- PRNetAddr daemon;
- const PRNetAddr *sip;
- char *user;
- PRFileDesc *osfd = ss->fd->lower;
-
- /* Figure out where to connect to */
- rv = FindDaemon(ss, &daemon);
- if (rv) {
- return SECFailure;
- }
- direct = ChooseAddress(ss, sa);
- if (direct) {
- sip = sa;
- ss->socks->direct = 1;
- } else {
- sip = &daemon;
- ss->socks->direct = 0;
- }
- SSL_TRC(10, ("%d: SSL[%d]: socks %s connect to %d.%d.%d.%d:%d",
- SSL_GETPID(), ss->fd,
- direct ? "direct" : "sockd",
- (PR_ntohl(sip->inet.ip) >> 24) & 0xff,
- (PR_ntohl(sip->inet.ip) >> 16) & 0xff,
- (PR_ntohl(sip->inet.ip) >> 8) & 0xff,
- PR_ntohl(sip->inet.ip) & 0xff,
- PR_ntohs(sip->inet.port)));
-
- /* Attempt first connection */
- rv = osfd->methods->connect(osfd, sip, ss->cTimeout);
- err = PORT_GetError();
-#ifdef _WIN32
- PR_Sleep(PR_INTERVAL_NO_WAIT); /* workaround NT winsock connect bug. */
-#endif
- if (rv < 0) {
- if (err != PR_IS_CONNECTED_ERROR) {
- return rv;
- }
- /* Async connect finished */
- }
-
- /* If talking to sockd, do handshake */
- if (!direct) {
- /* Find user */
-#ifdef XP_UNIX
-#ifdef __386BSD__
- user = bsdi_cuserid(NULL);
-#else
- user = cuserid(NULL);
-#endif
- if (!user) {
- PORT_SetError(PR_UNKNOWN_ERROR);
- SSL_DBG(("%d: SSL[%d]: cuserid fails, errno=%d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- return SECFailure;
- }
-#else
- user = "SSL";
-#endif
-
- /* Send our message to it */
- rv = SayHello(ss, SOCKS_CONNECT, sa, user);
- if (rv) {
- return rv;
- }
-
- ss->handshake = SocksStartGather;
- ss->nextHandshake = 0;
-
- /* save up who we're really talking to so we can index the cache */
- ss->peer = sa->inet.ip;
- ss->port = sa->inet.port;
- }
- return 0;
-}
-
-/* Called from ssl_SocksBind(), SSL_BindForSockd(), and ssl_SocksAccept().
- * NOT called from ssl_SocksConnect().
- */
-static int
-SocksWaitForResponse(sslSocket *ss)
-{
- int rv;
-
- ss->handshake = SocksStartGather;
- ss->nextHandshake = 0;
-
- /* Get response. Do it now, spinning if necessary (!) */
- for (;;) {
- ssl_Get1stHandshakeLock(ss);
- rv = ssl_Do1stHandshake(ss);
- ssl_Release1stHandshakeLock(ss);
- if (rv == SECWouldBlock ||
- (rv == SECFailure && PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
-#ifdef XP_UNIX
- /*
- ** Spinning is really evil under unix. Call select and
- ** continue when a read select returns true. We only get
- ** here if the socket was marked async before the bind
- ** call.
- */
- PRPollDesc spin;
- spin.fd = ss->fd->lower;
- spin.in_flags = PR_POLL_READ;
- rv = PR_Poll(&spin, 1, PR_INTERVAL_NO_TIMEOUT);
- if (rv < 0) {
- return rv;
- }
-#else
- PRIntervalTime ticks = PR_MillisecondsToInterval(1);
- PR_Sleep(ticks);
-#endif
- continue;
- }
- break;
- }
- return rv;
-}
-
-/* sa identifies the server address we want to bind to.
- * First, determine if we need to register with a socks proxy.
- * If socks, then Connect to Socks proxy daemon, send SOCKS_BIND message,
- * wait for response from socks proxy.
- */
-int
-ssl_SocksBind(sslSocket *ss, const PRNetAddr *sa)
-{
- sslSocksInfo * si;
- PRFileDesc * osfd = ss->fd->lower;
- char * user;
- int rv;
- int direct;
- PRNetAddr daemon;
-
- PORT_Assert(ss->socks != 0);
- si = ss->socks;
-
- /* Figure out where to connect to */
- rv = FindDaemon(ss, &daemon);
- if (rv) {
- return SECFailure;
- }
- direct = ChooseAddress(ss, sa);
- if (direct) {
- ss->socks->direct = 1;
- rv = osfd->methods->bind(osfd, sa);
- PORT_Memcpy(&ss->socks->bindAddr, sa, sizeof(PRNetAddr));
- } else {
- ss->socks->direct = 0;
- SSL_TRC(10, ("%d: SSL[%d]: socks sockd bind to %d.%d.%d.%d:%d",
- SSL_GETPID(), ss->fd,
- (PR_ntohl(daemon.inet.ip) >> 24) & 0xff,
- (PR_ntohl(daemon.inet.ip) >> 16) & 0xff,
- (PR_ntohl(daemon.inet.ip) >> 8) & 0xff,
- PR_ntohl(daemon.inet.ip) & 0xff,
- PR_ntohs(daemon.inet.port)));
-
- /* First connect to socks daemon. ASYNC connects must be disabled! */
- rv = osfd->methods->connect(osfd, &daemon, ss->cTimeout);
- if (rv < 0) {
- return rv;
- }
-
- /* Find user */
-#ifdef XP_UNIX
-#ifdef __386BSD__
- user = bsdi_cuserid(NULL);
-#else
- user = cuserid(NULL);
-#endif
- if (!user) {
- SSL_DBG(("%d: SSL[%d]: cuserid fails, errno=%d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- PORT_SetError(PR_UNKNOWN_ERROR);
- return SECFailure;
- }
-#else
- user = "SSL";
-#endif
- /* Send message to sockd */
- rv = SayHello(ss, SOCKS_BIND, sa, user);
- if (rv) {
- return rv;
- }
-
- /* SocksGatherRecord up bind response from sockd */
- rv = SocksWaitForResponse(ss);
- if (rv == 0) {
- /* Done */
- si->bindAddr.inet.family = PR_AF_INET;
- si->bindAddr.inet.port = si->destPort;
- if (PR_ntohl(si->destHost) == PR_INADDR_ANY) {
- si->bindAddr.inet.ip = daemon.inet.ip;
- } else {
- si->bindAddr.inet.ip = si->destHost;
- }
- }
- }
- si->didBind = 1;
- return rv;
-}
-
-
-PRFileDesc *
-ssl_SocksAccept(sslSocket *ss, PRNetAddr *addr)
-{
- PORT_Assert(0);
-#if 0 /* XXX This doesn't work. */
- sslSocket *ns;
- sslSocksInfo *si;
- PRFileDesc *fd, *osfd = ss->fd->lower;
- int rv;
-
- PORT_Assert(ss->socks != 0);
- si = ss->socks;
-
- if (!si->didBind || si->direct) {
- /*
- ** If we didn't do the bind yet this call will generate an error
- ** from the OS. If we did do the bind then we must be direct and
- ** let the OS do the accept.
- */
- fd = osfd->methods->accept(osfd, addr, ss->cTimeout);
- return NULL;
- }
-
- /* Get next accept response from server */
- rv = SocksWaitForResponse(ss);
- if (rv) {
- return NULL;
- }
-
- /* Handshake finished. Give dest address back to caller */
- addr->inet.family = PR_AF_INET;
- addr->inet.port = si->destPort;
- addr->inet.ip = si->destHost;
-
- /* Dup the descriptor and return it */
- fd = osfd->methods->dup(osfd);
- if (fd == NULL) {
- return NULL;
- }
-
- /* Dup the socket structure */
- ns = ssl_DupSocket(ss, fd);
- if (ns == NULL) {
- PR_Close(fd);
- return NULL;
- }
-
- return fd;
-#else
- return NULL;
-#endif /* 0 */
-}
-
-int
-ssl_SocksListen(sslSocket *ss, int backlog)
-{
- PRFileDesc *osfd = ss->fd->lower;
- int rv;
-
- PORT_Assert(ss->socks != 0);
-
- if (ss->socks->direct) {
- rv = osfd->methods->listen(osfd, backlog);
- return rv;
- }
- return 0;
-}
-
-int
-ssl_SocksGetsockname(sslSocket *ss, PRNetAddr *name)
-{
- PRFileDesc *osfd = ss->fd->lower;
- int rv;
-
- PORT_Assert(ss->socks != 0);
- if (!ss->socks->didBind || ss->socks->direct) {
- rv = osfd->methods->getsockname(osfd, name);
- return rv;
- }
-
- PORT_Memcpy(name, &ss->socks->bindAddr, sizeof(PRNetAddr));
- return 0;
-}
-
-int
-ssl_SocksRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
-{
- int rv;
-
- PORT_Assert(ss->socks != 0);
-
- if (ss->handshake) {
- ssl_Get1stHandshakeLock(ss);
- rv = ssl_Do1stHandshake(ss);
- ssl_Release1stHandshakeLock(ss);
- if (rv < 0) {
- return rv;
- }
- rv = ssl_SendSavedWriteData(ss, &ss->saveBuf, ssl_DefSend);
- if (rv < 0) {
- return SECFailure;
- }
- /* XXX Deal with short write !! */
- }
-
- rv = ssl_DefRecv(ss, buf, len, flags);
- SSL_TRC(2, ("%d: SSL[%d]: recving %d bytes from sockd",
- SSL_GETPID(), ss->fd, rv));
- return rv;
-}
-
-int
-ssl_SocksRead(sslSocket *ss, unsigned char *buf, int len)
-{
- return ssl_SocksRecv(ss, buf, len, 0);
-}
-
-int
-ssl_SocksSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
-{
- int rv;
-
- PORT_Assert(ss->socks != 0);
-
- if (len == 0)
- return 0;
- if (ss->handshake) {
- ssl_Get1stHandshakeLock(ss);
- rv = ssl_Do1stHandshake(ss);
- ssl_Release1stHandshakeLock(ss);
- if (rv < 0) {
- if (rv == SECWouldBlock) {
- return len; /* ????? XXX */
- }
- return rv;
- }
- rv = ssl_SendSavedWriteData(ss, &ss->saveBuf, ssl_DefSend);
- if (rv < 0) {
- return SECFailure;
- }
- /* XXX Deal with short write !! */
- }
-
- SSL_TRC(2, ("%d: SSL[%d]: sending %d bytes using socks",
- SSL_GETPID(), ss->fd, len));
-
- /* Send out the data */
- rv = ssl_DefSend(ss, buf, len, flags);
- /* XXX Deal with short write !! */
- return rv;
-}
-
-int
-ssl_SocksWrite(sslSocket *ss, const unsigned char *buf, int len)
-{
- return ssl_SocksSend(ss, buf, len, 0);
-}
-
-/* returns > 0 if direct
- * returns == 0 if socks
- * returns < 0 if error.
- */
-int
-SSL_CheckDirectSock(PRFileDesc *s)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(s);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in CheckDirectSock", SSL_GETPID(), s));
- return SECFailure;
- }
-
- if (ss->socks != NULL) {
- return ss->socks->direct;
- }
- return SECFailure;
-}
-
-
-SECStatus
-SSL_ConfigSockd(PRFileDesc *s, PRUint32 host, PRUint16 port)
-{
- sslSocket *ss;
- SECStatus rv;
-
- ss = ssl_FindSocket(s);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in ConfigSocks", SSL_GETPID(), s));
- return SECFailure;
- }
-
- /* Create socks info if not already done */
- rv = ssl_CreateSocksInfo(ss);
- if (rv) {
- return rv;
- }
- ss->socks->sockdHost = host;
- ss->socks->sockdPort = port;
- return SECSuccess;
-}
-
diff --git a/security/nss/lib/ssl/ssltrace.c b/security/nss/lib/ssl/ssltrace.c
deleted file mode 100644
index 15f064813..000000000
--- a/security/nss/lib/ssl/ssltrace.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Functions to trace SSL protocol behavior in DEBUG builds.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-#include <stdarg.h>
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "prprf.h"
-
-#if defined(DEBUG) || defined(TRACE)
-static const char *hex = "0123456789abcdef";
-
-static const char printable[257] = {
- "................" /* 0x */
- "................" /* 1x */
- " !\"#$%&'()*+,-./" /* 2x */
- "0123456789:;<=>?" /* 3x */
- "@ABCDEFGHIJKLMNO" /* 4x */
- "PQRSTUVWXYZ[\\]^_" /* 5x */
- "`abcdefghijklmno" /* 6x */
- "pqrstuvwxyz{|}~." /* 7x */
- "................" /* 8x */
- "................" /* 9x */
- "................" /* ax */
- "................" /* bx */
- "................" /* cx */
- "................" /* dx */
- "................" /* ex */
- "................" /* fx */
-};
-
-void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *vp, int len)
-{
- const unsigned char *cp = (const unsigned char *)vp;
- char buf[80];
- char *bp;
- char *ap;
-
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]", SSL_GETPID(), ss->fd,
- msg, len));
- } else {
- SSL_TRACE(("%d: SSL: %s [Len: %d]", SSL_GETPID(), msg, len));
- }
- memset(buf, ' ', sizeof buf);
- bp = buf;
- ap = buf + 50;
- while (--len >= 0) {
- unsigned char ch = *cp++;
- *bp++ = hex[(ch >> 4) & 0xf];
- *bp++ = hex[ch & 0xf];
- *bp++ = ' ';
- *ap++ = printable[ch];
- if (ap - buf >= 66) {
- *ap = 0;
- SSL_TRACE((" %s", buf));
- memset(buf, ' ', sizeof buf);
- bp = buf;
- ap = buf + 50;
- }
- }
- if (bp > buf) {
- *ap = 0;
- SSL_TRACE((" %s", buf));
- }
-}
-
-#define LEN(cp) (((cp)[0] << 8) | ((cp)[1]))
-
-static void PrintType(sslSocket *ss, char *msg)
-{
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: dump-msg: %s", SSL_GETPID(), ss->fd,
- msg));
- } else {
- SSL_TRACE(("%d: SSL: dump-msg: %s", SSL_GETPID(), msg));
- }
-}
-
-static void PrintInt(sslSocket *ss, char *msg, unsigned v)
-{
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: %s=%u", SSL_GETPID(), ss->fd,
- msg, v));
- } else {
- SSL_TRACE(("%d: SSL: %s=%u", SSL_GETPID(), msg, v));
- }
-}
-
-/* PrintBuf is just like ssl_PrintBuf above, except that:
- * a) It prefixes each line of the buffer with "XX: SSL[xxx] "
- * b) It dumps only hex, not ASCII.
- */
-static void PrintBuf(sslSocket *ss, char *msg, unsigned char *cp, int len)
-{
- char buf[80];
- char *bp;
-
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]",
- SSL_GETPID(), ss->fd, msg, len));
- } else {
- SSL_TRACE(("%d: SSL: %s [Len: %d]",
- SSL_GETPID(), msg, len));
- }
- bp = buf;
- while (--len >= 0) {
- unsigned char ch = *cp++;
- *bp++ = hex[(ch >> 4) & 0xf];
- *bp++ = hex[ch & 0xf];
- *bp++ = ' ';
- if (bp + 4 > buf + 50) {
- *bp = 0;
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: %s",
- SSL_GETPID(), ss->fd, buf));
- } else {
- SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf));
- }
- bp = buf;
- }
- }
- if (bp > buf) {
- *bp = 0;
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: %s",
- SSL_GETPID(), ss->fd, buf));
- } else {
- SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf));
- }
- }
-}
-
-void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len)
-{
- switch (bp[0]) {
- case SSL_MT_ERROR:
- PrintType(ss, "Error");
- PrintInt(ss, "error", LEN(bp+1));
- break;
-
- case SSL_MT_CLIENT_HELLO:
- {
- unsigned lcs = LEN(bp+3);
- unsigned ls = LEN(bp+5);
- unsigned lc = LEN(bp+7);
-
- PrintType(ss, "Client-Hello");
-
- PrintInt(ss, "version (Major)", bp[1]);
- PrintInt(ss, "version (minor)", bp[2]);
-
- PrintBuf(ss, "cipher-specs", bp+9, lcs);
- PrintBuf(ss, "session-id", bp+9+lcs, ls);
- PrintBuf(ss, "challenge", bp+9+lcs+ls, lc);
- }
- break;
- case SSL_MT_CLIENT_MASTER_KEY:
- {
- unsigned lck = LEN(bp+4);
- unsigned lek = LEN(bp+6);
- unsigned lka = LEN(bp+8);
-
- PrintType(ss, "Client-Master-Key");
-
- PrintInt(ss, "cipher-choice", bp[1]);
- PrintInt(ss, "key-length", LEN(bp+2));
-
- PrintBuf(ss, "clear-key", bp+10, lck);
- PrintBuf(ss, "encrypted-key", bp+10+lck, lek);
- PrintBuf(ss, "key-arg", bp+10+lck+lek, lka);
- }
- break;
- case SSL_MT_CLIENT_FINISHED:
- PrintType(ss, "Client-Finished");
- PrintBuf(ss, "connection-id", bp+1, len-1);
- break;
- case SSL_MT_SERVER_HELLO:
- {
- unsigned lc = LEN(bp+5);
- unsigned lcs = LEN(bp+7);
- unsigned lci = LEN(bp+9);
-
- PrintType(ss, "Server-Hello");
-
- PrintInt(ss, "session-id-hit", bp[1]);
- PrintInt(ss, "certificate-type", bp[2]);
- PrintInt(ss, "version (Major)", bp[3]);
- PrintInt(ss, "version (minor)", bp[3]);
- PrintBuf(ss, "certificate", bp+11, lc);
- PrintBuf(ss, "cipher-specs", bp+11+lc, lcs);
- PrintBuf(ss, "connection-id", bp+11+lc+lcs, lci);
- }
- break;
- case SSL_MT_SERVER_VERIFY:
- PrintType(ss, "Server-Verify");
- PrintBuf(ss, "challenge", bp+1, len-1);
- break;
- case SSL_MT_SERVER_FINISHED:
- PrintType(ss, "Server-Finished");
- PrintBuf(ss, "session-id", bp+1, len-1);
- break;
- case SSL_MT_REQUEST_CERTIFICATE:
- PrintType(ss, "Request-Certificate");
- PrintInt(ss, "authentication-type", bp[1]);
- PrintBuf(ss, "certificate-challenge", bp+2, len-2);
- break;
- case SSL_MT_CLIENT_CERTIFICATE:
- {
- unsigned lc = LEN(bp+2);
- unsigned lr = LEN(bp+4);
- PrintType(ss, "Client-Certificate");
- PrintInt(ss, "certificate-type", bp[1]);
- PrintBuf(ss, "certificate", bp+6, lc);
- PrintBuf(ss, "response", bp+6+lc, lr);
- }
- break;
- default:
- ssl_PrintBuf(ss, "sending *unknown* message type", bp, len);
- return;
- }
-}
-
-void
-ssl_Trace(const char *format, ... )
-{
- char buf[2000];
-
- va_list args;
- va_start(args, format);
- PR_vsnprintf(buf, sizeof(buf), format, args);
- va_end(args);
- puts(buf);
-}
-#endif
diff --git a/security/nss/lib/ssl/unix_err.c b/security/nss/lib/ssl/unix_err.c
deleted file mode 100644
index f4c4b643b..000000000
--- a/security/nss/lib/ssl/unix_err.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
- * NSPR's functions, instead of duplicating them, but they're private.
- * As long as SSL's server session cache code must do platform native I/O
- * to accomplish its job, and NSPR's error mapping functions remain private,
- * this code will continue to need to be replicated.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#if 0
-#include "primpl.h"
-#else
-#define _PR_POLL_AVAILABLE 1
-#include "prerror.h"
-#endif
-
-#if defined(_PR_POLL_AVAILABLE)
-#include <poll.h>
-#endif
-#include <errno.h>
-
-/* forward declarations. */
-void nss_MD_unix_map_default_error(int err);
-
-void nss_MD_unix_map_opendir_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_closedir_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_BAD_DESCRIPTOR_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_readdir_error(int err)
-{
- PRErrorCode prError;
-
- switch (err) {
- case ENOENT: prError = PR_NO_MORE_FILES_ERROR; break;
-#ifdef EOVERFLOW
- case EOVERFLOW: prError = PR_IO_ERROR; break;
-#endif
- case EINVAL: prError = PR_IO_ERROR; break;
- case ENXIO: prError = PR_IO_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_unlink_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EPERM: prError = PR_IS_DIRECTORY_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_stat_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_fstat_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_rename_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EEXIST: prError = PR_DIRECTORY_NOT_EMPTY_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_access_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_mkdir_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_rmdir_error(int err)
-{
- PRErrorCode prError;
-
- switch (err) {
- case EEXIST: prError = PR_DIRECTORY_NOT_EMPTY_ERROR; break;
- case EINVAL: prError = PR_DIRECTORY_NOT_EMPTY_ERROR; break;
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_read_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_INVALID_METHOD_ERROR; break;
- case ENXIO: prError = PR_INVALID_ARGUMENT_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_write_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_INVALID_METHOD_ERROR; break;
- case ENXIO: prError = PR_INVALID_METHOD_ERROR; break;
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_lseek_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_fsync_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- case EINVAL: prError = PR_INVALID_METHOD_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_close_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_socket_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_socketavailable_error(int err)
-{
- PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
-}
-
-void nss_MD_unix_map_recv_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_recvfrom_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_send_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_sendto_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_writev_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_accept_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ENODEV: prError = PR_NOT_TCP_SOCKET_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_connect_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EACCES: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
-#if defined(UNIXWARE) || defined(SNI) || defined(NEC)
- /*
- * On some platforms, if we connect to a port on the local host
- * (the loopback address) that no process is listening on, we get
- * EIO instead of ECONNREFUSED.
- */
- case EIO: prError = PR_CONNECT_REFUSED_ERROR; break;
-#endif
- case ELOOP: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ENOENT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ENXIO: prError = PR_IO_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_bind_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; break;
- /*
- * UNIX domain sockets are not supported in NSPR
- */
- case EIO: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case EISDIR: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ELOOP: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ENOENT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ENOTDIR: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case EROFS: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_listen_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_shutdown_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_socketpair_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_getsockname_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_getpeername_error(int err)
-{
- PRErrorCode prError;
-
- switch (err) {
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_getsockopt_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_BUFFER_OVERFLOW_ERROR; break;
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_setsockopt_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_BUFFER_OVERFLOW_ERROR; break;
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_open_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EAGAIN: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case EBUSY: prError = PR_IO_ERROR; break;
- case ENODEV: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_mmap_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EAGAIN: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case EMFILE: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case ENODEV: prError = PR_OPERATION_NOT_SUPPORTED_ERROR; break;
- case ENXIO: prError = PR_INVALID_ARGUMENT_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_gethostname_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_select_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-#ifdef _PR_POLL_AVAILABLE
-void nss_MD_unix_map_poll_error(int err)
-{
- PRErrorCode prError;
-
- switch (err) {
- case EAGAIN: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_poll_revents_error(int err)
-{
- if (err & POLLNVAL)
- PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
- else if (err & POLLHUP)
- PR_SetError(PR_CONNECT_RESET_ERROR, EPIPE);
- else if (err & POLLERR)
- PR_SetError(PR_IO_ERROR, EIO);
- else
- PR_SetError(PR_UNKNOWN_ERROR, err);
-}
-#endif /* _PR_POLL_AVAILABLE */
-
-
-void nss_MD_unix_map_flock_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_BAD_DESCRIPTOR_ERROR; break;
- case EWOULDBLOCK: prError = PR_FILE_IS_LOCKED_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_lockf_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EACCES: prError = PR_FILE_IS_LOCKED_ERROR; break;
- case EDEADLK: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-#ifdef HPUX11
-void nss_MD_hpux_map_sendfile_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-#endif /* HPUX11 */
-
-
-void nss_MD_unix_map_default_error(int err)
-{
- PRErrorCode prError;
- switch (err ) {
- case EACCES: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case EADDRINUSE: prError = PR_ADDRESS_IN_USE_ERROR; break;
- case EADDRNOTAVAIL: prError = PR_ADDRESS_NOT_AVAILABLE_ERROR; break;
- case EAFNOSUPPORT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case EAGAIN: prError = PR_WOULD_BLOCK_ERROR; break;
- case EALREADY: prError = PR_ALREADY_INITIATED_ERROR; break;
- case EBADF: prError = PR_BAD_DESCRIPTOR_ERROR; break;
-#ifdef EBADMSG
- case EBADMSG: prError = PR_IO_ERROR; break;
-#endif
- case EBUSY: prError = PR_FILESYSTEM_MOUNTED_ERROR; break;
- case ECONNREFUSED: prError = PR_CONNECT_REFUSED_ERROR; break;
- case ECONNRESET: prError = PR_CONNECT_RESET_ERROR; break;
- case EDEADLK: prError = PR_DEADLOCK_ERROR; break;
-#ifdef EDIRCORRUPTED
- case EDIRCORRUPTED: prError = PR_DIRECTORY_CORRUPTED_ERROR; break;
-#endif
-#ifdef EDQUOT
- case EDQUOT: prError = PR_NO_DEVICE_SPACE_ERROR; break;
-#endif
- case EEXIST: prError = PR_FILE_EXISTS_ERROR; break;
- case EFAULT: prError = PR_ACCESS_FAULT_ERROR; break;
- case EFBIG: prError = PR_FILE_TOO_BIG_ERROR; break;
- case EINPROGRESS: prError = PR_IN_PROGRESS_ERROR; break;
- case EINTR: prError = PR_PENDING_INTERRUPT_ERROR; break;
- case EINVAL: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case EIO: prError = PR_IO_ERROR; break;
- case EISCONN: prError = PR_IS_CONNECTED_ERROR; break;
- case EISDIR: prError = PR_IS_DIRECTORY_ERROR; break;
- case ELOOP: prError = PR_LOOP_ERROR; break;
- case EMFILE: prError = PR_PROC_DESC_TABLE_FULL_ERROR; break;
- case EMLINK: prError = PR_MAX_DIRECTORY_ENTRIES_ERROR; break;
- case EMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
-#ifdef EMULTIHOP
- case EMULTIHOP: prError = PR_REMOTE_FILE_ERROR; break;
-#endif
- case ENAMETOOLONG: prError = PR_NAME_TOO_LONG_ERROR; break;
- case ENETUNREACH: prError = PR_NETWORK_UNREACHABLE_ERROR; break;
- case ENFILE: prError = PR_SYS_DESC_TABLE_FULL_ERROR; break;
-#if !defined(SCO)
- case ENOBUFS: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
-#endif
- case ENODEV: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case ENOENT: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case ENOLCK: prError = PR_FILE_IS_LOCKED_ERROR; break;
-#ifdef ENOLINK
- case ENOLINK: prError = PR_REMOTE_FILE_ERROR; break;
-#endif
- case ENOMEM: prError = PR_OUT_OF_MEMORY_ERROR; break;
- case ENOPROTOOPT: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case ENOSPC: prError = PR_NO_DEVICE_SPACE_ERROR; break;
- case ENOSR: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case ENOTCONN: prError = PR_NOT_CONNECTED_ERROR; break;
- case ENOTDIR: prError = PR_NOT_DIRECTORY_ERROR; break;
- case ENOTSOCK: prError = PR_NOT_SOCKET_ERROR; break;
- case ENXIO: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case EOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
-#ifdef EOVERFLOW
- case EOVERFLOW: prError = PR_BUFFER_OVERFLOW_ERROR; break;
-#endif
- case EPERM: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case EPIPE: prError = PR_CONNECT_RESET_ERROR; break;
-#ifdef EPROTO
- case EPROTO: prError = PR_IO_ERROR; break;
-#endif
- case EPROTONOSUPPORT: prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR; break;
- case EPROTOTYPE: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ERANGE: prError = PR_INVALID_METHOD_ERROR; break;
- case EROFS: prError = PR_READ_ONLY_FILESYSTEM_ERROR; break;
- case ESPIPE: prError = PR_INVALID_METHOD_ERROR; break;
- case ETIMEDOUT: prError = PR_IO_TIMEOUT_ERROR; break;
-#if EWOULDBLOCK != EAGAIN
- case EWOULDBLOCK: prError = PR_WOULD_BLOCK_ERROR; break;
-#endif
- case EXDEV: prError = PR_NOT_SAME_DEVICE_ERROR; break;
-
- default: prError = PR_UNKNOWN_ERROR; break;
- }
- PR_SetError(prError, err);
-}
diff --git a/security/nss/lib/ssl/unix_err.h b/security/nss/lib/ssl/unix_err.h
deleted file mode 100644
index 2611baf81..000000000
--- a/security/nss/lib/ssl/unix_err.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
- * NSPR's functions, instead of duplicating them, but they're private.
- * As long as SSL's server session cache code must do platform native I/O
- * to accomplish its job, and NSPR's error mapping functions remain private,
- * this code will continue to need to be replicated.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-/* NSPR doesn't make these functions public, so we have to duplicate
-** them in NSS.
-*/
-extern void nss_MD_hpux_map_sendfile_error(int err);
-extern void nss_MD_unix_map_accept_error(int err);
-extern void nss_MD_unix_map_access_error(int err);
-extern void nss_MD_unix_map_bind_error(int err);
-extern void nss_MD_unix_map_close_error(int err);
-extern void nss_MD_unix_map_closedir_error(int err);
-extern void nss_MD_unix_map_connect_error(int err);
-extern void nss_MD_unix_map_default_error(int err);
-extern void nss_MD_unix_map_flock_error(int err);
-extern void nss_MD_unix_map_fstat_error(int err);
-extern void nss_MD_unix_map_fsync_error(int err);
-extern void nss_MD_unix_map_gethostname_error(int err);
-extern void nss_MD_unix_map_getpeername_error(int err);
-extern void nss_MD_unix_map_getsockname_error(int err);
-extern void nss_MD_unix_map_getsockopt_error(int err);
-extern void nss_MD_unix_map_listen_error(int err);
-extern void nss_MD_unix_map_lockf_error(int err);
-extern void nss_MD_unix_map_lseek_error(int err);
-extern void nss_MD_unix_map_mkdir_error(int err);
-extern void nss_MD_unix_map_mmap_error(int err);
-extern void nss_MD_unix_map_open_error(int err);
-extern void nss_MD_unix_map_opendir_error(int err);
-extern void nss_MD_unix_map_poll_error(int err);
-extern void nss_MD_unix_map_poll_revents_error(int err);
-extern void nss_MD_unix_map_read_error(int err);
-extern void nss_MD_unix_map_readdir_error(int err);
-extern void nss_MD_unix_map_recv_error(int err);
-extern void nss_MD_unix_map_recvfrom_error(int err);
-extern void nss_MD_unix_map_rename_error(int err);
-extern void nss_MD_unix_map_rmdir_error(int err);
-extern void nss_MD_unix_map_select_error(int err);
-extern void nss_MD_unix_map_send_error(int err);
-extern void nss_MD_unix_map_sendto_error(int err);
-extern void nss_MD_unix_map_setsockopt_error(int err);
-extern void nss_MD_unix_map_shutdown_error(int err);
-extern void nss_MD_unix_map_socket_error(int err);
-extern void nss_MD_unix_map_socketavailable_error(int err);
-extern void nss_MD_unix_map_socketpair_error(int err);
-extern void nss_MD_unix_map_stat_error(int err);
-extern void nss_MD_unix_map_unlink_error(int err);
-extern void nss_MD_unix_map_write_error(int err);
-extern void nss_MD_unix_map_writev_error(int err);
diff --git a/security/nss/lib/ssl/win32err.c b/security/nss/lib/ssl/win32err.c
deleted file mode 100644
index acfce2c9d..000000000
--- a/security/nss/lib/ssl/win32err.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
- * NSPR's functions, instead of duplicating them, but they're private.
- * As long as SSL's server session cache code must do platform native I/O
- * to accomplish its job, and NSPR's error mapping functions remain private,
- * this code will continue to need to be replicated.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "prerror.h"
-#include "prlog.h"
-#include <errno.h>
-#include <windows.h>
-
-/*
- * On Win32, we map three kinds of error codes:
- * - GetLastError(): for Win32 functions
- * - WSAGetLastError(): for Winsock functions
- * - errno: for standard C library functions
- *
- * We do not check for WSAEINPROGRESS and WSAEINTR because we do not
- * use blocking Winsock 1.1 calls.
- *
- * Except for the 'socket' call, we do not check for WSAEINITIALISED.
- * It is assumed that if Winsock is not initialized, that fact will
- * be detected at the time we create new sockets.
- */
-
-/* forward declaration. */
-void nss_MD_win32_map_default_error(PRInt32 err);
-
-void nss_MD_win32_map_opendir_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_closedir_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_readdir_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_delete_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-/* The error code for stat() is in errno. */
-void nss_MD_win32_map_stat_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_fstat_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_rename_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-/* The error code for access() is in errno. */
-void nss_MD_win32_map_access_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_mkdir_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_rmdir_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_read_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_transmitfile_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_write_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_lseek_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_fsync_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-/*
- * For both CloseHandle() and closesocket().
- */
-void nss_MD_win32_map_close_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_socket_error(PRInt32 err)
-{
- PR_ASSERT(err != WSANOTINITIALISED);
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_recv_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_recvfrom_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_send_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_sendto_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_accept_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
- case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_acceptex_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_connect_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEWOULDBLOCK: prError = PR_IN_PROGRESS_ERROR; break;
- case WSAEINVAL: prError = PR_ALREADY_INITIATED_ERROR; break;
- case WSAETIMEDOUT: prError = PR_IO_TIMEOUT_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_bind_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEINVAL: prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_listen_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
- case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_shutdown_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_getsockname_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_getpeername_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_getsockopt_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_setsockopt_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_open_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_gethostname_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-/* Win32 select() only works on sockets. So in this
-** context, WSAENOTSOCK is equivalent to EBADF on Unix.
-*/
-void nss_MD_win32_map_select_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAENOTSOCK: prError = PR_BAD_DESCRIPTOR_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_lockf_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-
-
-void nss_MD_win32_map_default_error(PRInt32 err)
-{
- PRErrorCode prError;
-
- switch (err) {
- case EACCES: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case ENOENT: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case ERROR_ACCESS_DENIED: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case ERROR_ALREADY_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
- case ERROR_DISK_CORRUPT: prError = PR_IO_ERROR; break;
- case ERROR_DISK_FULL: prError = PR_NO_DEVICE_SPACE_ERROR; break;
- case ERROR_DISK_OPERATION_FAILED: prError = PR_IO_ERROR; break;
- case ERROR_DRIVE_LOCKED: prError = PR_FILE_IS_LOCKED_ERROR; break;
- case ERROR_FILENAME_EXCED_RANGE: prError = PR_NAME_TOO_LONG_ERROR; break;
- case ERROR_FILE_CORRUPT: prError = PR_IO_ERROR; break;
- case ERROR_FILE_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
- case ERROR_FILE_INVALID: prError = PR_BAD_DESCRIPTOR_ERROR; break;
-#if ERROR_FILE_NOT_FOUND != ENOENT
- case ERROR_FILE_NOT_FOUND: prError = PR_FILE_NOT_FOUND_ERROR; break;
-#endif
- case ERROR_HANDLE_DISK_FULL: prError = PR_NO_DEVICE_SPACE_ERROR; break;
- case ERROR_INVALID_ADDRESS: prError = PR_ACCESS_FAULT_ERROR; break;
- case ERROR_INVALID_HANDLE: prError = PR_BAD_DESCRIPTOR_ERROR; break;
- case ERROR_INVALID_NAME: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case ERROR_INVALID_PARAMETER: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case ERROR_INVALID_USER_BUFFER: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case ERROR_LOCKED: prError = PR_FILE_IS_LOCKED_ERROR; break;
- case ERROR_NETNAME_DELETED: prError = PR_CONNECT_RESET_ERROR; break;
- case ERROR_NOACCESS: prError = PR_ACCESS_FAULT_ERROR; break;
- case ERROR_NOT_ENOUGH_MEMORY: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case ERROR_NOT_ENOUGH_QUOTA: prError = PR_OUT_OF_MEMORY_ERROR; break;
- case ERROR_NOT_READY: prError = PR_IO_ERROR; break;
- case ERROR_NO_MORE_FILES: prError = PR_NO_MORE_FILES_ERROR; break;
- case ERROR_OPEN_FAILED: prError = PR_IO_ERROR; break;
- case ERROR_OPEN_FILES: prError = PR_IO_ERROR; break;
- case ERROR_OUTOFMEMORY: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case ERROR_PATH_BUSY: prError = PR_IO_ERROR; break;
- case ERROR_PATH_NOT_FOUND: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case ERROR_SEEK_ON_DEVICE: prError = PR_IO_ERROR; break;
- case ERROR_SHARING_VIOLATION: prError = PR_FILE_IS_BUSY_ERROR; break;
- case ERROR_STACK_OVERFLOW: prError = PR_ACCESS_FAULT_ERROR; break;
- case ERROR_TOO_MANY_OPEN_FILES: prError = PR_SYS_DESC_TABLE_FULL_ERROR; break;
- case ERROR_WRITE_PROTECT: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case WSAEACCES: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case WSAEADDRINUSE: prError = PR_ADDRESS_IN_USE_ERROR; break;
- case WSAEADDRNOTAVAIL: prError = PR_ADDRESS_NOT_AVAILABLE_ERROR; break;
- case WSAEAFNOSUPPORT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case WSAEALREADY: prError = PR_ALREADY_INITIATED_ERROR; break;
- case WSAEBADF: prError = PR_BAD_DESCRIPTOR_ERROR; break;
- case WSAECONNABORTED: prError = PR_CONNECT_ABORTED_ERROR; break;
- case WSAECONNREFUSED: prError = PR_CONNECT_REFUSED_ERROR; break;
- case WSAECONNRESET: prError = PR_CONNECT_RESET_ERROR; break;
- case WSAEDESTADDRREQ: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case WSAEFAULT: prError = PR_ACCESS_FAULT_ERROR; break;
- case WSAEHOSTUNREACH: prError = PR_HOST_UNREACHABLE_ERROR; break;
- case WSAEINVAL: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case WSAEISCONN: prError = PR_IS_CONNECTED_ERROR; break;
- case WSAEMFILE: prError = PR_PROC_DESC_TABLE_FULL_ERROR; break;
- case WSAEMSGSIZE: prError = PR_BUFFER_OVERFLOW_ERROR; break;
- case WSAENETDOWN: prError = PR_NETWORK_DOWN_ERROR; break;
- case WSAENETRESET: prError = PR_CONNECT_ABORTED_ERROR; break;
- case WSAENETUNREACH: prError = PR_NETWORK_UNREACHABLE_ERROR; break;
- case WSAENOBUFS: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case WSAENOPROTOOPT: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case WSAENOTCONN: prError = PR_NOT_CONNECTED_ERROR; break;
- case WSAENOTSOCK: prError = PR_NOT_SOCKET_ERROR; break;
- case WSAEOPNOTSUPP: prError = PR_OPERATION_NOT_SUPPORTED_ERROR; break;
- case WSAEPROTONOSUPPORT: prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR; break;
- case WSAEPROTOTYPE: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case WSAESHUTDOWN: prError = PR_SOCKET_SHUTDOWN_ERROR; break;
- case WSAESOCKTNOSUPPORT: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case WSAETIMEDOUT: prError = PR_CONNECT_ABORTED_ERROR; break;
- case WSAEWOULDBLOCK: prError = PR_WOULD_BLOCK_ERROR; break;
- default: prError = PR_UNKNOWN_ERROR; break;
- }
- PR_SetError(prError, err);
-}
-
diff --git a/security/nss/lib/ssl/win32err.h b/security/nss/lib/ssl/win32err.h
deleted file mode 100644
index b87dfefd4..000000000
--- a/security/nss/lib/ssl/win32err.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
- * NSPR's functions, instead of duplicating them, but they're private.
- * As long as SSL's server session cache code must do platform native I/O
- * to accomplish its job, and NSPR's error mapping functions remain private,
- * This code will continue to need to be replicated.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-/* NSPR doesn't make these functions public, so we have to duplicate
-** them in NSS.
-*/
-extern void nss_MD_win32_map_accept_error(PRInt32 err);
-extern void nss_MD_win32_map_acceptex_error(PRInt32 err);
-extern void nss_MD_win32_map_access_error(PRInt32 err);
-extern void nss_MD_win32_map_bind_error(PRInt32 err);
-extern void nss_MD_win32_map_close_error(PRInt32 err);
-extern void nss_MD_win32_map_closedir_error(PRInt32 err);
-extern void nss_MD_win32_map_connect_error(PRInt32 err);
-extern void nss_MD_win32_map_default_error(PRInt32 err);
-extern void nss_MD_win32_map_delete_error(PRInt32 err);
-extern void nss_MD_win32_map_fstat_error(PRInt32 err);
-extern void nss_MD_win32_map_fsync_error(PRInt32 err);
-extern void nss_MD_win32_map_gethostname_error(PRInt32 err);
-extern void nss_MD_win32_map_getpeername_error(PRInt32 err);
-extern void nss_MD_win32_map_getsockname_error(PRInt32 err);
-extern void nss_MD_win32_map_getsockopt_error(PRInt32 err);
-extern void nss_MD_win32_map_listen_error(PRInt32 err);
-extern void nss_MD_win32_map_lockf_error(PRInt32 err);
-extern void nss_MD_win32_map_lseek_error(PRInt32 err);
-extern void nss_MD_win32_map_mkdir_error(PRInt32 err);
-extern void nss_MD_win32_map_open_error(PRInt32 err);
-extern void nss_MD_win32_map_opendir_error(PRInt32 err);
-extern void nss_MD_win32_map_read_error(PRInt32 err);
-extern void nss_MD_win32_map_readdir_error(PRInt32 err);
-extern void nss_MD_win32_map_recv_error(PRInt32 err);
-extern void nss_MD_win32_map_recvfrom_error(PRInt32 err);
-extern void nss_MD_win32_map_rename_error(PRInt32 err);
-extern void nss_MD_win32_map_rmdir_error(PRInt32 err);
-extern void nss_MD_win32_map_select_error(PRInt32 err);
-extern void nss_MD_win32_map_send_error(PRInt32 err);
-extern void nss_MD_win32_map_sendto_error(PRInt32 err);
-extern void nss_MD_win32_map_setsockopt_error(PRInt32 err);
-extern void nss_MD_win32_map_shutdown_error(PRInt32 err);
-extern void nss_MD_win32_map_socket_error(PRInt32 err);
-extern void nss_MD_win32_map_stat_error(PRInt32 err);
-extern void nss_MD_win32_map_transmitfile_error(PRInt32 err);
-extern void nss_MD_win32_map_write_error(PRInt32 err);