OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [net/] [ssl/] [provider/] [InputSecurityParameters.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* SecurityParameters.java -- SSL security parameters.
2
   Copyright (C) 2006  Free Software Foundation, Inc.
3
 
4
This file is a part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or (at
9
your option) any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19
USA
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version.  */
37
 
38
 
39
package gnu.javax.net.ssl.provider;
40
 
41
import gnu.classpath.debug.Component;
42
import gnu.classpath.debug.SystemLogger;
43
import gnu.java.security.util.ByteArray;
44
import gnu.java.security.util.ByteBufferOutputStream;
45
 
46
import java.nio.BufferOverflowException;
47
import java.nio.ByteBuffer;
48
 
49
import java.util.Arrays;
50
import java.util.zip.DataFormatException;
51
import java.util.zip.Inflater;
52
 
53
import javax.crypto.Cipher;
54
import javax.crypto.IllegalBlockSizeException;
55
import javax.crypto.Mac;
56
import javax.crypto.ShortBufferException;
57
 
58
import javax.net.ssl.SSLException;
59
 
60
public class InputSecurityParameters
61
{
62
  private static final SystemLogger logger = SystemLogger.SYSTEM;
63
  private final Cipher cipher;
64
  private final Mac mac;
65
  private final Inflater inflater;
66
  private SessionImpl session;
67
  private final CipherSuite suite;
68
  private long sequence;
69
 
70
  public InputSecurityParameters (final Cipher cipher, final Mac mac,
71
                                  final Inflater inflater,
72
                                  final SessionImpl session,
73
                                  final CipherSuite suite)
74
  {
75
    this.cipher = cipher;
76
    this.mac = mac;
77
    this.inflater = inflater;
78
    this.session = session;
79
    this.suite = suite;
80
    sequence = 0;
81
  }
82
 
83
  /**
84
   * Decrypt a record, storing the decrypted fragment into the given array
85
   * of byte buffers.
86
   *
87
   * @param record The input record.
88
   * @param output The output buffers.
89
   * @param offset The offset of the first buffer to use.
90
   * @param length The number of buffers to use.
91
   * @return The number of bytes put in the output buffers.
92
   * @throws DataFormatException If decompression fails.
93
   * @throws IllegalBlockSizeException If the current cipher is a block cipher,
94
   *  and the input fragment is not a multiple of the block size.
95
   * @throws MacException If verifying the MAC fails.
96
   * @throws SSLException ???
97
   * @throws ShortBufferException
98
   */
99
  public int decrypt(Record record, ByteBuffer[] output, int offset, int length)
100
    throws DataFormatException, IllegalBlockSizeException,
101
           MacException, SSLException, ShortBufferException
102
  {
103
    return decrypt(record, output, offset, length, null);
104
  }
105
 
106
  /**
107
   * Decrypt a record, storing the decrypted fragment into the given growable
108
   * buffer.
109
   *
110
   * @param record The input record.
111
   * @param outputStream The output buffer.
112
   * @return The number of bytes put into the output buffer.
113
   * @throws DataFormatException
114
   * @throws IllegalBlockSizeException
115
   * @throws MacException
116
   * @throws SSLException
117
   * @throws ShortBufferException
118
   */
119
  public int decrypt(Record record, ByteBufferOutputStream outputStream)
120
    throws DataFormatException, IllegalBlockSizeException,
121
           MacException, SSLException, ShortBufferException
122
  {
123
    return decrypt(record, null, 0, 0, outputStream);
124
  }
125
 
126
  private int decrypt(Record record, ByteBuffer[] output, int offset, int length,
127
                      ByteBufferOutputStream outputStream)
128
    throws DataFormatException, IllegalBlockSizeException,
129
           MacException, SSLException, ShortBufferException
130
  {
131
    boolean badPadding = false;
132
    ByteBuffer fragment;
133
    if (cipher != null)
134
      {
135
        ByteBuffer input = record.fragment();
136
        fragment = ByteBuffer.allocate(input.remaining());
137
        cipher.update(input, fragment);
138
      }
139
    else
140
      fragment = record.fragment();
141
 
142
    if (Debug.DEBUG_DECRYPTION)
143
      logger.logv(Component.SSL_RECORD_LAYER, "decrypted fragment:\n{0}",
144
                  Util.hexDump((ByteBuffer) fragment.duplicate().position(0), " >> "));
145
 
146
    int fragmentLength = record.length();
147
    int maclen = 0;
148
    if (mac != null)
149
      maclen = mac.getMacLength();
150
    fragmentLength -= maclen;
151
 
152
    int padlen = 0;
153
    int padRemoveLen = 0;
154
    if (!suite.isStreamCipher ())
155
      {
156
        padlen = fragment.get(record.length() - 1) & 0xFF;
157
        padRemoveLen = padlen + 1;
158
        if (Debug.DEBUG)
159
          logger.logv(Component.SSL_RECORD_LAYER, "padlen:{0}", padlen);
160
 
161
        if (record.version() == ProtocolVersion.SSL_3)
162
          {
163
            // In SSLv3, the padding length must not be larger than
164
            // the cipher's block size.
165
            if (padlen > cipher.getBlockSize ())
166
              badPadding = true;
167
          }
168
        else if (record.version().compareTo(ProtocolVersion.TLS_1) >= 0)
169
          {
170
            // In TLSv1 and later, the padding must be `padlen' copies of the
171
            // value `padlen'.
172
            byte[] pad = new byte[padlen];
173
            ((ByteBuffer) fragment.duplicate().position(record.length() - padlen - 1)).get(pad);
174
            for (int i = 0; i < pad.length; i++)
175
              if ((pad[i] & 0xFF) != padlen)
176
                badPadding = true;
177
            if (Debug.DEBUG)
178
              logger.logv(Component.SSL_RECORD_LAYER, "TLSv1.x padding\n{0}",
179
                          new ByteArray(pad));
180
          }
181
 
182
        if (Debug.DEBUG)
183
          logger.logv(Component.SSL_RECORD_LAYER, "padding bad? {0}",
184
                      badPadding);
185
        if (!badPadding)
186
          fragmentLength = fragmentLength - padRemoveLen;
187
      }
188
 
189
    int ivlen = 0;
190
    if (session.version.compareTo(ProtocolVersion.TLS_1_1) >= 0
191
        && !suite.isStreamCipher())
192
      ivlen = cipher.getBlockSize();
193
 
194
    // Compute and check the MAC.
195
    if (mac != null)
196
      {
197
        mac.update((byte) (sequence >>> 56));
198
        mac.update((byte) (sequence >>> 48));
199
        mac.update((byte) (sequence >>> 40));
200
        mac.update((byte) (sequence >>> 32));
201
        mac.update((byte) (sequence >>> 24));
202
        mac.update((byte) (sequence >>> 16));
203
        mac.update((byte) (sequence >>>  8));
204
        mac.update((byte)  sequence);
205
        mac.update((byte) record.getContentType().getValue());
206
        ProtocolVersion version = record.version();
207
        if (version != ProtocolVersion.SSL_3)
208
          {
209
            mac.update((byte) version.major());
210
            mac.update((byte) version.minor());
211
          }
212
        mac.update((byte) ((fragmentLength - ivlen) >>> 8));
213
        mac.update((byte)  (fragmentLength - ivlen));
214
        ByteBuffer content =
215
          (ByteBuffer) fragment.duplicate().position(ivlen).limit(fragmentLength);
216
        mac.update(content);
217
        byte[] mac1 = mac.doFinal ();
218
        byte[] mac2 = new byte[maclen];
219
        mac.reset();
220
        ((ByteBuffer) fragment.duplicate().position(fragmentLength)).get(mac2);
221
        if (Debug.DEBUG)
222
          logger.logv(Component.SSL_RECORD_LAYER, "mac1:{0} mac2:{1}",
223
                      Util.toHexString(mac1, ':'), Util.toHexString(mac2, ':'));
224
        if (!Arrays.equals (mac1, mac2))
225
          badPadding = true;
226
      }
227
 
228
    // We always say "bad MAC" and not "bad padding," because saying
229
    // the latter will leak information to an attacker.
230
    if (badPadding)
231
      throw new MacException ();
232
 
233
    // Inflate the compressed bytes.
234
    int produced = 0;
235
    if (inflater != null)
236
      {
237
        ByteBufferOutputStream out = new ByteBufferOutputStream(fragmentLength);
238
        byte[] inbuffer = new byte[1024];
239
        byte[] outbuffer = new byte[1024];
240
        boolean done = false;
241
        if (record.version().compareTo(ProtocolVersion.TLS_1_1) >= 0
242
            && !suite.isStreamCipher())
243
          fragment.position (cipher.getBlockSize());
244
        else
245
          fragment.position(0);
246
        fragment.limit(fragmentLength);
247
 
248
        while (!done)
249
          {
250
            int l;
251
            if (inflater.needsInput())
252
              {
253
                l = Math.min(inbuffer.length, fragment.remaining());
254
                fragment.get(inbuffer, 0, l);
255
                inflater.setInput(inbuffer);
256
              }
257
 
258
            l = inflater.inflate(outbuffer);
259
            out.write(outbuffer, 0, l);
260
            done = !fragment.hasRemaining() && inflater.finished();
261
          }
262
 
263
        ByteBuffer outbuf = out.buffer();
264
        if (outputStream != null)
265
          {
266
            byte[] buf = new byte[1024];
267
            while (outbuf.hasRemaining())
268
              {
269
                int l = Math.min(outbuf.remaining(), buf.length);
270
                outbuf.get(buf, 0, l);
271
                outputStream.write(buf, 0, l);
272
                produced += l;
273
              }
274
          }
275
        else
276
          {
277
            int i = offset;
278
            while (outbuf.hasRemaining() && i < offset + length)
279
              {
280
                int l = Math.min(output[i].remaining(), outbuf.remaining());
281
                ByteBuffer b = (ByteBuffer)
282
                  outbuf.duplicate().limit(outbuf.position() + l);
283
                output[i++].put(b);
284
                outbuf.position(outbuf.position() + l);
285
                produced += l;
286
              }
287
            if (outbuf.hasRemaining())
288
              throw new BufferOverflowException();
289
          }
290
      }
291
    else
292
      {
293
        ByteBuffer outbuf = (ByteBuffer)
294
          fragment.duplicate().position(0).limit(record.length() - maclen - padRemoveLen);
295
        if (record.version().compareTo(ProtocolVersion.TLS_1_1) >= 0
296
            && !suite.isStreamCipher())
297
          outbuf.position(cipher.getBlockSize());
298
        if (outputStream != null)
299
          {
300
            byte[] buf = new byte[1024];
301
            while (outbuf.hasRemaining())
302
              {
303
                int l = Math.min(outbuf.remaining(), buf.length);
304
                outbuf.get(buf, 0, l);
305
                outputStream.write(buf, 0, l);
306
                produced += l;
307
              }
308
          }
309
        else
310
          {
311
            int i = offset;
312
            while (outbuf.hasRemaining() && i < offset + length)
313
              {
314
                int l = Math.min(output[i].remaining(), outbuf.remaining());
315
                ByteBuffer b = (ByteBuffer) outbuf.duplicate().limit(outbuf.position() + l);
316
                output[i++].put(b);
317
                outbuf.position(outbuf.position() + l);
318
                produced += l;
319
              }
320
            if (outbuf.hasRemaining())
321
              throw new BufferOverflowException();
322
          }
323
      }
324
 
325
    sequence++;
326
 
327
    return produced;
328
  }
329
 
330
  CipherSuite cipherSuite ()
331
  {
332
    return suite;
333
  }
334
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.