ssl3gthr.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:7k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * Gather (Read) entire SSL3 records from socket into buffer.  
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public
  5.  * License Version 1.1 (the "License"); you may not use this file
  6.  * except in compliance with the License. You may obtain a copy of
  7.  * the License at http://www.mozilla.org/MPL/
  8.  * 
  9.  * Software distributed under the License is distributed on an "AS
  10.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  11.  * implied. See the License for the specific language governing
  12.  * rights and limitations under the License.
  13.  * 
  14.  * The Original Code is the Netscape security libraries.
  15.  * 
  16.  * The Initial Developer of the Original Code is Netscape
  17.  * Communications Corporation.  Portions created by Netscape are 
  18.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  19.  * Rights Reserved.
  20.  * 
  21.  * Contributor(s):
  22.  * 
  23.  * Alternatively, the contents of this file may be used under the
  24.  * terms of the GNU General Public License Version 2 or later (the
  25.  * "GPL"), in which case the provisions of the GPL are applicable 
  26.  * instead of those above.  If you wish to allow use of your 
  27.  * version of this file only under the terms of the GPL and not to
  28.  * allow others to use your version of this file under the MPL,
  29.  * indicate your decision by deleting the provisions above and
  30.  * replace them with the notice and other provisions required by
  31.  * the GPL.  If you do not delete the provisions above, a recipient
  32.  * may use your version of this file under either the MPL or the
  33.  * GPL.
  34.  *
  35.  * $Id: ssl3gthr.c,v 1.2.2.1 2000/12/02 01:01:15 nelsonb%netscape.com Exp $
  36.  */
  37. #include "cert.h"
  38. #include "ssl.h"
  39. #include "sslimpl.h"
  40. #include "ssl3prot.h"
  41. /* 
  42.  * Attempt to read in an entire SSL3 record.
  43.  * Blocks here for blocking sockets, otherwise returns -1 with 
  44.  *  PR_WOULD_BLOCK_ERROR when socket would block.
  45.  *
  46.  * returns  1 if received a complete SSL3 record.
  47.  * returns  0 if recv returns EOF
  48.  * returns -1 if recv returns <0  
  49.  * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
  50.  *
  51.  * Caller must hold the recv buf lock.
  52.  *
  53.  * The Gather state machine has 3 states:  GS_INIT, GS_HEADER, GS_DATA.
  54.  * GS_HEADER: waiting for the 5-byte SSL3 record header to come in.
  55.  * GS_DATA:   waiting for the body of the SSL3 record   to come in.
  56.  *
  57.  * This loop returns when either (a) an error or EOF occurs, 
  58.  * (b) PR_WOULD_BLOCK_ERROR,
  59.  *  (c) data (entire SSL3 record) has been received.
  60.  */
  61. static int
  62. ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
  63. {
  64.     unsigned char *bp;
  65.     unsigned char *lbp;
  66.     int            nb;
  67.     int            err;
  68.     int            rv = 1;
  69.     PORT_Assert( ssl_HaveRecvBufLock(ss) );
  70.     if (gs->state == GS_INIT) {
  71. gs->state       = GS_HEADER;
  72. gs->remainder   = 5;
  73. gs->offset      = 0;
  74. gs->writeOffset = 0;
  75. gs->readOffset  = 0;
  76. gs->inbuf.len   = 0;
  77.     }
  78.     
  79.     lbp = gs->inbuf.buf;
  80.     for(;;) {
  81. SSL_TRC(30, ("%d: SSL3[%d]: gather state %d (need %d more)",
  82. SSL_GETPID(), ss->fd, gs->state, gs->remainder));
  83. bp = ((gs->state != GS_HEADER) ? lbp : gs->hdr) + gs->offset;
  84. nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
  85. if (nb > 0) {
  86.     PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
  87. } else if (nb == 0) {
  88.     /* EOF */
  89.     SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
  90.     rv = 0;
  91.     break;
  92. } else /* if (nb < 0) */ {
  93.     SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
  94.      PR_GetError()));
  95.     rv = SECFailure;
  96.     break;
  97. }
  98. PORT_Assert( nb <= gs->remainder );
  99. if (nb > gs->remainder) {
  100.     /* ssl_DefRecv is misbehaving!  this error is fatal to SSL. */
  101.     gs->state = GS_INIT;         /* so we don't crash next time */
  102.     rv = SECFailure;
  103.     break;
  104. }
  105. gs->offset    += nb;
  106. gs->remainder -= nb;
  107. if (gs->state == GS_DATA)
  108.     gs->inbuf.len += nb;
  109. /* if there's more to go, read some more. */
  110. if (gs->remainder > 0) {
  111.     continue;
  112. }
  113. /* have received entire record header, or entire record. */
  114. switch (gs->state) {
  115. case GS_HEADER:
  116.     /*
  117.     ** Have received SSL3 record header in gs->hdr.
  118.     ** Now extract the length of the following encrypted data, 
  119.     ** and then read in the rest of the SSL3 record into gs->inbuf.
  120.     */
  121.     gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
  122.     /* This is the max fragment length for an encrypted fragment
  123.     ** plus the size of the record header.
  124.     */
  125.     if(gs->remainder > (MAX_FRAGMENT_LENGTH + 2048 + 5)) {
  126. SSL3_SendAlert(ss, alert_fatal, unexpected_message);
  127. gs->state = GS_INIT;
  128. PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
  129. return SECFailure;
  130.     }
  131.     gs->state     = GS_DATA;
  132.     gs->offset    = 0;
  133.     gs->inbuf.len = 0;
  134.     if (gs->remainder > gs->inbuf.space) {
  135. err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
  136. if (err) { /* realloc has set error code to no mem. */
  137.     return err;
  138. }
  139. lbp = gs->inbuf.buf;
  140.     }
  141.     break; /* End this case.  Continue around the loop. */
  142. case GS_DATA:
  143.     /* 
  144.     ** SSL3 record has been completely received.
  145.     */
  146.     gs->state = GS_INIT;
  147.     return 1;
  148. }
  149.     }
  150.     return rv;
  151. }
  152. /* Gather in a record and when complete, Handle that record.
  153.  * Repeat this until the handshake is complete, 
  154.  * or until application data is available.
  155.  *
  156.  * Returns  1 when the handshake is completed without error, or 
  157.  *                 application data is available.
  158.  * Returns  0 if ssl3_GatherData hits EOF.
  159.  * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
  160.  * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
  161.  *
  162.  * Called from ssl_GatherRecord1stHandshake       in sslcon.c, 
  163.  *    and from SSL_ForceHandshake in sslsecur.c
  164.  *    and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c).
  165.  *
  166.  * Caller must hold the recv buf lock.
  167.  */
  168. int
  169. ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
  170. {
  171.     sslGather *    gs        = ss->gather;
  172.     SSL3Ciphertext cText;
  173.     int            rv;
  174.     PORT_Assert( ssl_HaveRecvBufLock(ss) );
  175.     do {
  176. /* bring in the next sslv3 record. */
  177. rv = ssl3_GatherData(ss, gs, flags);
  178. if (rv <= 0) {
  179.     return rv;
  180. }
  181. /* decipher it, and handle it if it's a handshake. 
  182.  * If it's application data, gs->buf will not be empty upon return. 
  183.  */
  184. cText.type    = (SSL3ContentType)gs->hdr[0];
  185. cText.version = (gs->hdr[1] << 8) | gs->hdr[2];
  186. cText.buf     = &gs->inbuf;
  187. rv = ssl3_HandleRecord(ss, &cText, &gs->buf);
  188. if (rv < 0) {
  189.     return ss->recvdCloseNotify ? 0 : rv;
  190. }
  191.     } while (ss->ssl3->hs.ws != idle_handshake && gs->buf.len == 0);
  192.     gs->readOffset = 0;
  193.     gs->writeOffset = gs->buf.len;
  194.     return 1;
  195. }
  196. /* Repeatedly gather in a record and when complete, Handle that record.
  197.  * Repeat this until some application data is received.
  198.  *
  199.  * Returns  1 when application data is available.
  200.  * Returns  0 if ssl3_GatherData hits EOF.
  201.  * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
  202.  * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
  203.  *
  204.  * Called from DoRecv in sslsecur.c
  205.  * Caller must hold the recv buf lock.
  206.  */
  207. int
  208. ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
  209. {
  210.     sslGather *    gs       = ss->gather;
  211.     int            rv;
  212.     PORT_Assert( ssl_HaveRecvBufLock(ss) );
  213.     do {
  214. rv = ssl3_GatherCompleteHandshake(ss, flags);
  215.     } while (rv > 0 && gs->buf.len == 0);
  216.     return rv;
  217. }