< prev index next >

src/java.base/share/classes/sun/security/ssl/DTLSOutputRecord.java

Print this page


   1 /*
   2  * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  41     int                 writeEpoch;
  42 
  43     int                 prevWriteEpoch;
  44     Authenticator       prevWriteAuthenticator;
  45     SSLWriteCipher      prevWriteCipher;
  46 
  47     private volatile boolean isCloseWaiting = false;
  48 
  49     DTLSOutputRecord(HandshakeHash handshakeHash) {
  50         super(handshakeHash, SSLWriteCipher.nullDTlsWriteCipher());
  51 
  52         this.writeEpoch = 0;
  53         this.prevWriteEpoch = 0;
  54         this.prevWriteCipher = SSLWriteCipher.nullDTlsWriteCipher();
  55 
  56         this.packetSize = DTLSRecord.maxRecordSize;
  57         this.protocolVersion = ProtocolVersion.NONE;
  58     }
  59 
  60     @Override
  61     public void close() throws IOException {
  62         recordLock.lock();
  63         try {
  64             if (!isClosed) {
  65                 if (fragmenter != null && fragmenter.hasAlert()) {
  66                     isCloseWaiting = true;
  67                 } else {
  68                     super.close();
  69                 }
  70             }
  71         } finally {
  72             recordLock.unlock();
  73         }
  74     }
  75 
  76     boolean isClosed() {
  77         return isClosed || isCloseWaiting;
  78     }
  79 
  80     @Override
  81     void initHandshaker() {
  82         // clean up
  83         fragmenter = null;
  84     }
  85 
  86     @Override
  87     void finishHandshake() {
  88         // Nothing to do here currently.
  89     }
  90 
  91     @Override
  92     void changeWriteCiphers(SSLWriteCipher writeCipher,


 227         for (int i = offset; i < offset + length; i++) {
 228             srcsRemains += sources[i].remaining();
 229         }
 230 
 231         if (srcsRemains == 0) {
 232             return null;
 233         }
 234 
 235         // not apply to handshake message
 236         int fragLen;
 237         if (packetSize > 0) {
 238             fragLen = Math.min(maxRecordSize, packetSize);
 239             fragLen = writeCipher.calculateFragmentSize(
 240                     fragLen, headerSize);
 241 
 242             fragLen = Math.min(fragLen, Record.maxDataSize);
 243         } else {
 244             fragLen = Record.maxDataSize;
 245         }
 246 
 247         // Calculate more impact, for example TLS 1.3 padding.
 248         fragLen = calculateFragmentSize(fragLen);

 249 
 250         int dstPos = destination.position();
 251         int dstLim = destination.limit();
 252         int dstContent = dstPos + headerSize +
 253                                 writeCipher.getExplicitNonceSize();
 254         destination.position(dstContent);
 255 
 256         int remains = Math.min(fragLen, destination.remaining());
 257         fragLen = 0;
 258         int srcsLen = offset + length;
 259         for (int i = offset; (i < srcsLen) && (remains > 0); i++) {
 260             int amount = Math.min(sources[i].remaining(), remains);
 261             int srcLimit = sources[i].limit();
 262             sources[i].limit(sources[i].position() + amount);
 263             destination.put(sources[i]);
 264             sources[i].limit(srcLimit);         // restore the limit
 265             remains -= amount;
 266             fragLen += amount;
 267         }
 268 


 446             RecordMemo memo = handshakeMemos.get(acquireIndex);
 447             HandshakeMemo hsMemo = null;
 448             if (memo.contentType == ContentType.HANDSHAKE.id) {
 449                 hsMemo = (HandshakeMemo)memo;
 450             }
 451 
 452             // ChangeCipherSpec message is pretty small.  Don't worry about
 453             // the fragmentation of ChangeCipherSpec record.
 454             int fragLen;
 455             if (packetSize > 0) {
 456                 fragLen = Math.min(maxRecordSize, packetSize);
 457                 fragLen = memo.encodeCipher.calculateFragmentSize(
 458                         fragLen, 25);   // 25: header size
 459                                                 //   13: DTLS record
 460                                                 //   12: DTLS handshake message
 461                 fragLen = Math.min(fragLen, Record.maxDataSize);
 462             } else {
 463                 fragLen = Record.maxDataSize;
 464             }
 465 
 466             // Calculate more impact, for example TLS 1.3 padding.
 467             fragLen = calculateFragmentSize(fragLen);

 468 
 469             int dstPos = dstBuf.position();
 470             int dstLim = dstBuf.limit();
 471             int dstContent = dstPos + headerSize +
 472                                     memo.encodeCipher.getExplicitNonceSize();
 473             dstBuf.position(dstContent);
 474 
 475             if (hsMemo != null) {
 476                 fragLen = Math.min(fragLen,
 477                         (hsMemo.fragment.length - hsMemo.acquireOffset));
 478 
 479                 dstBuf.put(hsMemo.handshakeType);
 480                 dstBuf.put((byte)((hsMemo.fragment.length >> 16) & 0xFF));
 481                 dstBuf.put((byte)((hsMemo.fragment.length >> 8) & 0xFF));
 482                 dstBuf.put((byte)(hsMemo.fragment.length & 0xFF));
 483                 dstBuf.put((byte)((hsMemo.messageSequence >> 8) & 0xFF));
 484                 dstBuf.put((byte)(hsMemo.messageSequence & 0xFF));
 485                 dstBuf.put((byte)((hsMemo.acquireOffset >> 16) & 0xFF));
 486                 dstBuf.put((byte)((hsMemo.acquireOffset >> 8) & 0xFF));
 487                 dstBuf.put((byte)(hsMemo.acquireOffset & 0xFF));


   1 /*
   2  * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  41     int                 writeEpoch;
  42 
  43     int                 prevWriteEpoch;
  44     Authenticator       prevWriteAuthenticator;
  45     SSLWriteCipher      prevWriteCipher;
  46 
  47     private volatile boolean isCloseWaiting = false;
  48 
  49     DTLSOutputRecord(HandshakeHash handshakeHash) {
  50         super(handshakeHash, SSLWriteCipher.nullDTlsWriteCipher());
  51 
  52         this.writeEpoch = 0;
  53         this.prevWriteEpoch = 0;
  54         this.prevWriteCipher = SSLWriteCipher.nullDTlsWriteCipher();
  55 
  56         this.packetSize = DTLSRecord.maxRecordSize;
  57         this.protocolVersion = ProtocolVersion.NONE;
  58     }
  59 
  60     @Override
  61     public synchronized void close() throws IOException {
  62         if (!isClosed) {
  63             if (fragmenter != null && fragmenter.hasAlert()) {
  64                 isCloseWaiting = true;
  65             } else {
  66                 super.close();



  67             }


  68         }
  69     }
  70 
  71     boolean isClosed() {
  72         return isClosed || isCloseWaiting;
  73     }
  74 
  75     @Override
  76     void initHandshaker() {
  77         // clean up
  78         fragmenter = null;
  79     }
  80 
  81     @Override
  82     void finishHandshake() {
  83         // Nothing to do here currently.
  84     }
  85 
  86     @Override
  87     void changeWriteCiphers(SSLWriteCipher writeCipher,


 222         for (int i = offset; i < offset + length; i++) {
 223             srcsRemains += sources[i].remaining();
 224         }
 225 
 226         if (srcsRemains == 0) {
 227             return null;
 228         }
 229 
 230         // not apply to handshake message
 231         int fragLen;
 232         if (packetSize > 0) {
 233             fragLen = Math.min(maxRecordSize, packetSize);
 234             fragLen = writeCipher.calculateFragmentSize(
 235                     fragLen, headerSize);
 236 
 237             fragLen = Math.min(fragLen, Record.maxDataSize);
 238         } else {
 239             fragLen = Record.maxDataSize;
 240         }
 241 
 242         if (fragmentSize > 0) {
 243             fragLen = Math.min(fragLen, fragmentSize);
 244         }
 245 
 246         int dstPos = destination.position();
 247         int dstLim = destination.limit();
 248         int dstContent = dstPos + headerSize +
 249                                 writeCipher.getExplicitNonceSize();
 250         destination.position(dstContent);
 251 
 252         int remains = Math.min(fragLen, destination.remaining());
 253         fragLen = 0;
 254         int srcsLen = offset + length;
 255         for (int i = offset; (i < srcsLen) && (remains > 0); i++) {
 256             int amount = Math.min(sources[i].remaining(), remains);
 257             int srcLimit = sources[i].limit();
 258             sources[i].limit(sources[i].position() + amount);
 259             destination.put(sources[i]);
 260             sources[i].limit(srcLimit);         // restore the limit
 261             remains -= amount;
 262             fragLen += amount;
 263         }
 264 


 442             RecordMemo memo = handshakeMemos.get(acquireIndex);
 443             HandshakeMemo hsMemo = null;
 444             if (memo.contentType == ContentType.HANDSHAKE.id) {
 445                 hsMemo = (HandshakeMemo)memo;
 446             }
 447 
 448             // ChangeCipherSpec message is pretty small.  Don't worry about
 449             // the fragmentation of ChangeCipherSpec record.
 450             int fragLen;
 451             if (packetSize > 0) {
 452                 fragLen = Math.min(maxRecordSize, packetSize);
 453                 fragLen = memo.encodeCipher.calculateFragmentSize(
 454                         fragLen, 25);   // 25: header size
 455                                                 //   13: DTLS record
 456                                                 //   12: DTLS handshake message
 457                 fragLen = Math.min(fragLen, Record.maxDataSize);
 458             } else {
 459                 fragLen = Record.maxDataSize;
 460             }
 461 
 462             if (fragmentSize > 0) {
 463                 fragLen = Math.min(fragLen, fragmentSize);
 464             }
 465 
 466             int dstPos = dstBuf.position();
 467             int dstLim = dstBuf.limit();
 468             int dstContent = dstPos + headerSize +
 469                                     memo.encodeCipher.getExplicitNonceSize();
 470             dstBuf.position(dstContent);
 471 
 472             if (hsMemo != null) {
 473                 fragLen = Math.min(fragLen,
 474                         (hsMemo.fragment.length - hsMemo.acquireOffset));
 475 
 476                 dstBuf.put(hsMemo.handshakeType);
 477                 dstBuf.put((byte)((hsMemo.fragment.length >> 16) & 0xFF));
 478                 dstBuf.put((byte)((hsMemo.fragment.length >> 8) & 0xFF));
 479                 dstBuf.put((byte)(hsMemo.fragment.length & 0xFF));
 480                 dstBuf.put((byte)((hsMemo.messageSequence >> 8) & 0xFF));
 481                 dstBuf.put((byte)(hsMemo.messageSequence & 0xFF));
 482                 dstBuf.put((byte)((hsMemo.acquireOffset >> 16) & 0xFF));
 483                 dstBuf.put((byte)((hsMemo.acquireOffset >> 8) & 0xFF));
 484                 dstBuf.put((byte)(hsMemo.acquireOffset & 0xFF));


< prev index next >