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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [java/] [security/] [provider/] [RSA.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* RSA.java -- RSA PKCS#1 signatures.
2
   Copyright (C) 2004  Free Software Foundation, Inc.
3
 
4
This file is 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, or (at your option)
9
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; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 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.java.security.provider;
40
 
41
import gnu.java.security.OID;
42
import gnu.java.security.der.DER;
43
import gnu.java.security.der.DERReader;
44
import gnu.java.security.der.DERValue;
45
import gnu.java.security.der.DERWriter;
46
 
47
import java.io.ByteArrayOutputStream;
48
import java.io.IOException;
49
import java.math.BigInteger;
50
import java.security.InvalidKeyException;
51
import java.security.MessageDigest;
52
import java.security.PrivateKey;
53
import java.security.PublicKey;
54
import java.security.SecureRandom;
55
import java.security.SignatureException;
56
import java.security.SignatureSpi;
57
import java.security.interfaces.RSAPrivateKey;
58
import java.security.interfaces.RSAPublicKey;
59
import java.util.ArrayList;
60
 
61
public abstract class RSA extends SignatureSpi implements Cloneable
62
{
63
 
64
  // Constants and fields.
65
  // -------------------------------------------------------------------------
66
 
67
  /**
68
   * digestAlgorithm OBJECT IDENTIFIER ::=
69
   *   { iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) }
70
   */
71
  protected static final OID DIGEST_ALGORITHM = new OID("1.2.840.113549.2");
72
 
73
  protected final OID digestAlgorithm;
74
  protected final MessageDigest md;
75
  protected RSAPrivateKey signerKey;
76
  protected RSAPublicKey verifierKey;
77
 
78
  // Constructor.
79
  // -------------------------------------------------------------------------
80
 
81
  protected RSA(MessageDigest md, OID digestAlgorithm)
82
  {
83
    super();
84
    this.md = md;
85
    this.digestAlgorithm = digestAlgorithm;
86
  }
87
 
88
  // Instance methods.
89
  // -------------------------------------------------------------------------
90
 
91
  public Object clone() throws CloneNotSupportedException
92
  {
93
    return super.clone();
94
  }
95
 
96
  protected Object engineGetParameter(String param)
97
  {
98
    throw new UnsupportedOperationException("deprecated");
99
  }
100
 
101
  protected void engineSetParameter(String param, Object value)
102
  {
103
    throw new UnsupportedOperationException("deprecated");
104
  }
105
 
106
  protected void engineInitSign(PrivateKey privateKey)
107
    throws InvalidKeyException
108
  {
109
    if (!(privateKey instanceof RSAPrivateKey))
110
      throw new InvalidKeyException();
111
    verifierKey = null;
112
    signerKey = (RSAPrivateKey) privateKey;
113
  }
114
 
115
  protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
116
    throws InvalidKeyException
117
  {
118
    // This class does not need random bytes.
119
    engineInitSign(privateKey);
120
  }
121
 
122
  protected void engineInitVerify(PublicKey publicKey)
123
    throws InvalidKeyException
124
  {
125
    if (!(publicKey instanceof RSAPublicKey))
126
      throw new InvalidKeyException();
127
    signerKey = null;
128
    verifierKey = (RSAPublicKey) publicKey;
129
  }
130
 
131
  protected void engineUpdate(byte b) throws SignatureException
132
  {
133
    if (signerKey == null && verifierKey == null)
134
      throw new SignatureException("not initialized");
135
    md.update(b);
136
  }
137
 
138
  protected void engineUpdate(byte[] buf, int off, int len)
139
    throws SignatureException
140
  {
141
    if (signerKey == null && verifierKey == null)
142
      throw new SignatureException("not initialized");
143
    md.update(buf, off, len);
144
  }
145
 
146
  protected byte[] engineSign() throws SignatureException
147
  {
148
    if (signerKey == null)
149
      throw new SignatureException("not initialized for signing");
150
    //
151
    // The signature will be the RSA encrypted BER representation of
152
    // the following:
153
    //
154
    //   DigestInfo ::= SEQUENCE {
155
    //     digestAlgorithm  DigestAlgorithmIdentifier,
156
    //     digest           Digest }
157
    //
158
    //   DigestAlgorithmIdentifier ::= AlgorithmIdentifier
159
    //
160
    //   Digest ::= OCTET STRING
161
    //
162
    ArrayList digestAlg = new ArrayList(2);
163
    digestAlg.add(new DERValue(DER.OBJECT_IDENTIFIER, digestAlgorithm));
164
    digestAlg.add(new DERValue(DER.NULL, null));
165
    ArrayList digestInfo = new ArrayList(2);
166
    digestInfo.add(new DERValue(DER.SEQUENCE, digestAlg));
167
    digestInfo.add(new DERValue(DER.OCTET_STRING, md.digest()));
168
    ByteArrayOutputStream out = new ByteArrayOutputStream();
169
    try
170
      {
171
        DERWriter.write(out, new DERValue(DER.SEQUENCE, digestInfo));
172
      }
173
    catch (IOException ioe)
174
      {
175
        throw new SignatureException(ioe.toString());
176
      }
177
    byte[] buf = out.toByteArray();
178
    md.reset();
179
 
180
    // k = octect length of the modulus.
181
    int k = signerKey.getModulus().bitLength();
182
    k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1);
183
    if (buf.length < k - 3)
184
      {
185
        throw new SignatureException("RSA modulus too small");
186
      }
187
    byte[] d = new byte[k];
188
 
189
    // Padding type 1:
190
    //     00 | 01 | FF | ... | FF | 00 | D
191
    d[1] = 0x01;
192
    for (int i = 2; i < k - buf.length - 1; i++)
193
      d[i] = (byte) 0xFF;
194
    System.arraycopy(buf, 0, d, k - buf.length, buf.length);
195
 
196
    BigInteger eb = new BigInteger(d);
197
 
198
    byte[] ed = eb.modPow(signerKey.getPrivateExponent(),
199
                          signerKey.getModulus()).toByteArray();
200
 
201
    // Ensure output is k octets long.
202
    if (ed.length < k)
203
      {
204
        byte[] b = new byte[k];
205
        System.arraycopy(eb, 0, b, k - ed.length, ed.length);
206
        ed = b;
207
      }
208
    else if (ed.length > k)
209
      {
210
        if (ed.length != k + 1)
211
          {
212
            throw new SignatureException("modPow result is larger than the modulus");
213
          }
214
        // Maybe an extra 00 octect.
215
        byte[] b = new byte[k];
216
        System.arraycopy(ed, 1, b, 0, k);
217
        ed = b;
218
      }
219
 
220
    return ed;
221
  }
222
 
223
  protected int engineSign(byte[] out, int off, int len)
224
    throws SignatureException
225
  {
226
    if (out == null || off < 0 || len < 0 || off+len > out.length)
227
      throw new SignatureException("illegal output argument");
228
    byte[] result = engineSign();
229
    if (result.length > len)
230
      throw new SignatureException("not enough space for signature");
231
    System.arraycopy(result, 0, out, off, result.length);
232
    return result.length;
233
  }
234
 
235
  protected boolean engineVerify(byte[] sig) throws SignatureException
236
  {
237
    if (verifierKey == null)
238
      throw new SignatureException("not initialized for verifying");
239
    if (sig == null)
240
      throw new SignatureException("no signature specified");
241
    int k = verifierKey.getModulus().bitLength();
242
    k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1);
243
    if (sig.length != k)
244
      throw new SignatureException("signature is the wrong size (expecting "
245
                                   + k + " bytes, got " + sig.length + ")");
246
    BigInteger ed = new BigInteger(1, sig);
247
    byte[] eb = ed.modPow(verifierKey.getPublicExponent(),
248
                          verifierKey.getModulus()).toByteArray();
249
 
250
    int i = 0;
251
    if (eb[0] == 0x00)
252
      {
253
        for (i = 1; i < eb.length && eb[i] == 0x00; i++);
254
        if (i == 1)
255
          throw new SignatureException("wrong RSA padding");
256
        i--;
257
      }
258
    else if (eb[0] == 0x01)
259
      {
260
        for (i = 1; i < eb.length && eb[i] != 0x00; i++)
261
          if (eb[i] != (byte) 0xFF)
262
            throw new IllegalArgumentException("wrong RSA padding");
263
      }
264
    else
265
      throw new SignatureException("wrong RSA padding type");
266
 
267
    byte[] d = new byte[eb.length-i-1];
268
    System.arraycopy(eb, i+1, d, 0, eb.length-i-1);
269
 
270
    DERReader der = new DERReader(d);
271
    try
272
      {
273
        DERValue val = der.read();
274
        if (val.getTag() != DER.SEQUENCE)
275
          throw new SignatureException("failed to parse DigestInfo");
276
        val = der.read();
277
        if (val.getTag() != DER.SEQUENCE)
278
          throw new SignatureException("failed to parse DigestAlgorithmIdentifier");
279
        boolean sequenceIsBer = val.getLength() == 0;
280
        val = der.read();
281
        if (val.getTag() != DER.OBJECT_IDENTIFIER)
282
          throw new SignatureException("failed to parse object identifier");
283
        if (!val.getValue().equals(digestAlgorithm))
284
          throw new SignatureException("digest algorithms do not match");
285
        val = der.read();
286
        // We should never see parameters here, since they are never used.
287
        if (val.getTag() != DER.NULL)
288
          throw new SignatureException("cannot handle digest parameters");
289
        if (sequenceIsBer)
290
          der.skip(1); // end-of-sequence byte.
291
        val = der.read();
292
        if (val.getTag() != DER.OCTET_STRING)
293
          throw new SignatureException("failed to parse Digest");
294
        return MessageDigest.isEqual(md.digest(), (byte[]) val.getValue());
295
      }
296
    catch (IOException ioe)
297
      {
298
        throw new SignatureException(ioe.toString());
299
      }
300
  }
301
 
302
  protected boolean engineVerify(byte[] sig, int off, int len)
303
    throws SignatureException
304
  {
305
    if (sig == null || off < 0 || len < 0 || off+len > sig.length)
306
      throw new SignatureException("illegal parameter");
307
    byte[] buf = new byte[len];
308
    System.arraycopy(sig, off, buf, 0, len);
309
    return engineVerify(buf);
310
  }
311
}

powered by: WebSVN 2.1.0

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