зеркало из https://github.com/mozilla/gecko-dev.git
1718 строки
65 KiB
C
1718 строки
65 KiB
C
/* -*- 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 http://mozilla.org/MPL/2.0/. */
|
|
|
|
#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 "sslexp.h"
|
|
#include "ssl3prot.h"
|
|
#include "hasht.h"
|
|
#include "nssilock.h"
|
|
#include "pkcs11t.h"
|
|
#if defined(XP_UNIX) || defined(XP_BEOS)
|
|
#include "unistd.h"
|
|
#endif
|
|
#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;
|
|
#include "sslencode.h"
|
|
#include "sslexp.h"
|
|
#include "ssl3ext.h"
|
|
#include "sslspec.h"
|
|
|
|
#if defined(DEBUG) || defined(TRACE)
|
|
#ifdef __cplusplus
|
|
#define Debug 1
|
|
#else
|
|
extern int Debug;
|
|
#endif
|
|
#else
|
|
#undef Debug
|
|
#endif
|
|
|
|
#if defined(DEBUG) && !defined(TRACE) && !defined(NISCC_TEST)
|
|
#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 PRINT_KEY(a, b) \
|
|
if (ssl_trace >= (a)) \
|
|
ssl_PrintKey b
|
|
#else
|
|
#define SSL_TRC(a, b)
|
|
#define PRINT_BUF(a, b)
|
|
#define PRINT_KEY(a, b)
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
#define SSL_DBG(b) \
|
|
if (ssl_debug) \
|
|
ssl_Trace b
|
|
#else
|
|
#define SSL_DBG(b)
|
|
#endif
|
|
|
|
#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,
|
|
SSLAppOpWrite,
|
|
SSLAppOpRDWR,
|
|
SSLAppOpPost,
|
|
SSLAppOpHeader
|
|
} SSLAppOperation;
|
|
|
|
#define SSL3_SESSIONID_BYTES 32
|
|
|
|
#define SSL_MIN_CHALLENGE_BYTES 16
|
|
#define SSL_MAX_CHALLENGE_BYTES 32
|
|
|
|
#define SSL3_MASTER_SECRET_LENGTH 48
|
|
|
|
/* number of wrap mechanisms potentially used to wrap master secrets. */
|
|
#define SSL_NUM_WRAP_MECHS 15
|
|
#define SSL_NUM_WRAP_KEYS 6
|
|
|
|
/* This makes the cert cache entry exactly 4k. */
|
|
#define SSL_MAX_CACHED_CERT_LEN 4060
|
|
|
|
#ifndef BPB
|
|
#define BPB 8 /* Bits Per Byte */
|
|
#endif
|
|
|
|
/* The default value from RFC 4347 is 1s, which is too slow. */
|
|
#define DTLS_RETRANSMIT_INITIAL_MS 50
|
|
/* The maximum time to wait between retransmissions. */
|
|
#define DTLS_RETRANSMIT_MAX_MS 10000
|
|
/* Time to wait in FINISHED state for retransmissions. */
|
|
#define DTLS_RETRANSMIT_FINISHED_MS 30000
|
|
|
|
/* default number of entries in namedGroupPreferences */
|
|
#define SSL_NAMED_GROUP_COUNT 31
|
|
|
|
/* 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;
|
|
|
|
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);
|
|
void ssl_ServerUncacheSessionID(sslSessionID *sid);
|
|
|
|
typedef sslSessionID *(*sslSessionIDLookupFunc)(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;
|
|
#else
|
|
ssl3CipherSuite cipher_suite;
|
|
PRUint8 policy;
|
|
unsigned char enabled : 1;
|
|
unsigned char isPresent : 1;
|
|
#endif
|
|
} ssl3CipherSuiteCfg;
|
|
|
|
#define ssl_V3_SUITES_IMPLEMENTED 71
|
|
|
|
#define MAX_DTLS_SRTP_CIPHER_SUITES 4
|
|
|
|
/* MAX_SIGNATURE_SCHEMES allows for all the values we support. */
|
|
#define MAX_SIGNATURE_SCHEMES 15
|
|
|
|
typedef struct sslOptionsStr {
|
|
/* If SSL_SetNextProtoNego has been called, then this contains the
|
|
* list of supported protocols. */
|
|
SECItem nextProtoNego;
|
|
|
|
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 enableNPN : 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;
|
|
} sslOptions;
|
|
|
|
typedef enum { sslHandshakingUndetermined = 0,
|
|
sslHandshakingAsClient,
|
|
sslHandshakingAsServer
|
|
} 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 is 13.
|
|
*/
|
|
unsigned char hdr[13];
|
|
|
|
/* 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
|
|
|
|
#define WRAPPED_MASTER_SECRET_SIZE 48
|
|
|
|
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,
|
|
in_client_cache,
|
|
in_server_cache,
|
|
invalid_cache, /* no longer in any cache. */
|
|
in_external_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;
|
|
PRUint8 sessionID[SSL3_SESSIONID_BYTES];
|
|
|
|
ssl3CipherSuite cipherSuite;
|
|
PRUint8 policy;
|
|
ssl3SidKeys keys;
|
|
/* mechanism used to wrap master secret */
|
|
CK_MECHANISM_TYPE masterWrapMech;
|
|
|
|
/* 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 NPN/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 {
|
|
idle_handshake,
|
|
wait_client_hello,
|
|
wait_end_of_early_data,
|
|
wait_client_cert,
|
|
wait_client_key,
|
|
wait_cert_verify,
|
|
wait_change_cipher,
|
|
wait_finished,
|
|
wait_server_hello,
|
|
wait_certificate_status,
|
|
wait_server_cert,
|
|
wait_server_key,
|
|
wait_cert_request,
|
|
wait_hello_done,
|
|
wait_new_session_ticket,
|
|
wait_encrypted_extensions,
|
|
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 */
|
|
SSL3ContentType type; /* The message type */
|
|
unsigned char *data; /* The data */
|
|
PRUint16 len; /* The data length */
|
|
} DTLSQueuedMessage;
|
|
|
|
typedef struct TLS13KeyShareEntryStr {
|
|
PRCList link; /* The linked list link */
|
|
const sslNamedGroupDef *group; /* The group for the entry */
|
|
SECItem key_exchange; /* The share itself */
|
|
} TLS13KeyShareEntry;
|
|
|
|
typedef struct TLS13EarlyDataStr {
|
|
PRCList link; /* The linked list link */
|
|
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 */
|
|
handshake_hash_record
|
|
} SSL3HandshakeHashType;
|
|
|
|
// A DTLS Timer.
|
|
typedef void (*DTLSTimerCb)(sslSocket *);
|
|
|
|
typedef struct {
|
|
const char *label;
|
|
DTLSTimerCb cb;
|
|
PRIntervalTime started;
|
|
PRUint32 timeout;
|
|
} dtlsTimer;
|
|
|
|
/*
|
|
** 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; /* 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 */
|
|
/* 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|, for SHA-256. */
|
|
PK11Context *md5;
|
|
PK11Context *sha;
|
|
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 */
|
|
sslBuffer msgState; /* current state for handshake messages*/
|
|
/* protected by recvBufLock */
|
|
|
|
/* 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;
|
|
|
|
PRBool authCertificatePending;
|
|
/* Which function should SSL_RestartHandshake* call if we're blocked?
|
|
* One of NULL, ssl3_SendClientSecondRound, ssl3_FinishHandshake,
|
|
* or ssl3_AlwaysFail */
|
|
sslRestartTarget restartTarget;
|
|
/* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */
|
|
PRBool cacheSID;
|
|
|
|
PRBool canFalseStart; /* Can/did we False Start */
|
|
/* Which preliminaryinfo values have been set. */
|
|
PRUint32 preliminaryInfo;
|
|
|
|
/* Parsed extensions */
|
|
PRCList remoteExtensions; /* Parsed incoming extensions */
|
|
|
|
/* 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 PSK. */
|
|
PK11SymKey *dheSecret; /* The (EC)DHE shared secret. */
|
|
PK11SymKey *pskBinderKey; /* Used to compute the PSK binder. */
|
|
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 clientCertRequested; /* True if CertificateRequest received. */
|
|
ssl3KEADef kea_def_mutable; /* Used to hold the writable kea_def
|
|
* we use for TLS 1.3 */
|
|
PRTime serverHelloTime; /* Time the ServerHello flight was sent. */
|
|
PRUint16 ticketNonce; /* A counter we use for tickets. */
|
|
SECItem fakeSid; /* ... (server) the SID the client used. */
|
|
PRBool endOfFlight; /* Processed a full flight (DTLS 1.3). */
|
|
|
|
/* 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. */
|
|
} SSL3HandshakeState;
|
|
|
|
#define SSL_ASSERT_HASHES_EMPTY(ss) \
|
|
do { \
|
|
PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_unknown); \
|
|
PORT_Assert(ss->ssl3.hs.messages.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;
|
|
|
|
/* Internal callback for when we do a cipher suite change. Used for
|
|
* debugging in TLS 1.3. This can only be set by non-public functions. */
|
|
sslCipherSpecChangedFunc changedCipherSpecFunc;
|
|
void *changedCipherSpecArg;
|
|
|
|
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
|
|
* be either SSL_ALLOWED or SSL_RESTRICTED
|
|
*/
|
|
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 dtlsSRTPCiphers[MAX_DTLS_SRTP_CIPHER_SUITES];
|
|
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 {
|
|
SSL3ContentType type;
|
|
SSL3ProtocolVersion version;
|
|
sslSequenceNumber seq_num; /* DTLS only */
|
|
sslBuffer *buf;
|
|
} SSL3Ciphertext;
|
|
|
|
struct sslKeyPairStr {
|
|
SECKEYPrivateKey *privKey;
|
|
SECKEYPublicKey *pubKey;
|
|
PRInt32 refCount; /* use PR_Atomic calls for this. */
|
|
};
|
|
|
|
typedef struct {
|
|
PRCList link;
|
|
const sslNamedGroupDef *group;
|
|
sslKeyPair *keys;
|
|
} sslEphemeralKeyPair;
|
|
|
|
struct ssl3DHParamsStr {
|
|
SSLNamedGroup name;
|
|
SECItem prime; /* p */
|
|
SECItem base; /* g */
|
|
};
|
|
|
|
typedef struct SSLWrappedSymWrappingKeyStr {
|
|
PRUint8 wrappedSymmetricWrappingkey[512];
|
|
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;
|
|
CK_MECHANISM_TYPE msWrapMech;
|
|
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->sec.ci".
|
|
**
|
|
** 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;
|
|
|
|
/* 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;
|
|
|
|
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;
|
|
};
|
|
|
|
struct sslSelfEncryptKeysStr {
|
|
PRCallOnceType setup;
|
|
PRUint8 keyName[SELF_ENCRYPT_KEY_NAME_LEN];
|
|
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;
|
|
extern PRUint32 ssl3_sid_timeout;
|
|
extern PRUint32 ssl_ticket_lifetime;
|
|
extern PRUint32 ssl_max_early_data_size;
|
|
|
|
extern const char *const ssl3_cipherName[];
|
|
|
|
extern sslSessionIDLookupFunc ssl_sid_lookup;
|
|
|
|
extern const sslNamedGroupDef ssl_named_groups[];
|
|
|
|
/************************************************************************/
|
|
|
|
SEC_BEGIN_PROTOS
|
|
|
|
/* 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 int ssl_Do1stHandshake(sslSocket *ss);
|
|
|
|
extern SECStatus ssl3_InitPendingCipherSpecs(sslSocket *ss, PK11SymKey *secret,
|
|
PRBool derive);
|
|
extern sslSessionID *ssl3_NewSessionID(sslSocket *ss, PRBool is_server);
|
|
extern sslSessionID *ssl_LookupSID(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 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 void 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, int *outputLen,
|
|
int maxOutputLen, const unsigned char *input,
|
|
int inputLen);
|
|
extern void ssl3_RestartHandshakeHashes(sslSocket *ss);
|
|
extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket *ss,
|
|
const unsigned char *b,
|
|
unsigned int l);
|
|
SECStatus
|
|
ssl_HashHandshakeMessageInt(sslSocket *ss, SSLHandshakeType type,
|
|
PRUint32 dtlsSeq,
|
|
const PRUint8 *b, PRUint32 length);
|
|
SECStatus ssl_HashHandshakeMessage(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,
|
|
SSL3ContentType 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) \
|
|
PZ_Lock(ss->recvLock)
|
|
#define SSL_UNLOCK_READER(ss) \
|
|
if (ss->recvLock) \
|
|
PZ_Unlock(ss->recvLock)
|
|
#define SSL_LOCK_WRITER(ss) \
|
|
if (ss->sendLock) \
|
|
PZ_Lock(ss->sendLock)
|
|
#define SSL_UNLOCK_WRITER(ss) \
|
|
if (ss->sendLock) \
|
|
PZ_Unlock(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) \
|
|
(PZ_InMonitor((ss)->firstHandshakeLock))
|
|
|
|
/* 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) \
|
|
(PZ_InMonitor((ss)->ssl3HandshakeLock))
|
|
|
|
#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) \
|
|
(NSSRWLock_HaveWriteLock((ss)->specLock))
|
|
|
|
/* 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) \
|
|
(PZ_InMonitor((ss)->recvBufLock))
|
|
|
|
/* 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) \
|
|
(PZ_InMonitor((ss)->xmitBufLock))
|
|
|
|
/* Placeholder value used in version ranges when SSL 3.0 and all
|
|
* versions of TLS are disabled.
|
|
*/
|
|
#define SSL_LIBRARY_VERSION_NONE 0
|
|
|
|
/* 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.
|
|
*/
|
|
#define SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM SSL_LIBRARY_VERSION_TLS_1_1
|
|
#define SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM SSL_LIBRARY_VERSION_3_0
|
|
|
|
/* 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
|
|
#define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_3
|
|
#else
|
|
#define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_2
|
|
#endif
|
|
|
|
#define SSL_ALL_VERSIONS_DISABLED(vrange) \
|
|
((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);
|
|
|
|
/*
|
|
* 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);
|
|
|
|
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, sslBuffer *out);
|
|
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 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 */
|
|
#define SSL_RSASTRENGTH_TO_ECSTRENGTH(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(
|
|
sslSocket *ss, 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 PRBool ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme);
|
|
extern SECStatus ssl_CheckSignatureSchemeConsistency(
|
|
sslSocket *ss, SSLSignatureScheme scheme, CERTCertificate *cert);
|
|
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_SignHashes(sslSocket *ss, SSL3Hashes *hash,
|
|
SECKEYPrivateKey *key, 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_ValidateNextProtoNego(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 *);
|
|
|
|
/* 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_NegotiateCipherSuite(sslSocket *ss, const SECItem *suites,
|
|
PRBool initHashes);
|
|
SECStatus ssl3_InitHandshakeHashes(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 ssl3_AuthCertificate(sslSocket *ss);
|
|
SECStatus ssl_ReadCertificateStatus(sslSocket *ss, PRUint8 *b,
|
|
PRUint32 length);
|
|
SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, sslBuffer *buf);
|
|
SECStatus ssl_GetCertificateRequestCAs(const sslSocket *ss,
|
|
unsigned int *calenp,
|
|
const SECItem **namesp,
|
|
unsigned int *nnamesp);
|
|
SECStatus ssl3_ParseCertificateRequestCAs(sslSocket *ss, PRUint8 **b,
|
|
PRUint32 *length, CERTDistNames *ca_list);
|
|
SECStatus ssl3_CompleteHandleCertificateRequest(
|
|
sslSocket *ss, const SSLSignatureScheme *signatureSchemes,
|
|
unsigned int signatureSchemeCount, CERTDistNames *ca_list);
|
|
SECStatus ssl_ConstructServerHello(sslSocket *ss, PRBool helloRetry,
|
|
const sslBuffer *extensionBuf,
|
|
sslBuffer *messageBuf);
|
|
SECStatus ssl3_SendServerHello(sslSocket *ss);
|
|
SECStatus ssl3_SendChangeCipherSpecsInt(sslSocket *ss);
|
|
SECStatus ssl3_ComputeHandshakeHashes(sslSocket *ss,
|
|
ssl3CipherSpec *spec,
|
|
SSL3Hashes *hashes,
|
|
PRUint32 sender);
|
|
SECStatus ssl_CreateECDHEphemeralKeyPair(const sslSocket *ss,
|
|
const sslNamedGroupDef *ecGroup,
|
|
sslEphemeralKeyPair **keyPair);
|
|
SECStatus ssl_CreateStaticECDHEKey(sslSocket *ss,
|
|
const sslNamedGroupDef *ecGroup);
|
|
SECStatus ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags);
|
|
PK11SymKey *ssl3_GetWrappingKey(sslSocket *ss,
|
|
PK11SlotInfo *masterSecretSlot,
|
|
CK_MECHANISM_TYPE masterWrapMech,
|
|
void *pwArg);
|
|
SECStatus ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid,
|
|
PK11SymKey *secret);
|
|
const ssl3CipherSuiteDef *ssl_LookupCipherSuiteDef(ssl3CipherSuite suite);
|
|
SECStatus ssl3_SelectServerCert(sslSocket *ss);
|
|
SECStatus ssl_PickSignatureScheme(sslSocket *ss,
|
|
SECKEYPublicKey *pubKey,
|
|
SECKEYPrivateKey *privKey,
|
|
const SSLSignatureScheme *peerSchemes,
|
|
unsigned int peerSchemeCount,
|
|
PRBool requireSha1);
|
|
SECOidTag ssl3_HashTypeToOID(SSLHashType hashType);
|
|
SSLHashType ssl_SignatureSchemeToHashType(SSLSignatureScheme scheme);
|
|
KeyType ssl_SignatureSchemeToKeyType(SSLSignatureScheme scheme);
|
|
|
|
SECStatus ssl3_SetupCipherSuite(sslSocket *ss, PRBool initHashes);
|
|
|
|
/* Pull in DTLS functions */
|
|
#include "dtlscon.h"
|
|
|
|
/* Pull in TLS 1.3 functions */
|
|
#include "tls13con.h"
|
|
#include "dtls13con.h"
|
|
|
|
/********************** misc calls *********************/
|
|
|
|
#ifdef DEBUG
|
|
extern void ssl3_CheckCipherSuiteOrderConsistency();
|
|
#endif
|
|
|
|
extern int ssl_MapLowLevelError(int hiLevelError);
|
|
|
|
extern PRUint32 ssl_TimeSec(void);
|
|
#ifdef UNSAFE_FUZZER_MODE
|
|
#define ssl_TimeUsec() ((PRTime)12345678)
|
|
#else
|
|
#define ssl_TimeUsec() (PR_Now())
|
|
#endif
|
|
extern PRBool ssl_TicketTimeValid(const NewSessionTicket *ticket);
|
|
|
|
extern void SSL_AtomicIncrementLong(long *x);
|
|
|
|
SECStatus ssl3_ApplyNSSPolicy(void);
|
|
|
|
extern SECStatus
|
|
ssl3_TLSPRFWithMasterSecret(sslSocket *ss, ssl3CipherSpec *spec,
|
|
const char *label, unsigned int labelLen,
|
|
const unsigned char *val, unsigned int valLen,
|
|
unsigned char *out, unsigned int outLen);
|
|
|
|
extern void
|
|
ssl3_RecordKeyLog(sslSocket *ss, const char *label, PK11SymKey *secret);
|
|
|
|
PRBool ssl_AlpnTagAllowed(const sslSocket *ss, const SECItem *tag);
|
|
|
|
#ifdef TRACE
|
|
#define SSL_TRACE(msg) ssl_Trace msg
|
|
#else
|
|
#define SSL_TRACE(msg)
|
|
#endif
|
|
|
|
void ssl_Trace(const char *format, ...);
|
|
|
|
void ssl_CacheExternalToken(sslSocket *ss);
|
|
SECStatus ssl_DecodeResumptionToken(sslSessionID *sid, const PRUint8 *encodedTicket,
|
|
PRUint32 encodedTicketLen);
|
|
PRBool ssl_IsResumptionTokenValid(sslSocket *ss);
|
|
|
|
/* Remove when stable. */
|
|
|
|
SECStatus SSLExp_SetResumptionTokenCallback(PRFileDesc *fd,
|
|
SSLResumptionTokenCallback cb,
|
|
void *ctx);
|
|
SECStatus SSLExp_SetResumptionToken(PRFileDesc *fd, const PRUint8 *token,
|
|
unsigned int len);
|
|
|
|
SECStatus SSLExp_GetResumptionTokenInfo(const PRUint8 *tokenData, unsigned int tokenLen,
|
|
SSLResumptionTokenInfo *token, unsigned int version);
|
|
|
|
SECStatus SSLExp_DestroyResumptionTokenInfo(SSLResumptionTokenInfo *token);
|
|
|
|
#define SSLResumptionTokenVersion 1
|
|
|
|
SEC_END_PROTOS
|
|
|
|
#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
|
|
#define SSL_GETPID getpid
|
|
#elif defined(WIN32)
|
|
extern int __cdecl _getpid(void);
|
|
#define SSL_GETPID _getpid
|
|
#else
|
|
#define SSL_GETPID() 0
|
|
#endif
|
|
|
|
#endif /* __sslimpl_h_ */
|