atlsrecordstage.java
来自「ATLS原代码库,实现的很不错 ATLS原代码库,实现的很不错」· Java 代码 · 共 517 行 · 第 1/2 页
JAVA
517 行
if (DEBUG) System.err.println ("aTLSRecordStage: DONE Calling recordReader()"); if (records.isEmpty()) { if (DEBUG) System.err.println ("aTLSRecordStage: recordReader returned null, so not enough info to generate a Record yet."); // not enough data to generate an entire record yet. return; } while (!records.isEmpty()) { // multiple records could have been sent in one packet, so need to handle all of them individually aTLSRecord record = (aTLSRecord) records.removeFirst(); if (record instanceof aTLSCipherSpecRecord) { changeCipherSpecMessage(atlsconn, record); } else if (record instanceof aTLSAlertRecord) { alertMessage(atlsconn, record); } else if (record instanceof aTLSHandshakeRecord) { handshakeMessage(atlsconn, record); } else if (record instanceof aTLSAppDataRecord) { dataMessage(atlsconn, record); } else { System.err.println ("aTLSRecordStage: Received Bad Packet. Internal Error, contact mdw@cs.berkeley.edu"); } } } } } public void handleEvents(QueueElementIF[] qelarr) { for (int i = 0; i < qelarr.length; i++) { if (qelarr[i] == null) { System.err.println ("aTLSRecordStage: Received a null in handleEvents(). Internal Error, contact mdw@cs.berkeley.edu"); } else { handleEvent(qelarr[i]); } } } /** * Helper function to deal with alert messages. Calls PureTLS to decode the alert message and to handle is * appropriately in SSLRecordReader.readRecord(). */ private void alertMessage(aTLSConnection atlsconn, aTLSRecord record) { if (DEBUG) System.err.println ("aTLSRecordStage: received an alert message."); ByteArrayInputStream bais = new ByteArrayInputStream (record.data); atlsconn.conn.sock_in = new PushbackInputStream (bais); try { atlsconn.rr.readRecord(); } catch (Exception e) { System.err.println ("aTLSRecordStage: Exception trying to readrecord " + e); try { atlsconn.getConnection().close(mySink); } catch (SinkClosedException sce) { System.err.println ("aTLSRecordStage: Exception trying to close the connection " + sce); } } } /** * Helper function that posts handshake messages to the handshake stage. * If the server is attemptiing to resume a session, then handleResume is called. */ private void handshakeMessage(aTLSConnection atlsconn, aTLSRecord record) { if (DEBUG) System.err.println ("aTLSREcordStage: received a handshake message."); if ((atlsconn.isServer) && ((SSLHandshakeServer)atlsconn.conn.hs).resume) { handleResume (atlsconn, record); } else { if (PROFILE) { atlsconn.prof.addMeasurements(System.currentTimeMillis(), "aTLSRecordStage sending handshake message to handshake stage"); } handshakeSink.enqueue_lossy(new aTLSHandshakePacket (atlsconn, (aTLSHandshakeRecord)record)); } } /** * Helper function that does the same things has handshake message, but needs to differentiate * between a cipher spec message and a regular handshake message because must be handled differently. */ private void changeCipherSpecMessage(aTLSConnection atlsconn, aTLSRecord record) { if (DEBUG) System.err.println ("aTLSRecordStage: dealing with a changeCipherSpec Message"); if ((atlsconn.isServer) && ((SSLHandshakeServer)atlsconn.conn.hs).resume) { handleResume (atlsconn, record); } else { handshakeSink.enqueue_lossy(new aTLSCipherSpecPacket (atlsconn, (aTLSCipherSpecRecord)record)); } } /** * This function will decrypt the application data record by calling PureTLS, and will then * pass the decrypted record back to the user. But if startReader for the connection has not been called, * then must enqueue onto the dataQueue rather than post to the user sink. The dataSinkLock needed to * synchronize actions with aTLSConnection. */ private void dataMessage(aTLSConnection atlsconn, aTLSRecord record) { ByteArrayInputStream bais = new ByteArrayInputStream (record.data); atlsconn.conn.sock_in = new PushbackInputStream (bais); try { atlsconn.rr.readRecord(); } catch (Exception e) { System.err.println ("aTLSRecordStage: Exception trying to readrecord " + e + " "); byte[] temp = atlsconn.conn.hs.session_id; for (int i = 0; i < temp.length; i++) { System.err.print (temp[i] + " "); } e.printStackTrace(); try { atlsconn.getConnection().close(mySink); } catch (SinkClosedException sce) { System.err.println ("aTLSRecordStage: Exception trying to close the connection " + sce); } } // after read record is called, all the data resides on the sock_in_data stream of PureTLS. // so need to read all the data off of that stream and pass it to the user. int length = ((aTLSAppDataRecord)record).length; byte[] data = new byte[length]; try { atlsconn.conn.sock_in_data.read (data, 0, length); } catch (Exception e) { System.err.println ("aTLSRecordStage: Exception trying to read data from sock_in_data"); try { atlsconn.getConnection().close(mySink); } catch (SinkClosedException sce) { System.err.println ("aTLSRecordStage: Exception trying to close the connection " + sce); } } record.data = data; // if startReader hasn't been called, then no dataSink has been assigned, so just enqueue onto // the temporary queue until user has called startReader(). synchronized (atlsconn.dataSinkLock) { if (atlsconn.getDataSink() != null) { atlsconn.getDataSink().enqueue_lossy (new ATcpInPacket (atlsconn, new BufferElement(record.data))); } else { atlsconn.dataQueue.add(record); } } } /** * PureTLS will decide if a connection can be resumed once the clientHello has been received. If * the sessionID is valid, then will set the boolean resume to true in SSLHandshakeServer. So * a resumed session does not need to go through the same handshake process, so no need to * enqueue anything to handshake stage. Best way is to handle it right here because only a few steps, * and decryption can occur here too, rather than in the handshake stage. * For a resume, only need a change cipher spec record and a finished record. */ private void handleResume(aTLSConnection atlsconn, aTLSRecord record) { if (DEBUG) System.err.println ("aTLSRecordStage: Server is going to resume session with client"); ByteArrayInputStream bais = new ByteArrayInputStream (record.data); atlsconn.conn.sock_in = new PushbackInputStream (bais); try { atlsconn.rr.readRecord(); } catch (Exception e) { System.err.println ("aTLSRecordStage: Exception trying to readrecord " + e); try { atlsconn.getConnection().close(mySink); } catch (SinkClosedException sce) { System.err.println ("aTLSRecordStage: Exception trying to close the connection " + sce); } } if (record instanceof aTLSCipherSpecRecord) { return; // because readRecord already handled it for us. } else if (record instanceof aTLSHandshakeRecord) { // then it better have been a finished message! try { if (DEBUG) System.err.println ("aTLSRecordStage: Calling handshakecontinue()"); atlsconn.conn.hs.handshakeContinue(); } catch (Exception e) { System.err.println ("aTLSRecordStage: Exception in handshakeContinue " + e); try { atlsconn.getConnection().close(mySink); } catch (SinkClosedException sce) { System.err.println ("aTLSRecordStage: Exception trying to close the connection " + sce); } } if (atlsconn.conn.hs.state == SSL_HANDSHAKE_FINISHED) { atlsconn.conn.sock_out_external=new SSLOutputStream(atlsconn.conn); // creating the output stream for the data // pass the atlsconn back up to the user who created the serversocket atlsconn.getNewConnSink().enqueue_lossy(atlsconn); } else { System.err.println ("aTLSRecordStage: Error, trying to resume in bad state with bad packet." + " Internal error, contact mdw@cs.berkeley.edu"); } } else { System.err.println ("aTLSRecordStage: Internal Error, contact mdw@cs.berkeley.edu"); } } /** * This function cleans up the state for a closed connection. Necessary to remove from * hash tables to avoid memory leaks. * * NOTE: if the server receives a sink closed event, should not remove itself from the * hash tables. The sinkclosedevent is simply used to notify server of a closed connection, * no need to clean up state because needs to remain intact. */ void cleanupConnection(aTLSConnection atlsconn) { if (DEBUG) System.err.println ("aTLSRecordStage: Closing and cleaning up connection."); // have to clean up two hashtables ATcpConnection atcpconn = atlsconn.getConnection(); connTable.remove(atcpconn); if (!(atlsconn.isServer)) clientSocketTable.remove(atcpconn.getClientSocket()); } /** * Return mySink */ SinkIF getSink() { return mySink; } /** * The Sandstorm stage destroy method. */ public void destroy() { }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?