Chromium Code Reviews| Index: net/third_party/nss/ssl/sslimpl.h |
| =================================================================== |
| --- net/third_party/nss/ssl/sslimpl.h (revision 127709) |
| +++ net/third_party/nss/ssl/sslimpl.h (working copy) |
| @@ -62,6 +62,7 @@ |
| #endif |
| #include "nssrwlk.h" |
| #include "prthread.h" |
| +#include "prclist.h" |
| #include "sslt.h" /* for some formerly private types, now public */ |
| @@ -195,6 +196,10 @@ |
| #define EXPORT_RSA_KEY_LENGTH 64 /* bytes */ |
| +#define INITIAL_DTLS_TIMEOUT_MS 1000 /* Default value from RFC 4347 = 1s*/ |
| +#define MAX_DTLS_TIMEOUT_MS 60000 /* 1 minute */ |
| +#define DTLS_FINISHED_TIMER 120000 /* Time to wait in FINISHED state */ |
|
wtc
2012/03/21 01:22:07
DTLS_FINISHED_TIMER is larger than MAX_DTLS_TIMEOU
wtc
2012/03/21 01:22:07
Nit: it would be nice to standardize on one of "TI
ekr
2012/03/21 01:36:40
No. MAX_DTLS_TIMEOUT_MS is the biggest timer we ba
ekr
2012/03/21 01:36:40
Good point.
|
| + |
| typedef struct sslBufferStr sslBuffer; |
| typedef struct sslConnectInfoStr sslConnectInfo; |
| typedef struct sslGatherStr sslGather; |
| @@ -287,6 +292,8 @@ |
| /* 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_USE_EPOCH 0x10000000 /* DTLS only */ |
| +#define ssl_SEND_FLAG_NO_RETRANSMIT 0x08000000 /* DTLS only */ |
| #define ssl_SEND_FLAG_MASK 0x7f000000 |
| /* |
| @@ -382,6 +389,7 @@ |
| #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. |
| @@ -448,8 +456,15 @@ |
| ** The portion of the SSL record header put here always comes off the wire |
| ** as plaintext, never ciphertext. |
| ** For SSL2, the plaintext portion is two bytes long. For SSl3 it is 5. |
| - */ |
| - unsigned char hdr[5]; /* ssl 2 & 3 */ |
| + ** For DTLS it is 13 |
| + */ |
| + unsigned char hdr[13]; /* ssl 2 & 3, or dtls */ |
| + |
| + /* 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; |
| }; |
| /* sslGather.state */ |
| @@ -521,6 +536,10 @@ |
| PRUint32 low; |
| } SSL3SequenceNumber; |
| +typedef PRUint16 DTLSEpoch; |
| + |
| +typedef void (*DtlsTimerCb)(sslSocket *); |
| + |
| #define MAX_MAC_CONTEXT_BYTES 400 |
| #define MAX_MAC_CONTEXT_LLONGS (MAX_MAC_CONTEXT_BYTES / 8) |
| @@ -547,6 +566,21 @@ |
| PRUint64 cipher_context[MAX_CIPHER_CONTEXT_LLONGS]; |
| } ssl3KeyMaterial; |
| + |
| +/* The DTLS anti-replay window. Defined here because we need it in |
| + the cipher spec. Note that this is a ring buffer but left and |
| + right represent the true window, with modular arithmetic |
| + used to mape them onto the buffer. |
| +*/ |
| +#define DTLS_RECVD_RECORDS_WINDOW 1024 /* Packets; approximate |
| + * Must be divisible by 8 |
| + **/ |
| +typedef struct DTLSRecvdRecordsStr { |
| + unsigned char data[DTLS_RECVD_RECORDS_WINDOW/8]; |
| + PRUint64 left; |
| + PRUint64 right; |
| +} DTLSRecvdRecords; |
| + |
| /* |
| ** These are the "specs" in the "ssl3" struct. |
| ** Access to the pointers to these specs, and all the specs' contents |
| @@ -582,6 +616,8 @@ |
| SECItem srvVirtName; /* for server: name that was negotiated |
| * with a client. For client - is |
| * always set to NULL.*/ |
| + DTLSEpoch epoch; |
| + DTLSRecvdRecords recvdRecords; |
| } ssl3CipherSpec; |
| typedef enum { never_cached, |
| @@ -777,6 +813,17 @@ |
| typedef SECStatus (*sslRestartTarget)(sslSocket *); |
| /* |
| +** A DTLS Queued message (potentially to be retransmitted) |
| +*/ |
| +typedef struct DTLSQueuedMessageStr { |
| + PRCList link; /* The linked list link */ |
| + DTLSEpoch epoch; /* The epoch to use */ |
| + SSL3ContentType type; /* The message type */ |
| + unsigned char *data; /* The data */ |
| + PRUint16 len; /* The data length */ |
| +} DTLSQueuedMessage; |
| + |
| +/* |
| ** This is the "hs" member of the "ssl3" struct. |
| ** This entire struct is protected by ssl3HandshakeLock |
| */ |
| @@ -831,6 +878,25 @@ |
| sslRestartTarget restartTarget; |
| /* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */ |
| PRBool cacheSID; |
| + |
| + /* This group of values is used for DTLS */ |
| + PRUint16 sendMessageSeq; /* The sending message sequence number*/ |
| + PRCList * lastMessageFlight; /* The last message flight we sent. This |
| + * is a pointer because ssl_FreeSocket |
| + * relocates the structure in DEBUG mode |
| + * which messes up the list macros */ |
| + 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. */ |
| + unsigned char cookie[32]; /* The cookie */ |
| + unsigned char cookieLen; /* The length of the cookie*/ |
| + PRIntervalTime rtTimerStarted; /* When the timer was started */ |
| + DtlsTimerCb rtTimerCb; /* The timer to call on expiry */ |
|
wtc
2012/03/21 01:22:07
Nit: this comment should read "The function to cal
ekr
2012/03/21 01:36:40
Agreed.
|
| + PRUint32 rtTimeoutMs; /* The length of the current timeout |
| + * used for backoff (in ms)*/ |
| + PRUint32 rtRetries; /* The retry counter */ |
|
wtc
2012/03/21 01:22:07
In the names of these members, "rt" stands for "re
ekr
2012/03/21 01:36:40
Correct.
|
| } SSL3HandshakeState; |
| @@ -882,11 +948,18 @@ |
| */ |
| SECItem nextProto; |
| SSLNextProtoState nextProtoState; |
| + PRUint16 mtu; /* Our estimate of the MTU */ |
| }; |
| +#define DTLS_MAX_MTU (1500) /* Ethernet MTU but without subtracting the headers, |
| + * so slightly larger than expected */ |
| +#define IS_DTLS(ss) (ss->protocolVariant == ssl_variant_datagram) |
| + |
| + |
| typedef struct { |
| SSL3ContentType type; |
| SSL3ProtocolVersion version; |
| + SSL3SequenceNumber seq_num; /* DTLS only */ |
| sslBuffer * buf; |
| } SSL3Ciphertext; |
| @@ -1083,7 +1156,6 @@ |
| /* 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 (in ssl3) ssl3HandshakeLock. */ |
| @@ -1188,6 +1260,9 @@ |
| /* True when the current session is a stateless resume. */ |
| PRBool statelessResume; |
| TLSExtensionData xtnData; |
| + |
| + /* Whether we are doing stream or datagram mode */ |
| + SSLProtocolVariant protocolVariant; |
| }; |
| @@ -1321,7 +1396,28 @@ |
| extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled); |
| extern PRBool ssl3_CanFalseStart(sslSocket *ss); |
| +extern PRInt32 ssl3_SendRecord(sslSocket *ss, DTLSEpoch epoch, |
| + SSL3ContentType type, |
| + const SSL3Opaque* pIn, PRInt32 nIn, |
| + PRInt32 flags); |
| +#ifdef NSS_ENABLE_ZLIB |
| +/* |
| + * The DEFLATE algorithm can result in an expansion of 0.1% + 12 bytes. For a |
| + * maximum TLS record payload of 2**14 bytes, that's 29 bytes. |
| + */ |
| +#define SSL3_COMPRESSION_MAX_EXPANSION 29 |
| +#else /* !NSS_ENABLE_ZLIB */ |
| +#define SSL3_COMPRESSION_MAX_EXPANSION 0 |
| +#endif |
| + |
| +/* |
| + * make sure there is room in the write buffer for padding and |
| + * other compression and cryptographic expansions. |
| + */ |
| +#define SSL3_BUFFER_FUDGE 100 + SSL3_COMPRESSION_MAX_EXPANSION |
| + |
| + |
| #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) |
| @@ -1436,7 +1532,7 @@ |
| /* |
| * SSL3 specific routines |
| */ |
| -SECStatus ssl3_SendClientHello(sslSocket *ss); |
| +SECStatus ssl3_SendClientHello(sslSocket *ss, PRBool resending); |
| /* |
| * input into the SSL3 machinery from the actualy network reading code |
| @@ -1531,6 +1627,8 @@ |
| unsigned char *cs, int *size); |
| extern SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache); |
| +extern SECStatus ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, |
| + PRUint32 length); |
| extern void ssl3_DestroySSL3Info(sslSocket *ss); |
| @@ -1680,6 +1778,9 @@ |
| SSL3KEAType exchKeyType, |
| SSLWrappedSymWrappingKey *wswk); |
| +/* Generate an error */ |
| +extern SECStatus ssl3_DecodeError(sslSocket *ss); |
| + |
| /* 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 |
| @@ -1724,6 +1825,41 @@ |
| CERTCertList* list); |
| #endif /* NSS_PLATFORM_CLIENT_AUTH */ |
| +/**************** DTLS-specific functions **************/ |
| +extern void dtls_FreeQueuedMessage(DTLSQueuedMessage *msg); |
| +extern void dtls_FreeQueuedMessages(PRCList *lst); |
| +extern void dtls_FreeHandshakeMessages(PRCList *lst); |
| + |
| +extern SECStatus dtls_HandleHandshake(sslSocket *ss, |
| + sslBuffer *origBuf); |
| +extern SECStatus dtls_HandleHelloVerifyRequest(sslSocket *ss, |
| + SSL3Opaque *b, PRUint32 length); |
| +extern SECStatus dtls_StageHandshakeMessage(sslSocket *ss); |
| +extern SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type, |
| + const SSL3Opaque *pIn, PRInt32 nIn); |
| +extern SECStatus dtls_FlushHandshakeMessages(sslSocket *ss, |
| + PRInt32 flags); |
| +extern SECStatus dtls_CompressMACEncryptRecord(sslSocket *ss, |
| + DTLSEpoch epoch, PRBool use_epoch, |
| + SSL3ContentType type, const SSL3Opaque * pIn, |
| + PRUint32 contentLen, |
| + sslBuffer * wrBuf); |
| +SECStatus ssl3_DisableNonDTLSSuites(sslSocket * ss); |
| +extern SECStatus dtls_StartTimer(sslSocket *ss, DtlsTimerCb cb); |
| +extern SECStatus dtls_RestartTimer(sslSocket *ss, PRBool backoff, |
| + DtlsTimerCb cb); |
| +extern void dtls_CheckTimer(sslSocket *ss); |
| +extern void dtls_CancelTimer(sslSocket *ss); |
| +extern void dtls_FinishedTimerCb(sslSocket *ss); |
| +extern void dtls_SetMTU(sslSocket *ss, PRUint16 advertised); |
| +extern void dtls_InitRecvdRecords(DTLSRecvdRecords *records); |
| +extern int dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq); |
| +extern void dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq); |
| +extern SSL3ProtocolVersion |
| +dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion ttlsv); |
| +extern SSL3ProtocolVersion |
| +dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv); |
| + |
| /********************** misc calls *********************/ |
| extern int ssl_MapLowLevelError(int hiLevelError); |
| @@ -1735,13 +1871,28 @@ |
| SECStatus SSL_DisableDefaultExportCipherSuites(void); |
| SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd); |
| PRBool SSL_IsExportCipherSuite(PRUint16 cipherSuite); |
| - |
| extern SECStatus |
| ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, |
| const char *label, unsigned int labelLen, |
| const unsigned char *val, unsigned int valLen, |
| unsigned char *out, unsigned int outLen); |
| + |
| +/****************** Exposed for DTLS ********************/ |
| +extern SECStatus |
| +ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec, |
| + PRBool isServer, |
| + PRBool isDtls, |
| + SSL3ContentType type, |
| + const SSL3Opaque * pIn, |
| + PRUint32 contentLen, |
| + sslBuffer * wrBuf); |
| +extern void ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName); |
| +extern const ssl3CipherSuiteDef *ssl_LookupCipherSuiteDef(ssl3CipherSuite |
| + suite); |
| +extern void dtls_RehandshakeCleanup(sslSocket *ss); |
| + |
| + |
| #ifdef TRACE |
| #define SSL_TRACE(msg) ssl_Trace msg |
| #else |