Source code

Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
* This file is PRIVATE to SSL and should be the first thing included by
* any SSL implementation file.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at */
#ifndef __sslimpl_h_
#define __sslimpl_h_
#ifdef DEBUG
#undef NDEBUG
#undef NDEBUG
#define NDEBUG
#include "secport.h"
#include "secerr.h"
#include "sslerr.h"
#include "sslexp.h"
#include "ssl3prot.h"
#include "hasht.h"
#include "nssilock.h"
#include "pkcs11t.h"
#if defined(XP_UNIX)
#include "unistd.h"
#include "nssrwlk.h"
#include "prthread.h"
#include "prclist.h"
#include "private/pprthred.h"
#include "sslt.h" /* for some formerly private types, now public */
typedef struct sslSocketStr sslSocket;
typedef struct sslNamedGroupDefStr sslNamedGroupDef;
typedef struct sslEchConfigStr sslEchConfig;
typedef struct sslEchConfigContentsStr sslEchConfigContents;
typedef struct sslEchCookieDataStr sslEchCookieData;
typedef struct sslEchXtnStateStr sslEchXtnState;
typedef struct sslPskStr sslPsk;
typedef struct sslDelegatedCredentialStr sslDelegatedCredential;
typedef struct sslEphemeralKeyPairStr sslEphemeralKeyPair;
typedef struct TLS13KeyShareEntryStr TLS13KeyShareEntry;
#include "sslencode.h"
#include "sslexp.h"
#include "ssl3ext.h"
#include "sslspec.h"
#if defined(DEBUG) || defined(TRACE)
#ifdef __cplusplus
#define Debug 1
extern int Debug;
#undef Debug
#if defined(DEBUG) && !defined(TRACE) && !defined(NISCC_TEST)
#define TRACE
#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 PRINT_KEY(a, b) \
if (ssl_trace >= (a)) \
ssl_PrintKey b
#define SSL_TRC(a, b)
#define PRINT_BUF(a, b)
#define PRINT_KEY(a, b)
#ifdef DEBUG
#define SSL_DBG(b) \
if (ssl_debug) \
ssl_Trace b
#define SSL_DBG(b)
#define LSB(x) ((unsigned char)((x)&0xff))
#define MSB(x) ((unsigned char)(((unsigned)(x)) >> 8))
#define CONST_CAST(T, X) ((T *)(X))
typedef enum { SSLAppOpRead = 0,
} SSLAppOperation;
/* number of wrap mechanisms potentially used to wrap master secrets. */
/* This makes the cert cache entry exactly 4k. */
#ifndef BPB
#define BPB 8 /* Bits Per Byte */
/* The default value from RFC 4347 is 1s, which is too slow. */
/* The maximum time to wait between retransmissions. */
/* Time to wait in FINISHED state for retransmissions. */
/* default number of entries in namedGroupPreferences */
/* The maximum DH and RSA bit-length supported. */
#define SSL_MAX_DH_KEY_BITS 8192
#define SSL_MAX_RSA_KEY_BITS 8192
/* Types and names of elliptic curves used in TLS */
typedef enum {
ec_type_explicitPrime = 1, /* not supported */
ec_type_explicitChar2Curve = 2, /* not supported */
ec_type_named = 3
} ECType;
typedef enum {
ticket_allow_early_data = 1,
ticket_allow_psk_ke = 2,
ticket_allow_psk_dhe_ke = 4,
ticket_allow_psk_auth = 8,
ticket_allow_psk_sign_auth = 16
} TLS13SessionTicketFlags;
typedef enum {
update_not_requested = 0,
update_requested = 1
} tls13KeyUpdateRequest;
struct sslNamedGroupDefStr {
/* The name is the value that is encoded on the wire in TLS. */
SSLNamedGroup name;
/* The number of bits in the group. */
unsigned int bits;
/* The key exchange algorithm this group provides. */
SSLKEAType keaType;
/* The OID that identifies the group to PKCS11. This also determines
* whether the group is enabled in policy. */
SECOidTag oidTag;
/* Assume that the group is always supported. */
PRBool assumeSupported;
typedef struct sslConnectInfoStr sslConnectInfo;
typedef struct sslGatherStr sslGather;
typedef struct sslSecurityInfoStr sslSecurityInfo;
typedef struct sslSessionIDStr sslSessionID;
typedef struct sslSocketOpsStr sslSocketOps;
typedef struct ssl3StateStr ssl3State;
typedef struct ssl3CertNodeStr ssl3CertNode;
typedef struct sslKeyPairStr sslKeyPair;
typedef struct ssl3DHParamsStr ssl3DHParams;
struct ssl3CertNodeStr {
struct ssl3CertNodeStr *next;
CERTCertificate *cert;
typedef SECStatus (*sslHandshakeFunc)(sslSocket *ss);
void ssl_CacheSessionID(sslSocket *ss);
void ssl_UncacheSessionID(sslSocket *ss);
void ssl_ServerCacheSessionID(sslSessionID *sid, PRTime creationTime);
void ssl_ServerUncacheSessionID(sslSessionID *sid);
typedef sslSessionID *(*sslSessionIDLookupFunc)(PRTime ssl_now,
const PRIPv6Addr *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_NO_RETRANSMIT 0x08000000 /* DTLS only */
#define ssl_SEND_FLAG_MASK 0x7f000000
** SSL3 cipher suite policy and preference struct.
typedef struct {
#if !defined(_WIN32)
unsigned int cipher_suite : 16;
unsigned int policy : 8;
unsigned int enabled : 1;
unsigned int isPresent : 1;
ssl3CipherSuite cipher_suite;
PRUint8 policy;
unsigned char enabled : 1;
unsigned char isPresent : 1;
} ssl3CipherSuiteCfg;
#define ssl_V3_SUITES_IMPLEMENTED 71
/* MAX_SIGNATURE_SCHEMES allows for all the values we support. */
typedef struct sslOptionsStr {
/* If SSL_SetNextProtoNego has been called, then this contains the
* list of supported protocols. */
SECItem nextProtoNego;
PRUint16 recordSizeLimit;
PRUint32 maxEarlyDataSize;
unsigned int useSecurity : 1;
unsigned int useSocks : 1;
unsigned int requestCertificate : 1;
unsigned int requireCertificate : 2;
unsigned int handshakeAsClient : 1;
unsigned int handshakeAsServer : 1;
unsigned int noCache : 1;
unsigned int fdx : 1;
unsigned int detectRollBack : 1;
unsigned int noLocks : 1;
unsigned int enableSessionTickets : 1;
unsigned int enableDeflate : 1; /* Deprecated. */
unsigned int enableRenegotiation : 2;
unsigned int requireSafeNegotiation : 1;
unsigned int enableFalseStart : 1;
unsigned int cbcRandomIV : 1;
unsigned int enableOCSPStapling : 1;
unsigned int enableALPN : 1;
unsigned int reuseServerECDHEKey : 1;
unsigned int enableFallbackSCSV : 1;
unsigned int enableServerDhe : 1;
unsigned int enableExtendedMS : 1;
unsigned int enableSignedCertTimestamps : 1;
unsigned int requireDHENamedGroups : 1;
unsigned int enable0RttData : 1;
unsigned int enableTls13CompatMode : 1;
unsigned int enableDtlsShortHeader : 1;
unsigned int enableHelloDowngradeCheck : 1;
unsigned int enableV2CompatibleHello : 1;
unsigned int enablePostHandshakeAuth : 1;
unsigned int enableDelegatedCredentials : 1;
unsigned int enableDtls13VersionCompat : 1;
unsigned int suppressEndOfEarlyData : 1;
unsigned int enableTls13GreaseEch : 1;
unsigned int enableTls13BackendEch : 1;
unsigned int callExtensionWriterOnEchInner : 1;
unsigned int enableGrease : 1;
unsigned int enableChXtnPermutation : 1;
} sslOptions;
typedef enum { sslHandshakingUndetermined = 0,
} sslHandshakingType;
#define SSL_LOCK_RANK_SPEC 255
/* 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. */
/* "buf" holds received plaintext SSL records, after decrypt and MAC check.
* recv'd ciphertext records are put in inbuf (see below), then decrypted
* into buf.
sslBuffer buf; /*recvBufLock*/
/* number of bytes previously read into hdr or inbuf.
** (offset - writeOffset) is the number of ciphertext bytes read in but
** not yet deciphered.
unsigned int offset;
/* number of bytes to read in next call to ssl_DefRecv (recv) */
unsigned int remainder;
/* DoRecv uses the next two values 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*/
/* 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 SSL3/TLS, the plaintext portion is 5 bytes long. For DTLS it
** varies based on version and header type.
unsigned char hdr[13];
unsigned int hdrLen;
/* Buffer for DTLS data read off the wire as a single datagram */
sslBuffer dtlsPacket;
/* the start of the buffered DTLS record in dtlsPacket */
unsigned int dtlsPacketOffset;
/* tracks whether we've seen a v3-type record before and must reject
* any further v2-type records. */
PRBool rejectV2Records;
/* sslGather.state */
#define GS_INIT 0
#define GS_HEADER 1
#define GS_DATA 2
typedef struct {
PRUint8 wrapped_master_secret[WRAPPED_MASTER_SECRET_SIZE];
PRUint8 wrapped_master_secret_len;
PRUint8 resumable;
PRUint8 extendedMasterSecretUsed;
} ssl3SidKeys; /* 52 bytes */
typedef enum { never_cached,
invalid_cache, /* no longer in any cache. */
} Cached;
#include "sslcert.h"
struct sslSessionIDStr {
/* The global cache lock must be held when accessing these members when the
* sid is in any cache.
sslSessionID *next; /* chain used for client sockets, only */
Cached cached;
int references;
PRTime lastAccessTime;
/* The rest of the members, except for the members of u.ssl3.locked, may
* be modified only when the sid is not in any cache.
CERTCertificate *peerCert;
SECItemArray peerCertStatus; /* client only */
const char *peerID; /* client only */
const char *urlSvrName; /* client only */
const sslNamedGroupDef *namedCurve; /* (server) for certificate lookup */
CERTCertificate *localCert;
PRIPv6Addr addr;
PRUint16 port;
SSL3ProtocolVersion version;
PRTime creationTime;
PRTime expirationTime;
SSLAuthType authType;
PRUint32 authKeyBits;
SSLKEAType keaType;
PRUint32 keaKeyBits;
SSLNamedGroup keaGroup;
SSLSignatureScheme sigScheme;
union {
struct {
/* values that are copied into the server's on-disk SID cache. */
PRUint8 sessionIDLength;
ssl3CipherSuite cipherSuite;
PRUint8 policy;
ssl3SidKeys keys;
/* mechanism used to wrap master secret */
/* 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;
SECItem srvName;
/* Signed certificate timestamps received in a TLS extension.
** (used only in client).
SECItem signedCertTimestamps;
/* The ALPN value negotiated in the original connection.
* Used for TLS 1.3. */
SECItem alpnSelection;
/* This lock is lazily initialized by CacheSID when a sid is first
* cached. Before then, there is no need to lock anything because
* the sid isn't being shared by anything.
PRRWLock *lock;
/* The lock must be held while reading or writing these members
* because they change while the sid is cached.
struct {
/* The session ticket, if we have one, is sent as an extension
* in the ClientHello message. This field is used only by
* clients. It is protected by lock when lock is non-null
* (after the sid has been added to the client session cache).
NewSessionTicket sessionTicket;
} locked;
} ssl3;
} u;
struct ssl3CipherSuiteDefStr {
ssl3CipherSuite cipher_suite;
SSL3BulkCipher bulk_cipher_alg;
SSL3MACAlgorithm mac_alg;
SSL3KeyExchangeAlgorithm key_exchange_alg;
SSLHashType prf_hash;
** There are tables of these, all const.
typedef struct {
/* An identifier for this struct. */
SSL3KeyExchangeAlgorithm kea;
/* The type of key exchange used by the cipher suite. */
SSLKEAType exchKeyType;
/* If the cipher suite uses a signature, the type of key used in the
* signature. */
KeyType signKeyType;
/* In most cases, cipher suites depend on their signature type for
* authentication, ECDH certificates being the exception. */
SSLAuthType authKeyType;
/* True if the key exchange for the suite is ephemeral. Or to be more
* precise: true if the ServerKeyExchange message is always required. */
PRBool ephemeral;
/* An OID describing the key exchange */
SECOidTag oid;
} ssl3KEADef;
typedef enum {
ssl_0rtt_none, /* 0-RTT not present */
ssl_0rtt_sent, /* 0-RTT sent (no decision yet) */
ssl_0rtt_accepted, /* 0-RTT sent and accepted */
ssl_0rtt_ignored, /* 0-RTT sent but rejected/ignored */
ssl_0rtt_done /* 0-RTT accepted, but finished */
} sslZeroRttState;
typedef enum {
ssl_0rtt_ignore_none, /* not ignoring */
ssl_0rtt_ignore_trial, /* ignoring with trial decryption */
ssl_0rtt_ignore_hrr /* ignoring until ClientHello (due to HRR) */
} sslZeroRttIgnore;
typedef enum {
wait_invalid /* Invalid value. There is no handshake message "invalid". */
} SSL3WaitState;
typedef enum {
client_hello_initial, /* The first attempt. */
client_hello_retry, /* If we receive HelloRetryRequest. */
client_hello_retransmit, /* In DTLS, if we receive HelloVerifyRequest. */
client_hello_renegotiation /* A renegotiation attempt. */
} sslClientHelloType;
typedef struct SessionTicketDataStr SessionTicketData;
typedef SECStatus (*sslRestartTarget)(sslSocket *);
** A DTLS queued message (potentially to be retransmitted)
typedef struct DTLSQueuedMessageStr {
PRCList link; /* The linked list link */
ssl3CipherSpec *cwSpec; /* The cipher spec to use, null for none */
SSLContentType type; /* The message type */
unsigned char *data; /* The data */
PRUint16 len; /* The data length */
} DTLSQueuedMessage;
struct TLS13KeyShareEntryStr {
PRCList link; /* The linked list link */
const sslNamedGroupDef *group; /* The group for the entry */
SECItem key_exchange; /* The share itself */
typedef struct TLS13EarlyDataStr {
PRCList link; /* The linked list link */
unsigned int consumed; /* How much has been read. */
SECItem data; /* The data */
} TLS13EarlyData;
typedef enum {
handshake_hash_unknown = 0,
handshake_hash_combo = 1, /* The MD5/SHA-1 combination */
handshake_hash_single = 2, /* A single hash */
} SSL3HandshakeHashType;
// A DTLS Timer.
typedef void (*DTLSTimerCb)(sslSocket *);
typedef struct {
const char *label;
DTLSTimerCb cb;
PRIntervalTime started;
PRUint32 timeout;
} dtlsTimer;
/* TLS 1.3 client GREASE entry indices. */
typedef enum {
} tls13ClientGreaseEntry;
/* TLS 1.3 client GREASE values struct. */
typedef struct tls13ClientGreaseStr {
PRUint16 idx[grease_entries];
PRUint8 pskKem;
} tls13ClientGrease;
** 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;
SSL3Random client_inner_random; /* TLS 1.3 ECH Inner. */
SSL3WaitState ws; /* May also contain SSL3WaitState | 0x80 for TLS 1.3 */
/* This group of members is used for handshake running hashes. */
SSL3HandshakeHashType hashType;
sslBuffer messages; /* Accumulated handshake messages */
sslBuffer echInnerMessages; /* Accumulated ECH Inner handshake messages */
/* PKCS #11 mode:
* SSL 3.0 - TLS 1.1 use both |md5| and |sha|. |md5| is used for MD5 and
* |sha| for SHA-1.
* TLS 1.2 and later use only |sha| variants, for SHA-256.
* Under normal (non-1.3 ECH) handshakes, only |sha| and |shaPostHandshake|
* are used. When doing 1.3 ECH, |sha| contains the transcript hash
* corresponding to the outer Client Hello. To facilitate secure retry and
* disablement, |shaEchInner|, tracks, in parallel, the transcript hash
* corresponding to the inner Client Hello. Once we process the SH
* extensions, coalesce into |sha|. */
PK11Context *md5;
PK11Context *sha;
PK11Context *shaEchInner;
PK11Context *shaPostHandshake;
SSLSignatureScheme signatureScheme;
const ssl3KEADef *kea_def;
ssl3CipherSuite cipher_suite;
const ssl3CipherSuiteDef *suite_def;
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 */
SSLHandshakeType msg_type;
unsigned long msg_len;
PRBool isResuming; /* we are resuming (not used in TLS 1.3) */
PRBool sendingSCSV; /* instead of empty RI */
/* The session ticket received in a NewSessionTicket message is temporarily
* stored in newSessionTicket until the handshake is finished; then it is
* moved to the sid.
PRBool receivedNewSessionTicket;
NewSessionTicket newSessionTicket;
PRUint16 finishedBytes; /* size of single finished below */
union {
TLSFinished tFinished[2]; /* client, then server */
SSL3Finished sFinished[2];
PRUint8 data[72];
} finishedMsgs;
/* True when handshake is blocked on client certificate selection */
PRBool clientCertificatePending;
/* Parameters stored whilst waiting for client certificate */
SSLSignatureScheme *clientAuthSignatureSchemes;
unsigned int clientAuthSignatureSchemesLen;
PRBool authCertificatePending;
/* Which function should SSL_RestartHandshake* call if we're blocked?
* One of NULL, ssl3_SendClientSecondRound, ssl3_FinishHandshake,
* or ssl3_AlwaysFail */
sslRestartTarget restartTarget;
PRBool canFalseStart; /* Can/did we False Start */
/* Which preliminaryinfo values have been set. */
PRUint32 preliminaryInfo;
/* Parsed extensions */
PRCList remoteExtensions; /* Parsed incoming extensions */
PRCList echOuterExtensions; /* If ECH, hold CHOuter extensions for decompression. */
/* This group of values is used for DTLS */
PRUint16 sendMessageSeq; /* The sending message sequence
* number */
PRCList lastMessageFlight; /* The last message flight we
* sent */
PRUint16 maxMessageSent; /* The largest message we sent */
PRUint16 recvMessageSeq; /* The receiving message sequence
* number */
sslBuffer recvdFragments; /* The fragments we have received in
* a bitmask */
PRInt32 recvdHighWater; /* The high water mark for fragments
* received. -1 means no reassembly
* in progress. */
SECItem cookie; /* The Hello(Retry|Verify)Request cookie. */
dtlsTimer timers[3]; /* Holder for timers. */
dtlsTimer *rtTimer; /* Retransmit timer. */
dtlsTimer *ackTimer; /* Ack timer (DTLS 1.3 only). */
dtlsTimer *hdTimer; /* Read cipher holddown timer (DLTS 1.3 only) */
PRUint32 rtRetries; /* The retry counter */
SECItem srvVirtName; /* for server: name that was negotiated
* with a client. For client - is
* always set to NULL.*/
/* This group of values is used for TLS 1.3 and above */
PK11SymKey *currentSecret; /* The secret down the "left hand side"
* of the TLS 1.3 key schedule. */
PK11SymKey *resumptionMasterSecret; /* The resumption_master_secret. */
PK11SymKey *dheSecret; /* The (EC)DHE shared secret. */
PK11SymKey *clientEarlyTrafficSecret; /* The secret we use for 0-RTT. */
PK11SymKey *clientHsTrafficSecret; /* The source keys for handshake */
PK11SymKey *serverHsTrafficSecret; /* traffic keys. */
PK11SymKey *clientTrafficSecret; /* The source keys for application */
PK11SymKey *serverTrafficSecret; /* traffic keys */
PK11SymKey *earlyExporterSecret; /* for 0-RTT exporters */
PK11SymKey *exporterSecret; /* for exporters */
PRCList cipherSpecs; /* The cipher specs in the sequence they
* will be applied. */
sslZeroRttState zeroRttState; /* Are we doing a 0-RTT handshake? */
sslZeroRttIgnore zeroRttIgnore; /* Are we ignoring 0-RTT? */
ssl3CipherSuite zeroRttSuite; /* The cipher suite we used for 0-RTT. */
PRCList bufferedEarlyData; /* Buffered TLS 1.3 early data
* on server.*/
PRBool helloRetry; /* True if HelloRetryRequest has been sent
* or received. */
PRBool receivedCcs; /* A server received ChangeCipherSpec
* before the handshake started. */
PRBool rejectCcs; /* Excessive ChangeCipherSpecs are rejected. */
PRBool clientCertRequested; /* True if CertificateRequest received. */
PRBool endOfFlight; /* Processed a full flight (DTLS 1.3). */
ssl3KEADef kea_def_mutable; /* Used to hold the writable kea_def
* we use for TLS 1.3 */
PRUint16 ticketNonce; /* A counter we use for tickets. */
SECItem fakeSid; /* ... (server) the SID the client used. */
PRCList psks; /* A list of PSKs, resumption and/or external. */
/* rttEstimate is used to guess the round trip time between server and client.
* When the server sends ServerHello it sets this to the current time.
* Only after it receives a message from the client's second flight does it
* set the value to something resembling an RTT estimate. */
PRTime rttEstimate;
/* The following lists contain DTLSHandshakeRecordEntry */
PRCList dtlsSentHandshake; /* Used to map records to handshake fragments. */
PRCList dtlsRcvdHandshake; /* Handshake records we have received
* used to generate ACKs. */
/* TLS 1.3 ECH state. */
PRUint8 greaseEchSize;
PRBool echAccepted; /* Client/Server: True if we've commited to using CHInner. */
PRBool echDecided;
HpkeContext *echHpkeCtx; /* Client/Server: HPKE context for ECH. */
const char *echPublicName; /* Client: If rejected, the ECHConfig.publicName to
* use for certificate verification. */
sslBuffer greaseEchBuf; /* Client: Remember GREASE ECH, as advertised, for CH2 (HRR case).
Server: Remember HRR Grease Value, for transcript calculations */
PRBool echInvalidExtension; /* Client: True if the server offered an invalid extension for the ClientHelloInner */
/* TLS 1.3 GREASE state. */
tls13ClientGrease *grease;
/* ClientHello Extension Permutation state. */
sslExtensionBuilder *chExtensionPermutation;
} SSL3HandshakeState;
do { \
PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_unknown); \
PORT_Assert(ss->ssl3.hs.messages.len == 0); \
PORT_Assert(ss->ssl3.hs.echInnerMessages.len == 0); \
} while (0)
** 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. */
/* This is true after the peer requests a key update; false after a key
* update is initiated locally. */
PRBool peerRequestedKeyUpdate;
/* This is true if we deferred sending a key update as
* post-handshake auth is in progress. */
PRBool keyUpdateDeferred;
tls13KeyUpdateRequest deferredKeyUpdateRequest;
/* This is true after the server requests client certificate;
* false after the client certificate is received. Used by the
* server. */
PRBool clientCertRequested;
CERTCertificate *clientCertificate; /* used by client */
SECKEYPrivateKey *clientPrivateKey; /* used by client */
CERTCertificateList *clientCertChain; /* used by client */
PRBool sendEmptyCert; /* used by client */
PRUint8 policy;
/* This says what cipher suites we can do, and should
PLArenaPool *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. */
SSL3HandshakeState hs;
PRUint16 mtu; /* Our estimate of the MTU */
/* DTLS-SRTP cipher suite preferences (if any) */
PRUint16 dtlsSRTPCipherCount;
PRBool fatalAlertSent;
PRBool dheWeakGroupEnabled; /* used by server */
const sslNamedGroupDef *dhePreferredGroup;
/* TLS 1.2 introduces separate signature algorithm negotiation.
* TLS 1.3 combined signature and hash into a single enum.
* This is our preference order. */
SSLSignatureScheme signatureSchemes[MAX_SIGNATURE_SCHEMES];
unsigned int signatureSchemeCount;
/* The version to check if we fell back from our highest version
* of TLS. Default is 0 in which case we check against the maximum
* configured version for this socket. Used only on the client. */
SSL3ProtocolVersion downgradeCheckVersion;
/* Ethernet MTU but without subtracting the headers,
* so slightly larger than expected */
#define DTLS_MAX_MTU 1500U
#define IS_DTLS(ss) (ss->protocolVariant == ssl_variant_datagram)
typedef struct {
/* |seqNum| eventually contains the reconstructed sequence number. */
sslSequenceNumber seqNum;
/* The header of the cipherText. */
PRUint8 *hdr;
unsigned int hdrLen;
/* |buf| is the payload of the ciphertext. */
sslBuffer *buf;
} SSL3Ciphertext;
struct sslKeyPairStr {
SECKEYPrivateKey *privKey;
SECKEYPublicKey *pubKey;
PRInt32 refCount; /* use PR_Atomic calls for this. */
struct sslEphemeralKeyPairStr {
PRCList link;
const sslNamedGroupDef *group;
sslKeyPair *keys;
struct ssl3DHParamsStr {
SSLNamedGroup name;
SECItem prime; /* p */
SECItem base; /* g */
typedef struct SSLWrappedSymWrappingKeyStr {
PRUint8 wrappedSymmetricWrappingkey[SSL_MAX_RSA_KEY_BITS / 8];
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. */
PRInt16 wrapMechIndex;
PRUint16 wrapKeyIndex;
PRUint16 wrappedSymKeyLen;
} SSLWrappedSymWrappingKey;
typedef struct SessionTicketStr {
PRBool valid;
SSL3ProtocolVersion ssl_version;
ssl3CipherSuite cipher_suite;
SSLAuthType authType;
PRUint32 authKeyBits;
SSLKEAType keaType;
PRUint32 keaKeyBits;
SSLNamedGroup originalKeaGroup;
SSLSignatureScheme signatureScheme;
const sslNamedGroupDef *namedCurve; /* For certificate lookup. */
* msWrapMech contains a meaningful value only if ms_is_wrapped is true.
PRUint8 ms_is_wrapped;
PRUint16 ms_length;
PRUint8 master_secret[48];
PRBool extendedMasterSecretUsed;
ClientAuthenticationType client_auth_type;
SECItem peer_cert;
PRTime timestamp;
PRUint32 flags;
SECItem srvName; /* negotiated server name */
SECItem alpnSelection;
PRUint32 maxEarlyData;
PRUint32 ticketAgeBaseline;
SECItem applicationToken;
} SessionTicket;
* 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->".
** Protection: All the variables in here are protected by
** firstHandshakeLock AND ssl3HandshakeLock
struct sslConnectInfoStr {
/* outgoing handshakes appended to this. */
sslBuffer sendBuf; /*xmitBufLock*/
PRIPv6Addr peer;
unsigned short port;
sslSessionID *sid;
/* 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 ssl3HandshakeLock.
struct sslSecurityInfoStr {
#define SSL_ROLE(ss) (ss->sec.isServer ? "server" : "client")
PRBool isServer;
sslBuffer writeBuf; /*xmitBufLock*/
CERTCertificate *localCert;
CERTCertificate *peerCert;
SECKEYPublicKey *peerKey;
SSLAuthType authType;
PRUint32 authKeyBits;
SSLSignatureScheme signatureScheme;
SSLKEAType keaType;
PRUint32 keaKeyBits;
const sslNamedGroupDef *keaGroup;
const sslNamedGroupDef *originalKeaGroup;
/* The selected certificate (for servers only). */
const sslServerCert *serverCert;
/* These are used during a connection handshake */
sslConnectInfo ci;
** SSL Socket struct
** Protection: XXX
struct sslSocketStr {
PRFileDesc *fd;
/* Pointer to operations vector for this socket */
const sslSocketOps *ops;
/* SSL socket options */
sslOptions opt;
/* Enabled version range */
SSLVersionRange vrange;
/* A function that returns the current time. */
SSLTimeFunc now;
void *nowArg;
/* State flags */
unsigned long clientAuthRequested;
unsigned long delayDisabled; /* Nagle delay disabled */
unsigned long firstHsDone; /* first handshake is complete. */
unsigned long enoughFirstHsDone; /* enough of the first handshake is
* done for callbacks to be able to
* retrieve channel security
* parameters from the SSL socket. */
unsigned long handshakeBegun;
unsigned long lastWriteBlocked;
unsigned long recvdCloseNotify; /* received SSL EOF. */
unsigned long TCPconnected;
unsigned long appDataBuffered;
unsigned long peerRequestedProtection; /* from old renegotiation */
/* version of the protocol to use */
SSL3ProtocolVersion version;
SSL3ProtocolVersion clientHelloVersion; /* version sent in client hello. */
sslSecurityInfo sec; /* not a pointer any more */
/* protected by firstHandshakeLock AND ssl3HandshakeLock. */
const char *url;
sslHandshakeFunc handshake; /*firstHandshakeLock*/
/* the following variable is only used with socks or other proxies. */
char *peerID; /* String uniquely identifies target server. */
/* ECDHE and DHE keys: In TLS 1.3, we might have to maintain multiple of
* these on the client side. The server inserts a single value into this
* list for all versions. */
PRCList /*<sslEphemeralKeyPair>*/ ephemeralKeyPairs;
/* Callbacks */
SSLAuthCertificate authCertificate;
void *authCertificateArg;
SSLGetClientAuthData getClientAuthData;
void *getClientAuthDataArg;
SSLSNISocketConfig sniSocketConfig;
void *sniSocketConfigArg;
SSLAlertCallback alertReceivedCallback;
void *alertReceivedCallbackArg;
SSLAlertCallback alertSentCallback;
void *alertSentCallbackArg;
SSLBadCertHandler handleBadCert;
void *badCertArg;
SSLHandshakeCallback handshakeCallback;
void *handshakeCallbackData;
SSLCanFalseStartCallback canFalseStartCallback;
void *canFalseStartCallbackData;
void *pkcs11PinArg;
SSLNextProtoCallback nextProtoCallback;
void *nextProtoArg;
SSLHelloRetryRequestCallback hrrCallback;
void *hrrCallbackArg;
PRCList extensionHooks;
SSLResumptionTokenCallback resumptionTokenCallback;
void *resumptionTokenContext;
SSLSecretCallback secretCallback;
void *secretCallbackArg;
SSLRecordWriteCallback recordWriteCallback;
void *recordWriteCallbackArg;
PRIntervalTime rTimeout; /* timeout for NSPR I/O */
PRIntervalTime wTimeout; /* timeout for NSPR I/O */
PRIntervalTime cTimeout; /* timeout for NSPR I/O */
PZLock *recvLock; /* lock against multiple reader threads. */
PZLock *sendLock; /* lock against multiple sender threads. */
PZMonitor *recvBufLock; /* locks low level recv buffers. */
PZMonitor *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.
PZMonitor *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. */
PZMonitor *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;
PRThread *writerThread; /* thread holds SSL_LOCK_WRITER lock */
PRUint16 shutdownHow; /* See ssl_SHUTDOWN defines below. */
sslHandshakingType handshaking;
/* Gather object used for gathering data */
sslGather gs; /*recvBufLock*/
sslBuffer saveBuf; /*xmitBufLock*/
sslBuffer pendingBuf; /*xmitBufLock*/
/* Configuration state for server sockets */
/* One server cert and key for each authentication type. */
PRCList /* <sslServerCert> */ serverCerts;
ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED];
/* A list of groups that are sorted according to user preferences pointing
* to entries of ssl_named_groups. By default this list contains pointers
* to all elements in ssl_named_groups in the default order.
* This list also determines which groups are enabled. This
* starts with all being enabled and can be modified either by negotiation
* (in which case groups not supported by a peer are masked off), or by
* calling SSL_DHEGroupPrefSet().
* Note that renegotiation will ignore groups that were disabled in the
* first handshake.
const sslNamedGroupDef *namedGroupPreferences[SSL_NAMED_GROUP_COUNT];
/* The number of additional shares to generate for the TLS 1.3 ClientHello */
unsigned int additionalShares;
/* SSL3 state info. Formerly was a pointer */
ssl3State ssl3;
* TLS extension related data.
/* True when the current session is a stateless resume. */
PRBool statelessResume;
TLSExtensionData xtnData;
/* Whether we are doing stream or datagram mode */
SSLProtocolVariant protocolVariant;
/* TLS 1.3 Encrypted Client Hello. */
PRCList echConfigs; /* Client/server: Must not change while hs
* is in-progress. */
SECKEYPublicKey *echPubKey; /* Server: The ECH keypair used in HPKE. */
SECKEYPrivateKey *echPrivKey; /* As above. */
/* Anti-replay for TLS 1.3 0-RTT. */
SSLAntiReplayContext *antiReplay;
/* An out-of-band PSK. */
sslPsk *psk;
struct sslSelfEncryptKeysStr {
PRCallOnceType setup;
PK11SymKey *encKey;
PK11SymKey *macKey;
typedef struct sslSelfEncryptKeysStr sslSelfEncryptKeys;
extern char ssl_debug;
extern char ssl_trace;
extern FILE *ssl_trace_iob;
extern FILE *ssl_keylog_iob;
extern PZLock *ssl_keylog_lock;
static const PRUint32 ssl_ticket_lifetime = 2 * 24 * 60 * 60; // 2 days.
extern const char *const ssl3_cipherName[];
extern sslSessionIDLookupFunc ssl_sid_lookup;
extern const sslNamedGroupDef ssl_named_groups[];
/* Internal initialization and installation of the SSL error tables */
extern SECStatus ssl_Init(void);
extern SECStatus ssl_InitializePRErrorTable(void);
/* 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 SECStatus ssl3_InitGather(sslGather *gs);
extern void ssl3_DestroyGather(sslGather *gs);
extern SECStatus ssl_GatherRecord1stHandshake(sslSocket *ss);
extern SECStatus ssl_CreateSecurityInfo(sslSocket *ss);
extern SECStatus ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os);
extern void ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset);
extern void ssl_DestroySecurityInfo(sslSecurityInfo *sec);
extern void ssl_PrintBuf(const sslSocket *ss, const char *msg, const void *cp,
int len);
extern void ssl_PrintKey(const sslSocket *ss, const char *msg, PK11SymKey *key);
extern int ssl_SendSavedWriteData(sslSocket *ss);
extern SECStatus ssl_SaveWriteData(sslSocket *ss,
const void *p, unsigned int l);
extern SECStatus ssl_BeginClientHandshake(sslSocket *ss);
extern SECStatus ssl_BeginServerHandshake(sslSocket *ss);
extern SECStatus ssl_Do1stHandshake(sslSocket *ss);
extern SECStatus ssl3_InitPendingCipherSpecs(sslSocket *ss, PK11SymKey *secret,
PRBool derive);
extern void ssl_DestroyKeyMaterial(ssl3KeyMaterial *keyMaterial);
extern sslSessionID *ssl3_NewSessionID(sslSocket *ss, PRBool is_server);
extern sslSessionID *ssl_LookupSID(PRTime now, const PRIPv6Addr *addr,
PRUint16 port, const char *peerID,
const char *urlSvrName);
extern void ssl_FreeSID(sslSessionID *sid);
extern void ssl_DestroySID(sslSessionID *sid, PRBool freeIt);
extern sslSessionID *ssl_ReferenceSID(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 ssl3_SetAlwaysBlock(sslSocket *ss);
extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
extern SECStatus ssl_FinishHandshake(sslSocket *ss);
extern SECStatus ssl_CipherPolicySet(PRInt32 which, PRInt32 policy);
extern SECStatus ssl_CipherPrefSetDefault(PRInt32 which, PRBool enabled);
extern SECStatus ssl3_ConstrainRangeByPolicy(void);
extern SECStatus ssl3_InitState(sslSocket *ss);
extern SECStatus Null_Cipher(void *ctx, unsigned char *output, unsigned int *outputLen,
unsigned int maxOutputLen, const unsigned char *input,
unsigned int inputLen);
extern void ssl3_RestartHandshakeHashes(sslSocket *ss);
typedef SECStatus (*sslUpdateHandshakeHashes)(sslSocket *ss,
const unsigned char *b,
unsigned int l);
extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket *ss,
const unsigned char *b,
unsigned int l);
extern SECStatus ssl3_UpdatePostHandshakeHashes(sslSocket *ss,
const unsigned char *b,
unsigned int l);
ssl_HashHandshakeMessageInt(sslSocket *ss, SSLHandshakeType type,
PRUint32 dtlsSeq,
const PRUint8 *b, PRUint32 length,
sslUpdateHandshakeHashes cb);
SECStatus ssl_HashHandshakeMessage(sslSocket *ss, SSLHandshakeType type,
const PRUint8 *b, PRUint32 length);
SECStatus ssl_HashHandshakeMessageEchInner(sslSocket *ss, SSLHandshakeType type,
const PRUint8 *b, PRUint32 length);
SECStatus ssl_HashHandshakeMessageDefault(sslSocket *ss, SSLHandshakeType type,
const PRUint8 *b, PRUint32 length);
SECStatus ssl_HashPostHandshakeMessage(sslSocket *ss, SSLHandshakeType type,
const PRUint8 *b, PRUint32 length);
/* Returns PR_TRUE if we are still waiting for the server to complete its
* response to our client second round. Once we've received the Finished from
* the server then there is no need to check false start.
extern PRBool ssl3_WaitingForServerSecondRound(sslSocket *ss);
extern PRInt32 ssl3_SendRecord(sslSocket *ss, ssl3CipherSpec *cwSpec,
SSLContentType type,
const PRUint8 *pIn, PRInt32 nIn,
PRInt32 flags);
/* Clear any PRCList, optionally calling f on the value. */
void ssl_ClearPRCList(PRCList *list, void (*f)(void *));
* Make sure there is room in the write buffer for padding and
* cryptographic expansions.
#define SSL3_BUFFER_FUDGE 100
#define SSL_LOCK_READER(ss) \
if (ss->recvLock) \
#define SSL_UNLOCK_READER(ss) \
if (ss->recvLock) \
#define SSL_LOCK_WRITER(ss) \
if (ss->sendLock) \
#define SSL_UNLOCK_WRITER(ss) \
if (ss->sendLock) \
/* firstHandshakeLock -> recvBufLock */
#define ssl_Get1stHandshakeLock(ss) \
{ \
if (!ss->opt.noLocks) { \
PORT_Assert(PZ_InMonitor((ss)->firstHandshakeLock) || \
!ssl_HaveRecvBufLock(ss)); \
PZ_EnterMonitor((ss)->firstHandshakeLock); \
} \
#define ssl_Release1stHandshakeLock(ss) \
{ \
if (!ss->opt.noLocks) \
PZ_ExitMonitor((ss)->firstHandshakeLock); \
#define ssl_Have1stHandshakeLock(ss) \
/* ssl3HandshakeLock -> xmitBufLock */
#define ssl_GetSSL3HandshakeLock(ss) \
{ \
if (!ss->opt.noLocks) { \
PORT_Assert(!ssl_HaveXmitBufLock(ss)); \
PZ_EnterMonitor((ss)->ssl3HandshakeLock); \
} \
#define ssl_ReleaseSSL3HandshakeLock(ss) \
{ \
if (!ss->opt.noLocks) \
PZ_ExitMonitor((ss)->ssl3HandshakeLock); \
#define ssl_HaveSSL3HandshakeLock(ss) \
#define ssl_GetSpecReadLock(ss) \
{ \
if (!ss->opt.noLocks) \
NSSRWLock_LockRead((ss)->specLock); \
#define ssl_ReleaseSpecReadLock(ss) \
{ \
if (!ss->opt.noLocks) \
NSSRWLock_UnlockRead((ss)->specLock); \
/* NSSRWLock_HaveReadLock is not exported so there's no
* ssl_HaveSpecReadLock macro. */
#define ssl_GetSpecWriteLock(ss) \
{ \
if (!ss->opt.noLocks) \
NSSRWLock_LockWrite((ss)->specLock); \
#define ssl_ReleaseSpecWriteLock(ss) \
{ \
if (!ss->opt.noLocks) \
NSSRWLock_UnlockWrite((ss)->specLock); \
#define ssl_HaveSpecWriteLock(ss) \
/* recvBufLock -> ssl3HandshakeLock -> xmitBufLock */
#define ssl_GetRecvBufLock(ss) \
{ \
if (!ss->opt.noLocks) { \
PORT_Assert(!ssl_HaveSSL3HandshakeLock(ss)); \
PORT_Assert(!ssl_HaveXmitBufLock(ss)); \
PZ_EnterMonitor((ss)->recvBufLock); \
} \
#define ssl_ReleaseRecvBufLock(ss) \
{ \
if (!ss->opt.noLocks) \
PZ_ExitMonitor((ss)->recvBufLock); \
#define ssl_HaveRecvBufLock(ss) \
/* xmitBufLock -> specLock */
#define ssl_GetXmitBufLock(ss) \
{ \
if (!ss->opt.noLocks) \
PZ_EnterMonitor((ss)->xmitBufLock); \
#define ssl_ReleaseXmitBufLock(ss) \
{ \
if (!ss->opt.noLocks) \
PZ_ExitMonitor((ss)->xmitBufLock); \
#define ssl_HaveXmitBufLock(ss) \
/* Placeholder value used in version ranges when SSL 3.0 and all
* versions of TLS are disabled.
/* SSL_LIBRARY_VERSION_MIN_SUPPORTED is the minimum version that this version
* of libssl supports. Applications should use SSL_VersionRangeGetSupported at
* runtime to determine which versions are supported by the version of libssl
* in use.
/* SSL_LIBRARY_VERSION_MAX_SUPPORTED is the maximum version that this version
* of libssl supports. Applications should use SSL_VersionRangeGetSupported at
* runtime to determine which versions are supported by the version of libssl
* in use.
#ifndef NSS_DISABLE_TLS_1_3
((vrange)->min == SSL_LIBRARY_VERSION_NONE)
extern PRBool ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
SSL3ProtocolVersion version);
/* These functions are called from secnav, even though they're "private". */
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 SECStatus ssl3_DecodeError(sslSocket *ss);
extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error);
extern SECStatus ssl3_ClientCertCallbackComplete(sslSocket *ss, SECStatus outcome, SECKEYPrivateKey *clientPrivateKey, CERTCertificate *clientCertificate);
* for dealing with SSL 3.0 clients sending SSL 2.0 format hellos
extern SECStatus ssl3_HandleV2ClientHello(
sslSocket *ss, unsigned char *buffer, unsigned int length, PRUint8 padding);
ssl3_CreateClientHelloPreamble(sslSocket *ss, const sslSessionID *sid,
PRBool realSid, PRUint16 version, PRBool isEchInner,
const sslBuffer *extensions, sslBuffer *preamble);
SECStatus ssl3_InsertChHeaderSize(const sslSocket *ss, sslBuffer *preamble, const sslBuffer *extensions);
SECStatus ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type);
* input into the SSL3 machinery from the actualy network reading code
SECStatus ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cipher);
SECStatus ssl3_HandleNonApplicationData(sslSocket *ss, SSLContentType rType,
DTLSEpoch epoch,
sslSequenceNumber seqNum,
sslBuffer *databuf);
SECStatus ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize);
int ssl3_GatherAppDataRecord(sslSocket *ss, int flags);
int ssl3_GatherCompleteHandshake(sslSocket *ss, int flags);
/* Create a new ref counted key pair object from two keys. */
extern sslKeyPair *ssl_NewKeyPair(SECKEYPrivateKey *privKey,
SECKEYPublicKey *pubKey);
/* get a new reference (bump ref count) to an ssl3KeyPair. */
extern sslKeyPair *ssl_GetKeyPairRef(sslKeyPair *keyPair);
/* Decrement keypair's ref count and free if zero. */
extern void ssl_FreeKeyPair(sslKeyPair *keyPair);
extern sslEphemeralKeyPair *ssl_NewEphemeralKeyPair(
const sslNamedGroupDef *group,
SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey);
extern sslEphemeralKeyPair *ssl_CopyEphemeralKeyPair(
sslEphemeralKeyPair *keyPair);
extern void ssl_FreeEphemeralKeyPair(sslEphemeralKeyPair *keyPair);
extern sslEphemeralKeyPair *ssl_LookupEphemeralKeyPair(
sslSocket *ss, const sslNamedGroupDef *groupDef);
extern PRBool ssl_HaveEphemeralKeyPair(const sslSocket *ss,
const sslNamedGroupDef *groupDef);
extern void ssl_FreeEphemeralKeyPairs(sslSocket *ss);
extern SECStatus ssl_AppendPaddedDHKeyShare(sslBuffer *buf,
const SECKEYPublicKey *pubKey,
PRBool appendLength);
extern PRBool ssl_CanUseSignatureScheme(SSLSignatureScheme scheme,
const SSLSignatureScheme *peerSchemes,
unsigned int peerSchemeCount,
PRBool requireSha1,
PRBool slotDoesPss);
extern const ssl3DHParams *ssl_GetDHEParams(const sslNamedGroupDef *groupDef);
extern SECStatus ssl_SelectDHEGroup(sslSocket *ss,
const sslNamedGroupDef **groupDef);
extern SECStatus ssl_CreateDHEKeyPair(const sslNamedGroupDef *groupDef,
const ssl3DHParams *params,
sslEphemeralKeyPair **keyPair);
extern PRBool ssl_IsValidDHEShare(const SECItem *dh_p, const SECItem *dh_Ys);
extern SECStatus ssl_ValidateDHENamedGroup(sslSocket *ss,
const SECItem *dh_p,
const SECItem *dh_g,
const sslNamedGroupDef **groupDef,
const ssl3DHParams **dhParams);
extern PRBool ssl_IsECCEnabled(const sslSocket *ss);
extern PRBool ssl_IsDHEEnabled(const sslSocket *ss);
/* Macro for finding a curve equivalent in strength to RSA key's */
((s <= 1024) ? 160 \
: ((s <= 2048) ? 224 \
: ((s <= 3072) ? 256 \
: ((s <= 7168) ? 384 \
: 521))))
extern const sslNamedGroupDef *ssl_LookupNamedGroup(SSLNamedGroup group);
extern PRBool ssl_NamedGroupEnabled(const sslSocket *ss, const sslNamedGroupDef *group);
extern SECStatus ssl_NamedGroup2ECParams(PLArenaPool *arena,
const sslNamedGroupDef *curve,
SECKEYECParams *params);
extern const sslNamedGroupDef *ssl_ECPubKey2NamedGroup(
const SECKEYPublicKey *pubKey);
extern const sslNamedGroupDef *ssl_GetECGroupForServerSocket(sslSocket *ss);
extern void ssl_FilterSupportedGroups(sslSocket *ss);
extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on);
extern SECStatus ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *on);
extern SECStatus ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool on);
extern SECStatus ssl3_CipherPrefGet(const sslSocket *ss, ssl3CipherSuite which, PRBool *on);
extern SECStatus ssl3_SetPolicy(ssl3CipherSuite which, PRInt32 policy);
extern SECStatus ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *policy);
extern void ssl3_InitSocketPolicy(sslSocket *ss);
extern SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache);
extern SECStatus ssl3_HandleHandshakeMessage(sslSocket *ss, PRUint8 *b,
PRUint32 length,
PRBool endOfRecord);
extern void ssl3_DestroySSL3Info(sslSocket *ss);
extern SECStatus ssl_ClientReadVersion(sslSocket *ss, PRUint8 **b,
PRUint32 *length,
SSL3ProtocolVersion *version);
extern SECStatus ssl3_NegotiateVersion(sslSocket *ss,
SSL3ProtocolVersion peerVersion,
PRBool allowLargerPeerVersion);
extern SECStatus ssl_ClientSetCipherSuite(sslSocket *ss,
SSL3ProtocolVersion version,
ssl3CipherSuite suite,
PRBool initHashes);
extern SECStatus ssl_GetPeerInfo(sslSocket *ss);
/* ECDH functions */
extern SECStatus ssl3_SendECDHClientKeyExchange(sslSocket *ss,
SECKEYPublicKey *svrPubKey);
extern SECStatus ssl3_HandleECDHServerKeyExchange(sslSocket *ss,
PRUint8 *b, PRUint32 length);
extern SECStatus ssl3_HandleECDHClientKeyExchange(sslSocket *ss,
PRUint8 *b, PRUint32 length,
sslKeyPair *serverKeys);
extern SECStatus ssl3_SendECDHServerKeyExchange(sslSocket *ss);
extern SECStatus ssl_ImportECDHKeyShare(
SECKEYPublicKey *peerKey,
PRUint8 *b, PRUint32 length, const sslNamedGroupDef *curve);
extern SECStatus ssl3_ComputeCommonKeyHash(SSLHashType hashAlg,
PRUint8 *hashBuf,
unsigned int bufLen,
SSL3Hashes *hashes);
extern SECStatus ssl3_AppendSignatureAndHashAlgorithm(
sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash);
extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRUint32 bytes,
PRUint8 **b, PRUint32 *length);
extern SECStatus ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRUint32 *num,
PRUint32 bytes, PRUint8 **b,
PRUint32 *length);
extern SECStatus ssl3_ConsumeHandshakeNumber64(sslSocket *ss, PRUint64 *num,
PRUint32 bytes, PRUint8 **b,
PRUint32 *length);
extern SECStatus ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i,
PRUint32 bytes, PRUint8 **b,
PRUint32 *length);
extern SECStatus ssl_SignatureSchemeFromSpki(const CERTSubjectPublicKeyInfo *spki,
PRBool isTls13,
SSLSignatureScheme *scheme);
extern PRBool ssl_SignatureSchemeEnabled(const sslSocket *ss,
SSLSignatureScheme scheme);
extern PRBool ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme);
extern SECStatus ssl_CheckSignatureSchemeConsistency(
sslSocket *ss, SSLSignatureScheme scheme, CERTSubjectPublicKeyInfo *spki);
extern SECStatus ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
SSLSignatureScheme **schemesOut,
unsigned int *numSchemesOut,
unsigned char **b,
unsigned int *len);
extern SECStatus ssl_ConsumeSignatureScheme(
sslSocket *ss, PRUint8 **b, PRUint32 *length, SSLSignatureScheme *out);
extern SECStatus ssl3_SignHashesWithPrivKey(SSL3Hashes *hash,
SECKEYPrivateKey *key,
SSLSignatureScheme scheme,
PRBool isTls,
SECItem *buf);
extern SECStatus ssl3_SignHashes(sslSocket *ss, SSL3Hashes *hash,
SECKEYPrivateKey *key, SECItem *buf);
extern SECStatus ssl_VerifySignedHashesWithPubKey(sslSocket *ss,
SECKEYPublicKey *spki,
SSLSignatureScheme scheme,
SSL3Hashes *hash,
SECItem *buf);
extern SECStatus ssl3_VerifySignedHashes(sslSocket *ss, SSLSignatureScheme scheme,
SSL3Hashes *hash, SECItem *buf);
extern SECStatus ssl3_CacheWrappedSecret(sslSocket *ss, sslSessionID *sid,
PK11SymKey *secret);
extern void ssl3_FreeSniNameArray(TLSExtensionData *xtnData);
/* Hello Extension related routines. */
extern void ssl3_SetSIDSessionTicket(sslSessionID *sid,
/*in/out*/ NewSessionTicket *session_ticket);
SECStatus ssl3_EncodeSessionTicket(sslSocket *ss,
const NewSessionTicket *ticket,
const PRUint8 *appToken,
unsigned int appTokenLen,
PK11SymKey *secret, SECItem *ticket_data);
SECStatus SSLExp_SendSessionTicket(PRFileDesc *fd, const PRUint8 *token,
unsigned int tokenLen);
SECStatus ssl_MaybeSetSelfEncryptKeyPair(const sslKeyPair *keyPair);
SECStatus ssl_GetSelfEncryptKeys(sslSocket *ss, unsigned char *keyName,
PK11SymKey **encKey, PK11SymKey **macKey);
void ssl_ResetSelfEncryptKeys();
extern SECStatus ssl3_ValidateAppProtocol(const unsigned char *data,
unsigned int length);
/* 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 SSL3 can initialize the present state of
* various ciphers */
extern unsigned int ssl3_config_match_init(sslSocket *);
/* Return PR_TRUE if suite is usable. This if the suite is permitted by policy,
* enabled, has a certificate (as needed), has a viable key agreement method, is
* usable with the negotiated TLS version, and is otherwise usable. */
PRBool ssl3_config_match(const ssl3CipherSuiteCfg *suite, PRUint8 policy,
const SSLVersionRange *vrange, const sslSocket *ss);
/* calls for accessing wrapping keys across processes. */
extern SECStatus
ssl_GetWrappingKey(unsigned int symWrapMechIndex,
unsigned int wrapKeyIndex, 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 SECStatus
ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk);
/* get rid of the symmetric wrapping key references. */
extern SECStatus SSL3_ShutdownServerCache(void);
extern SECStatus ssl_InitSymWrapKeysLock(void);
extern SECStatus ssl_FreeSymWrapKeysLock(void);
extern SECStatus ssl_InitSessionCacheLocks(PRBool lazyInit);
extern SECStatus ssl_FreeSessionCacheLocks(void);
CK_MECHANISM_TYPE ssl3_Alg2Mech(SSLCipherAlgorithm calg);
SECStatus ssl3_NegotiateCipherSuiteInner(sslSocket *ss, const SECItem *suites,
PRUint16 version, PRUint16 *suitep);
SECStatus ssl3_NegotiateCipherSuite(sslSocket *ss, const SECItem *suites,
PRBool initHashes);
SECStatus ssl3_InitHandshakeHashes(sslSocket *ss);
void ssl3_CoalesceEchHandshakeHashes(sslSocket *ss);
SECStatus ssl3_ServerCallSNICallback(sslSocket *ss);
SECStatus ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags);
SECStatus ssl3_CompleteHandleCertificate(sslSocket *ss,
PRUint8 *b, PRUint32 length);
void ssl3_SendAlertForCertError(sslSocket *ss, PRErrorCode errCode);
SECStatus ssl3_HandleNoCertificate(sslSocket *ss);
SECStatus ssl3_SendEmptyCertificate(sslSocket *ss);
void ssl3_CleanupPeerCerts(sslSocket *ss);
SECStatus ssl3_SendCertificateStatus(sslSocket *ss);
SECStatus ssl_SetAuthKeyBits(sslSocket *ss, const SECKEYPublicKey *pubKey);