KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > security > algorithms > implementations > SignatureDSA


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package com.sun.org.apache.xml.internal.security.algorithms.implementations;
18
19
20
21 import java.io.IOException JavaDoc;
22 import java.security.InvalidAlgorithmParameterException JavaDoc;
23 import java.security.InvalidKeyException JavaDoc;
24 import java.security.Key JavaDoc;
25 import java.security.PrivateKey JavaDoc;
26 import java.security.PublicKey JavaDoc;
27 import java.security.SecureRandom JavaDoc;
28 import java.security.Signature JavaDoc;
29 import java.security.SignatureException JavaDoc;
30 import java.security.spec.AlgorithmParameterSpec JavaDoc;
31
32 import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
33 import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi;
34 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
35 import com.sun.org.apache.xml.internal.security.utils.Base64;
36 import com.sun.org.apache.xml.internal.security.utils.Constants;
37
38
39 /**
40  *
41  * @author $Author: vishal $
42  */

43 public class SignatureDSA extends SignatureAlgorithmSpi {
44
45    /** {@link java.util.logging} logging facility */
46     static java.util.logging.Logger JavaDoc log =
47         java.util.logging.Logger.getLogger(SignatureDSA.class.getName());
48
49    /** Field _URI */
50    public static final String JavaDoc _URI = Constants.SignatureSpecNS + "dsa-sha1";
51
52    /** Field algorithm */
53    private java.security.Signature JavaDoc _signatureAlgorithm = null;
54
55    /**
56     * Method engineGetURI
57     *
58     * @inheritDoc
59     */

60    protected String JavaDoc engineGetURI() {
61       return SignatureDSA._URI;
62    }
63
64    /**
65     * Constructor SignatureDSA
66     *
67     * @throws XMLSignatureException
68     */

69    public SignatureDSA() throws XMLSignatureException {
70
71       String JavaDoc algorithmID = JCEMapper.translateURItoJCEID(SignatureDSA._URI);
72       if (true)
73         if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Created SignatureDSA using " + algorithmID);
74
75       try {
76          this._signatureAlgorithm = Signature.getInstance(algorithmID);
77       } catch (java.security.NoSuchAlgorithmException JavaDoc ex) {
78          Object JavaDoc[] exArgs = { algorithmID,
79                              ex.getLocalizedMessage() };
80
81          throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs);
82       }
83    }
84
85    /**
86     * @inheritDoc
87     */

88    protected void engineSetParameter(AlgorithmParameterSpec JavaDoc params)
89            throws XMLSignatureException {
90
91       try {
92          this._signatureAlgorithm.setParameter(params);
93       } catch (InvalidAlgorithmParameterException JavaDoc ex) {
94          throw new XMLSignatureException("empty", ex);
95       }
96    }
97
98    /**
99     * @inheritDoc
100     */

101    protected boolean engineVerify(byte[] signature)
102            throws XMLSignatureException {
103
104       try {
105          if (true)
106             if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Called DSA.verify() on " + Base64.encode(signature));
107
108          byte[] jcebytes = SignatureDSA.convertXMLDSIGtoASN1(signature);
109
110          return this._signatureAlgorithm.verify(jcebytes);
111       } catch (SignatureException JavaDoc ex) {
112          throw new XMLSignatureException("empty", ex);
113       } catch (IOException JavaDoc ex) {
114          throw new XMLSignatureException("empty", ex);
115       }
116    }
117
118    /**
119     * @inheritDoc
120     */

121    protected void engineInitVerify(Key JavaDoc publicKey) throws XMLSignatureException {
122
123       if (!(publicKey instanceof PublicKey JavaDoc)) {
124          String JavaDoc supplied = publicKey.getClass().getName();
125          String JavaDoc needed = PublicKey JavaDoc.class.getName();
126          Object JavaDoc exArgs[] = { supplied, needed };
127
128          throw new XMLSignatureException("algorithms.WrongKeyForThisOperation",
129                                          exArgs);
130       }
131
132       try {
133          this._signatureAlgorithm.initVerify((PublicKey JavaDoc) publicKey);
134       } catch (InvalidKeyException JavaDoc ex) {
135          throw new XMLSignatureException("empty", ex);
136       }
137    }
138
139    /**
140     * @inheritDoc
141     */

