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/] [OutputSecurityParameters.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* OutputSecurityParameters.java --
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.ByteBufferOutputStream;
44
 
45
import java.nio.ByteBuffer;
46
 
47
import java.util.zip.DataFormatException;
48
import java.util.zip.Deflater;
49
 
50
import javax.crypto.Cipher;
51
import javax.crypto.IllegalBlockSizeException;
52
import javax.crypto.Mac;
53
import javax.crypto.ShortBufferException;
54
 
55
public class OutputSecurityParameters
56
{
57
  private static final SystemLogger logger = SystemLogger.SYSTEM;
58
  private final Cipher cipher;
59
  private final Mac mac;
60
  private final Deflater deflater;
61
  private final SessionImpl session;
62
  private final CipherSuite suite;
63
  private long sequence;
64
 
65
  public OutputSecurityParameters (final Cipher cipher, final Mac mac,
66
                                   final Deflater deflater, SessionImpl session,
67
                                   CipherSuite suite)
68
  {
69
    this.cipher = cipher;
70
    this.mac = mac;
71
    this.deflater = deflater;
72
    this.session = session;
73
    this.suite = suite;
74
    sequence = 0;
75
  }
76
 
77
  /**
78
   * Encrypt a record, storing the result in the given output buffer.
79
   *
80
   * @return The number of bytes taken from the input, and the number stored
81
   * into `output;' that is, the size of the encrypted fragment, plus the
82
   * encoding for the record.
83
   */
84
  public int[] encrypt (final ByteBuffer[] input, int offset, int length,
85
                        final ContentType contentType, final ByteBuffer output)
86
    throws DataFormatException, IllegalBlockSizeException, ShortBufferException
87
  {
88
    if (offset < 0 || offset >= input.length
89
        || length <= 0 || offset + length > input.length)
90
      throw new IndexOutOfBoundsException();
91
 
92
    if (Debug.DEBUG)
93
      for (int i = offset; i < offset+length; i++)
94
        logger.logv(Component.SSL_RECORD_LAYER, "encrypting record [{0}]: {1}",
95
                    i-offset, input[i]);
96
 
97
    int maclen = 0;
98
    if (mac != null)
99
      maclen = session.isTruncatedMac() ? 10 : mac.getMacLength ();
100
 
101
    int ivlen = 0;
102
    byte[] iv = null;
103
    if (session.version.compareTo(ProtocolVersion.TLS_1_1) >= 0
104
        && !suite.isStreamCipher())
105
      {
106
        ivlen = cipher.getBlockSize();
107
        iv = new byte[ivlen];
108
        session.random().nextBytes(iv);
109
      }
110
 
111
    int padaddlen = 0;
112
    if (!suite.isStreamCipher()
113
        && session.version.compareTo(ProtocolVersion.TLS_1) >= 0)
114
      {
115
        padaddlen = (session.random().nextInt(255 / cipher.getBlockSize())
116
                     * cipher.getBlockSize());
117
      }
118
 
119
    int fragmentLength = 0;
120
    ByteBuffer[] fragments = null;
121
    // Compress the content, if needed.
122
    if (deflater != null)
123
      {
124
        ByteBufferOutputStream deflated = new ByteBufferOutputStream();
125
 
126
        byte[] inbuf = new byte[1024];
127
        byte[] outbuf = new byte[1024];
128
        int written = 0;
129
 
130
        // Here we use the guarantee that the deflater won't increase the
131
        // output size by more than 1K -- we resign ourselves to only deflate
132
        // as much data as we have space for *uncompressed*,
133
        int limit = output.remaining() - (maclen + ivlen + padaddlen) - 1024;
134
 
135
        for (int i = offset; i < length && written < limit; i++)
136
          {
137
            ByteBuffer in = input[i];
138
            while (in.hasRemaining() && written < limit)
139
              {
140
                int l = Math.min(in.remaining(), inbuf.length);
141
                l = Math.min(limit - written, l);
142
                in.get(inbuf, 0, l);
143
                deflater.setInput(inbuf, 0, l);
144
                l = deflater.deflate(outbuf);
145
                deflated.write(outbuf, 0, l);
146
                written += l;
147
              }
148
          }
149
        deflater.finish();
150
        while (!deflater.finished())
151
          {
152
            int l = deflater.deflate(outbuf);
153
            deflated.write(outbuf, 0, l);
154
            written += l;
155
          }
156
        fragments = new ByteBuffer[] { deflated.buffer() };
157
        fragmentLength = ((int) deflater.getBytesWritten()) + maclen + ivlen;
158
        deflater.reset();
159
        offset = 0;
160
        length = 1;
161
      }
162
    else
163
      {
164
        int limit = output.remaining() - (maclen + ivlen + padaddlen);
165
        fragments = input;
166
        for (int i = offset; i < length && fragmentLength < limit; i++)
167
          {
168
            int l = Math.min(limit - fragmentLength, fragments[i].remaining());
169
            fragmentLength += l;
170
          }
171
        fragmentLength += maclen + ivlen;
172
      }
173
 
174
    // Compute padding...
175
    int padlen = 0;
176
    byte[] pad = null;
177
    if (!suite.isStreamCipher())
178
      {
179
        int bs = cipher.getBlockSize();
180
        padlen = bs - (fragmentLength % bs);
181
        if (Debug.DEBUG)
182
          logger.logv(Component.SSL_RECORD_LAYER,
183
                      "framentLen:{0} padlen:{1} blocksize:{2}",
184
                      fragmentLength, padlen, bs);
185
        if (session.version.compareTo(ProtocolVersion.TLS_1) >= 0)
186
          {
187
            // TLS 1.0 and later uses a random amount of padding, up to
188
            // 255 bytes. Each byte of the pad is equal to the padding
189
            // length, minus one.
190
            padlen += padaddlen;
191
            while (padlen > 255)
192
              padlen -= bs;
193
            pad = new byte[padlen];
194
            for (int i = 0; i < padlen; i++)
195
              pad[i] = (byte) (padlen - 1);
196
          }
197
        else
198
          {
199
            // SSL 3 uses a pad only as large as the block size, but the
200
            // pad may contain any values.
201
            pad = new byte[padlen];
202
            session.random().nextBytes(pad);
203
            pad[padlen - 1] = (byte) (padlen - 1);
204
          }
205
        fragmentLength += pad.length;
206
      }
207
 
208
    // If there is a MAC, compute it.
209
    byte[] macValue = null;
210
    if (mac != null)
211
      {
212
        mac.update((byte) (sequence >>> 56));
213
        mac.update((byte) (sequence >>> 48));
214
        mac.update((byte) (sequence >>> 40));
215
        mac.update((byte) (sequence >>> 32));
216
        mac.update((byte) (sequence >>> 24));
217
        mac.update((byte) (sequence >>> 16));
218
        mac.update((byte) (sequence >>>  8));
219
        mac.update((byte)  sequence);
220
        mac.update((byte) contentType.getValue());
221
        if (session.version != ProtocolVersion.SSL_3)
222
          {
223
            mac.update((byte) session.version.major ());
224
            mac.update((byte) session.version.minor ());
225
          }
226
        int toWrite = fragmentLength - maclen - ivlen - padlen;
227
        mac.update((byte) (toWrite >>> 8));
228
        mac.update((byte)  toWrite);
229
        int written = 0;
230
        for (int i = offset; i < length && written < toWrite; i++)
231
          {
232
            ByteBuffer fragment = fragments[i].duplicate();
233
            int l = Math.min(fragment.remaining(), toWrite - written);
234
            fragment.limit(fragment.position() + l);
235
            mac.update(fragment);
236
          }
237
        macValue = mac.doFinal();
238
      }
239
 
240
    Record outrecord = new Record(output);
241
    outrecord.setContentType(contentType);
242
    outrecord.setVersion(session.version);
243
    outrecord.setLength(fragmentLength);
244
 
245
    int consumed = 0;
246
    ByteBuffer outfragment = outrecord.fragment();
247
 
248
    if (cipher != null)
249
      {
250
        if (iv != null)
251
          cipher.update(ByteBuffer.wrap(iv), outfragment);
252
        int toWrite = fragmentLength - maclen - ivlen - padlen;
253
        for (int i = offset; i < offset + length && consumed < toWrite; i++)
254
          {
255
            ByteBuffer fragment = fragments[i].slice();
256
            int l = Math.min(fragment.remaining(), toWrite - consumed);
257
            fragment.limit(fragment.position() + l);
258
            cipher.update(fragment, outfragment);
259
            fragments[i].position(fragments[i].position() + l);
260
            consumed += l;
261
          }
262
        if (macValue != null)
263
          cipher.update(ByteBuffer.wrap(macValue), outfragment);
264
        if (pad != null)
265
          cipher.update(ByteBuffer.wrap(pad), outfragment);
266
      }
267
    else
268
      {
269
        // iv and pad are only used if we have a block cipher.
270
        int toWrite = fragmentLength - maclen;
271
        for (int i = offset; i < offset + length && consumed < toWrite; i++)
272
          {
273
            ByteBuffer fragment = fragments[i];
274
            int l = Math.min(fragment.remaining(), toWrite - consumed);
275
            fragment.limit(fragment.position() + l);
276
            outfragment.put(fragment);
277
            consumed += l;
278
          }
279
        if (macValue != null)
280
          outfragment.put(macValue);
281
      }
282
 
283
    // Advance the output buffer's position.
284
    output.position(output.position() + outrecord.length() + 5);
285
    sequence++;
286
 
287
    return new int[] { consumed, fragmentLength + 5 };
288
  }
289
 
290
  CipherSuite suite()
291
  {
292
    return suite;
293
  }
294
}

powered by: WebSVN 2.1.0

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