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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [crypto/] [keyring/] [PasswordEncryptedEntry.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* PasswordEncryptedEntry.java --
2
   Copyright (C) 2003, 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.crypto.keyring;
40
 
41
import gnu.java.security.Configuration;
42
import gnu.java.security.Registry;
43
import gnu.java.security.prng.IRandom;
44
import gnu.java.security.prng.LimitReachedException;
45
import gnu.java.security.util.PRNG;
46
import gnu.java.security.util.Util;
47
import gnu.javax.crypto.cipher.CipherFactory;
48
import gnu.javax.crypto.cipher.IBlockCipher;
49
import gnu.javax.crypto.mode.IMode;
50
import gnu.javax.crypto.mode.ModeFactory;
51
import gnu.javax.crypto.pad.IPad;
52
import gnu.javax.crypto.pad.PadFactory;
53
import gnu.javax.crypto.pad.WrongPaddingException;
54
import gnu.javax.crypto.prng.IPBE;
55
import gnu.javax.crypto.prng.PRNGFactory;
56
 
57
import java.io.ByteArrayInputStream;
58
import java.io.ByteArrayOutputStream;
59
import java.io.DataInputStream;
60
import java.io.DataOutputStream;
61
import java.io.IOException;
62
import java.security.InvalidKeyException;
63
import java.util.HashMap;
64
import java.util.Iterator;
65
import java.util.logging.Logger;
66
 
67
/**
68
 * An envelope that is encrypted with a password-derived key.
69
 */
70
public class PasswordEncryptedEntry
71
    extends MaskableEnvelopeEntry
72
    implements PasswordProtectedEntry, Registry
73
{
74
  private static final Logger log = Logger.getLogger(PasswordEncryptedEntry.class.getName());
75
  public static final int TYPE = 1;
76
 
77
  public PasswordEncryptedEntry(String cipher, String mode, int keylen,
78
                                Properties properties)
79
  {
80
    super(TYPE, properties);
81
    if ((cipher == null || cipher.length() == 0)
82
        || (mode == null || mode.length() == 0))
83
      throw new IllegalArgumentException("cipher nor mode can be empty");
84
    this.properties.put("cipher", cipher);
85
    this.properties.put("mode", mode);
86
    this.properties.put("keylen", String.valueOf(keylen));
87
    setMasked(false);
88
  }
89
 
90
  private PasswordEncryptedEntry()
91
  {
92
    super(TYPE);
93
    setMasked(true);
94
  }
95
 
96
  public static PasswordEncryptedEntry decode(DataInputStream in,
97
                                              char[] password)
98
      throws IOException
99
  {
100
    PasswordEncryptedEntry entry = decode(in);
101
    try
102
      {
103
        entry.decrypt(password);
104
      }
105
    catch (WrongPaddingException wpe)
106
      {
107
        throw new MalformedKeyringException("wrong padding in decrypted data");
108
      }
109
    return entry;
110
  }
111
 
112
  public static PasswordEncryptedEntry decode(DataInputStream in)
113
      throws IOException
114
  {
115
    PasswordEncryptedEntry entry = new PasswordEncryptedEntry();
116
    entry.defaultDecode(in);
117
    return entry;
118
  }
119
 
120
  public void decrypt(char[] password) throws IllegalArgumentException,
121
      WrongPaddingException
122
  {
123
    if (Configuration.DEBUG)
124
      log.entering(this.getClass().getName(), "decrypt");
125
    if (isMasked() && payload != null)
126
      {
127
        long tt = -System.currentTimeMillis();
128
        IMode mode = getMode(password, IMode.DECRYPTION);
129
        IPad padding = PadFactory.getInstance("PKCS7");
130
        padding.init(mode.currentBlockSize());
131
        byte[] buf = new byte[payload.length];
132
        int count = 0;
133
        while (count + mode.currentBlockSize() <= payload.length)
134
          {
135
            mode.update(payload, count, buf, count);
136
            count += mode.currentBlockSize();
137
          }
138
        int padlen = padding.unpad(buf, 0, buf.length);
139
        setMasked(false);
140
        int len = buf.length - padlen;
141
        ByteArrayInputStream baos = new ByteArrayInputStream(buf, 0, len);
142
        DataInputStream in = new DataInputStream(baos);
143
        try
144
          {
145
            decodeEnvelope(in);
146
          }
147
        catch (IOException ioe)
148
          {
149
            throw new IllegalArgumentException("decryption failed");
150
          }
151
        tt += System.currentTimeMillis();
152
        log.fine("Decrypted in " + tt + "ms.");
153
      }
154
    else if (Configuration.DEBUG)
155
      log.fine("Skip decryption; " + (isMasked() ? "null payload" : "unmasked"));
156
    if (Configuration.DEBUG)
157
      log.exiting(this.getClass().getName(), "decrypt");
158
  }
159
 
160
  public void encrypt(char[] password) throws IOException
161
  {
162
    if (Configuration.DEBUG)
163
      log.entering(this.getClass().getName(), "encrypt", String.valueOf(password));
164
    long tt = -System.currentTimeMillis();
165
    long t1 = -System.currentTimeMillis();
166
    byte[] salt = new byte[8];
167
    PRNG.getInstance().nextBytes(salt);
168
    t1 += System.currentTimeMillis();
169
    if (Configuration.DEBUG)
170
      log.fine("-- Generated salt in " + t1 + "ms.");
171
    properties.put("salt", Util.toString(salt));
172
    IMode mode = getMode(password, IMode.ENCRYPTION);
173
    IPad pad = PadFactory.getInstance("PKCS7");
174
    pad.init(mode.currentBlockSize());
175
    ByteArrayOutputStream bout = new ByteArrayOutputStream(1024);
176
    DataOutputStream out2 = new DataOutputStream(bout);
177
    for (Iterator it = entries.iterator(); it.hasNext();)
178
      {
179
        Entry entry = (Entry) it.next();
180
        if (Configuration.DEBUG)
181
          log.fine("-- About to encode one " + entry);
182
        t1 = -System.currentTimeMillis();
183
        entry.encode(out2);
184
        t1 += System.currentTimeMillis();
185
        if (Configuration.DEBUG)
186
          log.fine("-- Encoded an Entry in " + t1 + "ms.");
187
      }
188
    byte[] plaintext = bout.toByteArray();
189
    byte[] padding = pad.pad(plaintext, 0, plaintext.length);
190
    payload = new byte[plaintext.length + padding.length];
191
    byte[] lastBlock = new byte[mode.currentBlockSize()];
192
    int l = mode.currentBlockSize() - padding.length;
193
    System.arraycopy(plaintext, plaintext.length - l, lastBlock, 0, l);
194
    System.arraycopy(padding, 0, lastBlock, l, padding.length);
195
    int count = 0;
196
    while (count + mode.currentBlockSize() < plaintext.length)
197
      {
198
        mode.update(plaintext, count, payload, count);
199
        count += mode.currentBlockSize();
200
      }
201
    mode.update(lastBlock, 0, payload, count);
202
    setMasked(true);
203
    tt += System.currentTimeMillis();
204
    if (Configuration.DEBUG)
205
      {
206
        log.fine("Encrypted in " + tt + "ms.");
207
        log.exiting(this.getClass().getName(), "encrypt");
208
      }
209
  }
210
 
211
  public void encode(DataOutputStream out, char[] password) throws IOException
212
  {
213
    encrypt(password);
214
    encode(out);
215
  }
216
 
217
  protected void encodePayload() throws IOException
218
  {
219
    if (payload == null)
220
      {
221
        if (Configuration.DEBUG)
222
          log.fine("Null payload: " + this);
223
        throw new IllegalStateException("not encrypted");
224
      }
225
  }
226
 
227
  private IMode getMode(char[] password, int state)
228
  {
229
    String s = properties.get("salt");
230
    if (s == null)
231
      throw new IllegalArgumentException("no salt");
232
    byte[] salt = Util.toBytesFromString(s);
233
    IBlockCipher cipher = CipherFactory.getInstance(properties.get("cipher"));
234
    if (cipher == null)
235
      throw new IllegalArgumentException("no such cipher: "
236
                                         + properties.get("cipher"));
237
    int blockSize = cipher.defaultBlockSize();
238
    if (properties.containsKey("block-size"))
239
      try
240
        {
241
          blockSize = Integer.parseInt(properties.get("block-size"));
242
        }
243
      catch (NumberFormatException nfe)
244
        {
245
          throw new IllegalArgumentException("bad block size: "
246
                                             + nfe.getMessage());
247
        }
248
    String modeName = properties.get("mode");
249
    IMode mode = ModeFactory.getInstance(modeName, cipher, blockSize);
250
    if (mode == null)
251
      throw new IllegalArgumentException("no such mode: " + modeName);
252
    HashMap pbAttr = new HashMap();
253
    pbAttr.put(IPBE.PASSWORD, password);
254
    pbAttr.put(IPBE.SALT, salt);
255
    pbAttr.put(IPBE.ITERATION_COUNT, ITERATION_COUNT);
256
    IRandom kdf = PRNGFactory.getInstance("PBKDF2-HMAC-SHA");
257
    kdf.init(pbAttr);
258
    int keylen = 0;
259
    if (! properties.containsKey("keylen"))
260
      throw new IllegalArgumentException("no key length");
261
    try
262
      {
263
        keylen = Integer.parseInt(properties.get("keylen"));
264
      }
265
    catch (NumberFormatException nfe)
266
      {
267
      }
268
    byte[] dk = new byte[keylen];
269
    byte[] iv = new byte[blockSize];
270
    try
271
      {
272
        kdf.nextBytes(dk, 0, keylen);
273
        kdf.nextBytes(iv, 0, blockSize);
274
      }
275
    catch (LimitReachedException shouldNotHappen)
276
      {
277
        throw new Error(shouldNotHappen.toString());
278
      }
279
    HashMap modeAttr = new HashMap();
280
    modeAttr.put(IMode.KEY_MATERIAL, dk);
281
    modeAttr.put(IMode.STATE, Integer.valueOf(state));
282
    modeAttr.put(IMode.IV, iv);
283
    try
284
      {
285
        mode.init(modeAttr);
286
      }
287
    catch (InvalidKeyException ike)
288
      {
289
        throw new IllegalArgumentException(ike.toString());
290
      }
291
    return mode;
292
  }
293
}

powered by: WebSVN 2.1.0

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