142    protected byte[] engineSign() throws XMLSignatureException {
143
144       try {
145          byte jcebytes[] = this._signatureAlgorithm.sign();
146
147          return SignatureDSA.convertASN1toXMLDSIG(jcebytes);
148       } catch (IOException JavaDoc ex) {
149          throw new XMLSignatureException("empty", ex);
150       } catch (SignatureException JavaDoc ex) {
151          throw new XMLSignatureException("empty", ex);
152       }
153    }
154
155    /**
156     * @inheritDoc
157     */

158    protected void engineInitSign(Key JavaDoc privateKey, SecureRandom JavaDoc secureRandom)
159            throws XMLSignatureException {
160
161       if (!(privateKey instanceof PrivateKey JavaDoc)) {
162          String JavaDoc supplied = privateKey.getClass().getName();
163          String JavaDoc needed = PrivateKey JavaDoc.class.getName();
164          Object JavaDoc exArgs[] = { supplied, needed };
165
166          throw new XMLSignatureException("algorithms.WrongKeyForThisOperation",
167                                          exArgs);
168       }
169
170       try {
171          this._signatureAlgorithm.initSign((PrivateKey JavaDoc) privateKey,
172                                            secureRandom);
173       } catch (InvalidKeyException JavaDoc ex) {
174          throw new XMLSignatureException("empty", ex);
175       }
176    }
177
178    /**
179     * @inheritDoc
180     */

181    protected void engineInitSign(Key JavaDoc privateKey) throws XMLSignatureException {
182
183       if (!(privateKey instanceof PrivateKey JavaDoc)) {
184          String JavaDoc supplied = privateKey.getClass().getName();
185          String JavaDoc needed = PrivateKey JavaDoc.class.getName();
186          Object JavaDoc exArgs[] = { supplied, needed };
187
188          throw new XMLSignatureException("algorithms.WrongKeyForThisOperation",
189                                          exArgs);
190       }
191
192       try {
193          this._signatureAlgorithm.initSign((PrivateKey JavaDoc) privateKey);
194       } catch (InvalidKeyException JavaDoc ex) {
195          throw new XMLSignatureException("empty", ex);
196       }
197    }
198
199    /**
200     * @inheritDoc
201     */

202    protected void engineUpdate(byte[] input) throws XMLSignatureException {
203
204       try {
205          this._signatureAlgorithm.update(input);
206       } catch (SignatureException JavaDoc ex) {
207          throw new XMLSignatureException("empty", ex);
208       }
209    }
210
211    /**
212     * @inheritDoc
213     */

214    protected void engineUpdate(byte input) throws XMLSignatureException {
215
216       try {
217          this._signatureAlgorithm.update(input);
218       } catch (SignatureException JavaDoc ex) {
219          throw new XMLSignatureException("empty", ex);
220       }
221    }
222
223    /**
224     * @inheritDoc
225     */

226    protected void engineUpdate(byte buf[], int offset, int len)
227            throws XMLSignatureException {
228
229       try {
230          this._signatureAlgorithm.update(buf, offset, len);
231       } catch (SignatureException JavaDoc ex) {
232          throw new XMLSignatureException("empty", ex);
233       }
234    }
235
236    /**
237     * Method engineGetJCEAlgorithmString
238     *
239     * @inheritDoc
240     */

241    protected String JavaDoc engineGetJCEAlgorithmString() {
242       return this._signatureAlgorithm.getAlgorithm();
243    }
244
245    /**
246     * Method engineGetJCEProviderName
247     *
248     * @inheritDoc
249     */

250    protected String JavaDoc engineGetJCEProviderName() {
251       return this._signatureAlgorithm.getProvider().getName();
252    }
253
254
255    /**
256     * Converts an ASN.1 DSA value to a XML Signature DSA Value.
257     *
258     * The JAVA JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value
259     * pairs; the XML Signature requires the core BigInteger values.
260     *
261     * @param asn1Bytes
262     * @return the decode bytes
263     *
264     * @throws IOException
265     * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
266     */

267    private static byte[] convertASN1toXMLDSIG(byte asn1Bytes[])
268            throws IOException JavaDoc {
269
270       byte rLength = asn1Bytes[3];
271       int i;
272
273       for (i = rLength; (i > 0) && (asn1Bytes[(4 + rLength) - i] == 0); i--);
274
275       byte sLength = asn1Bytes[5 + rLength];
276       int j;
277
278       for (j = sLength;
279               (j > 0) && (asn1Bytes[(6 + rLength + sLength) - j] == 0); j--);
280
281       if ((asn1Bytes[0] != 48) || (asn1Bytes[1] != asn1Bytes.length - 2)
282               || (asn1Bytes[2] != 2) || (i > 20)
283               || (asn1Bytes[4 + rLength] != 2) || (j > 20)) {
284          throw new IOException JavaDoc("Invalid ASN.1 format of DSA signature");
285       }
286       byte xmldsigBytes[] = new byte[40];
287
288       System.arraycopy(asn1Bytes, (4 + rLength) - i, xmldsigBytes, 20 - i,
289                           i);
290       System.arraycopy(asn1Bytes, (6 + rLength + sLength) - j, xmldsigBytes,
291                           40 - j, j);
292
293        return xmldsigBytes;
294    }
295
296    /**
297     * Converts a XML Signature DSA Value to an ASN.1 DSA value.
298     *
299     * The JAVA JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value
300     * pairs; the XML Signature requires the core BigInteger values.
301     *
302     * @param xmldsigBytes
303     * @return the encoded ASN.1 bytes
304     *
305     * @throws IOException
306     * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
307     */

308    private static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[])
309            throws IOException JavaDoc {
310
311       if (xmldsigBytes.length != 40) {
312          throw new IOException JavaDoc("Invalid XMLDSIG format of DSA signature");
313       }
314
315       int i;
316
317       for (i = 20; (i > 0) && (xmldsigBytes[20 - i] == 0); i--);
318
319       int j = i;
320
321       if (xmldsigBytes[20 - i] < 0) {
322          j += 1;
323       }
324
325       int k;
326
327       for (k = 20; (k > 0) && (xmldsigBytes[40 - k] == 0); k--);
328
329       int l = k;
330
331       if (xmldsigBytes[40 - k] < 0) {
332          l += 1;
333       }
334
335       byte asn1Bytes[] = new byte[6 + j + l];
336
337       asn1Bytes[0] = 48;
338       asn1Bytes[1] = (byte) (4 + j + l);
339       asn1Bytes[2] = 2;
340       asn1Bytes[3] = (byte) j;
341
342       System.arraycopy(xmldsigBytes, 20 - i, asn1Bytes, (4 + j) - i, i);
343
344       asn1Bytes[4 + j] = 2;
345       asn1Bytes[5 + j] = (byte) l;
346
347       System.arraycopy(xmldsigBytes, 40 - k, asn1Bytes, (6 + j + l) - k, k);
348
349       return asn1Bytes;
350    }
351
352    /**
353     * Method engineSetHMACOutputLength
354     *
355     * @param HMACOutputLength
356     * @throws XMLSignatureException
357     */

358    protected void engineSetHMACOutputLength(int HMACOutputLength)
359            throws XMLSignatureException {
360       throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC");
361    }
362
363    /**
364     * Method engineInitSign
365     *
366     * @param signingKey
367     * @param algorithmParameterSpec
368     * @throws XMLSignatureException
369     */

370    protected void engineInitSign(
371            Key JavaDoc signingKey, AlgorithmParameterSpec JavaDoc algorithmParameterSpec)
372               throws XMLSignatureException {
373       throw new XMLSignatureException(
374          "algorithms.CannotUseAlgorithmParameterSpecOnDSA");
375    }
376 }
377
Popular Tags