1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /**
6  * Licensed to the Apache Software Foundation (ASF) under one
7  * or more contributor license agreements. See the NOTICE file
8  * distributed with this work for additional information
9  * regarding copyright ownership. The ASF licenses this file
10  * to you under the Apache License, Version 2.0 (the
11  * "License"); you may not use this file except in compliance
12  * with the License. You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing,
17  * software distributed under the License is distributed on an
18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19  * KIND, either express or implied. See the License for the
20  * specific language governing permissions and limitations
21  * under the License.
22  */
23 package com.sun.org.apache.xml.internal.security.algorithms.implementations;
24 
25 import java.io.IOException;
26 import java.security.InvalidAlgorithmParameterException;
27 import java.security.InvalidKeyException;
28 import java.security.Key;
29 import java.security.NoSuchProviderException;
30 import java.security.PrivateKey;
31 import java.security.PublicKey;
32 import java.security.SecureRandom;
33 import java.security.Signature;
34 import java.security.SignatureException;
35 import java.security.spec.AlgorithmParameterSpec;
36 
37 import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
38 import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi;
39 import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
40 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
41 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
42 
43 /**
44  *
45  */
46 public abstract class SignatureECDSA extends SignatureAlgorithmSpi {
47 
48     private static final com.sun.org.slf4j.internal.Logger LOG =
49         com.sun.org.slf4j.internal.LoggerFactory.getLogger(SignatureECDSA.class);
50 
51     /** {@inheritDoc} */
engineGetURI()52     public abstract String engineGetURI();
53 
54     /** Field algorithm */
55     private Signature signatureAlgorithm;
56 
57     /**
58      * Converts an ASN.1 ECDSA value to a XML Signature ECDSA Value.
59      *
60      * The JAVA JCE ECDSA Signature algorithm creates ASN.1 encoded (r, s) value
61      * pairs; the XML Signature requires the core BigInteger values.
62      *
63      * @param asn1Bytes
64      * @return the decode bytes
65      *
66      * @throws IOException
67      * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
68      * @see <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc4050.txt">3.3. ECDSA Signatures</A>
69      */
convertASN1toXMLDSIG(byte asn1Bytes[])70     public static byte[] convertASN1toXMLDSIG(byte asn1Bytes[]) throws IOException {
71         return ECDSAUtils.convertASN1toXMLDSIG(asn1Bytes);
72     }
73 
74     /**
75      * Converts a XML Signature ECDSA Value to an ASN.1 DSA value.
76      *
77      * The JAVA JCE ECDSA Signature algorithm creates ASN.1 encoded (r, s) value
78      * pairs; the XML Signature requires the core BigInteger values.
79      *
80      * @param xmldsigBytes
81      * @return the encoded ASN.1 bytes
82      *
83      * @throws IOException
84      * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
85      * @see <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc4050.txt">3.3. ECDSA Signatures</A>
86      */
convertXMLDSIGtoASN1(byte xmldsigBytes[])87     public static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[]) throws IOException {
88         return ECDSAUtils.convertXMLDSIGtoASN1(xmldsigBytes);
89     }
90 
91     /**
92      * Constructor SignatureRSA
93      *
94      * @throws XMLSignatureException
95      */
SignatureECDSA()96     public SignatureECDSA() throws XMLSignatureException {
97 
98         String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
99 
100         LOG.debug("Created SignatureECDSA using {}", algorithmID);
101         String provider = JCEMapper.getProviderId();
102         try {
103             if (provider == null) {
104                 this.signatureAlgorithm = Signature.getInstance(algorithmID);
105             } else {
106                 this.signatureAlgorithm = Signature.getInstance(algorithmID, provider);
107             }
108         } catch (java.security.NoSuchAlgorithmException ex) {
109             Object[] exArgs = { algorithmID, ex.getLocalizedMessage() };
110 
111             throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs);
112         } catch (NoSuchProviderException ex) {
113             Object[] exArgs = { algorithmID, ex.getLocalizedMessage() };
114 
115             throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs);
116         }
117     }
118 
119     /** {@inheritDoc} */
engineSetParameter(AlgorithmParameterSpec params)120     protected void engineSetParameter(AlgorithmParameterSpec params)
121         throws XMLSignatureException {
122         try {
123             this.signatureAlgorithm.setParameter(params);
124         } catch (InvalidAlgorithmParameterException ex) {
125             throw new XMLSignatureException(ex);
126         }
127     }
128 
129     /** {@inheritDoc} */
engineVerify(byte[] signature)130     protected boolean engineVerify(byte[] signature) throws XMLSignatureException {
131         try {
132             byte[] jcebytes = SignatureECDSA.convertXMLDSIGtoASN1(signature);
133 
134             if (LOG.isDebugEnabled()) {
135                 LOG.debug("Called ECDSA.verify() on " + XMLUtils.encodeToString(signature));
136             }
137 
138             return this.signatureAlgorithm.verify(jcebytes);
139         } catch (SignatureException ex) {
140             throw new XMLSignatureException(ex);
141         } catch (IOException ex) {
142             throw new XMLSignatureException(ex);
143         }
144     }
145 
146     /** {@inheritDoc} */
engineInitVerify(Key publicKey)147     protected void engineInitVerify(Key publicKey) throws XMLSignatureException {
148 
149         if (!(publicKey instanceof PublicKey)) {
150             String supplied = null;
151             if (publicKey != null) {
152                 supplied = publicKey.getClass().getName();
153             }
154             String needed = PublicKey.class.getName();
155             Object exArgs[] = { supplied, needed };
156 
157             throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs);
158         }
159 
160         try {
161             this.signatureAlgorithm.initVerify((PublicKey) publicKey);
162         } catch (InvalidKeyException ex) {
163             // reinstantiate Signature object to work around bug in JDK
164             // see: http://bugs.java.com/view_bug.do?bug_id=4953555
165             Signature sig = this.signatureAlgorithm;
166             try {
167                 this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
168             } catch (Exception e) {
169                 // this shouldn't occur, but if it does, restore previous
170                 // Signature
171                 LOG.debug("Exception when reinstantiating Signature: {}", e);
172                 this.signatureAlgorithm = sig;
173             }
174             throw new XMLSignatureException(ex);
175         }
176     }
177 
178     /** {@inheritDoc} */
engineSign()179     protected byte[] engineSign() throws XMLSignatureException {
180         try {
181             byte jcebytes[] = this.signatureAlgorithm.sign();
182 
183             return SignatureECDSA.convertASN1toXMLDSIG(jcebytes);
184         } catch (SignatureException ex) {
185             throw new XMLSignatureException(ex);
186         } catch (IOException ex) {
187             throw new XMLSignatureException(ex);
188         }
189     }
190 
191     /** {@inheritDoc} */
engineInitSign(Key privateKey, SecureRandom secureRandom)192     protected void engineInitSign(Key privateKey, SecureRandom secureRandom)
193         throws XMLSignatureException {
194         if (!(privateKey instanceof PrivateKey)) {
195             String supplied = null;
196             if (privateKey != null) {
197                 supplied = privateKey.getClass().getName();
198             }
199             String needed = PrivateKey.class.getName();
200             Object exArgs[] = { supplied, needed };
201 
202             throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs);
203         }
204 
205         try {
206             if (secureRandom == null) {
207                 this.signatureAlgorithm.initSign((PrivateKey) privateKey);
208             } else {
209                 this.signatureAlgorithm.initSign((PrivateKey) privateKey, secureRandom);
210             }
211         } catch (InvalidKeyException ex) {
212             throw new XMLSignatureException(ex);
213         }
214     }
215 
216     /** {@inheritDoc} */
engineInitSign(Key privateKey)217     protected void engineInitSign(Key privateKey) throws XMLSignatureException {
218         engineInitSign(privateKey, (SecureRandom)null);
219     }
220 
221     /** {@inheritDoc} */
engineUpdate(byte[] input)222     protected void engineUpdate(byte[] input) throws XMLSignatureException {
223         try {
224             this.signatureAlgorithm.update(input);
225         } catch (SignatureException ex) {
226             throw new XMLSignatureException(ex);
227         }
228     }
229 
230     /** {@inheritDoc} */
engineUpdate(byte input)231     protected void engineUpdate(byte input) throws XMLSignatureException {
232         try {
233             this.signatureAlgorithm.update(input);
234         } catch (SignatureException ex) {
235             throw new XMLSignatureException(ex);
236         }
237     }
238 
239     /** {@inheritDoc} */
engineUpdate(byte buf[], int offset, int len)240     protected void engineUpdate(byte buf[], int offset, int len) throws XMLSignatureException {
241         try {
242             this.signatureAlgorithm.update(buf, offset, len);
243         } catch (SignatureException ex) {
244             throw new XMLSignatureException(ex);
245         }
246     }
247 
248     /** {@inheritDoc} */
engineGetJCEAlgorithmString()249     protected String engineGetJCEAlgorithmString() {
250         return this.signatureAlgorithm.getAlgorithm();
251     }
252 
253     /** {@inheritDoc} */
engineGetJCEProviderName()254     protected String engineGetJCEProviderName() {
255         return this.signatureAlgorithm.getProvider().getName();
256     }
257 
258     /** {@inheritDoc} */
engineSetHMACOutputLength(int HMACOutputLength)259     protected void engineSetHMACOutputLength(int HMACOutputLength)
260         throws XMLSignatureException {
261         throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC");
262     }
263 
264     /** {@inheritDoc} */
engineInitSign( Key signingKey, AlgorithmParameterSpec algorithmParameterSpec )265     protected void engineInitSign(
266         Key signingKey, AlgorithmParameterSpec algorithmParameterSpec
267     ) throws XMLSignatureException {
268         throw new XMLSignatureException("algorithms.CannotUseAlgorithmParameterSpecOnRSA");
269     }
270 
271     /**
272      * Class SignatureECDSASHA1
273      *
274      */
275     public static class SignatureECDSASHA1 extends SignatureECDSA {
276         /**
277          * Constructor SignatureECDSASHA1
278          *
279          * @throws XMLSignatureException
280          */
SignatureECDSASHA1()281         public SignatureECDSASHA1() throws XMLSignatureException {
282             super();
283         }
284 
285         /** {@inheritDoc} */
engineGetURI()286         public String engineGetURI() {
287             return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA1;
288         }
289     }
290 
291     /**
292      * Class SignatureECDSASHA224
293      */
294     public static class SignatureECDSASHA224 extends SignatureECDSA {
295 
296         /**
297          * Constructor SignatureECDSASHA224
298          *
299          * @throws XMLSignatureException
300          */
SignatureECDSASHA224()301         public SignatureECDSASHA224() throws XMLSignatureException {
302             super();
303         }
304 
305         /** {@inheritDoc} */
engineGetURI()306         public String engineGetURI() {
307             return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA224;
308         }
309     }
310 
311     /**
312      * Class SignatureECDSASHA256
313      *
314      */
315     public static class SignatureECDSASHA256 extends SignatureECDSA {
316 
317         /**
318          * Constructor SignatureECDSASHA256
319          *
320          * @throws XMLSignatureException
321          */
SignatureECDSASHA256()322         public SignatureECDSASHA256() throws XMLSignatureException {
323             super();
324         }
325 
326         /** {@inheritDoc} */
engineGetURI()327         public String engineGetURI() {
328             return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA256;
329         }
330     }
331 
332     /**
333      * Class SignatureECDSASHA384
334      *
335      */
336     public static class SignatureECDSASHA384 extends SignatureECDSA {
337 
338         /**
339          * Constructor SignatureECDSASHA384
340          *
341          * @throws XMLSignatureException
342          */
SignatureECDSASHA384()343         public SignatureECDSASHA384() throws XMLSignatureException {
344             super();
345         }
346 
347         /** {@inheritDoc} */
engineGetURI()348         public String engineGetURI() {
349             return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA384;
350         }
351     }
352 
353     /**
354      * Class SignatureECDSASHA512
355      *
356      */
357     public static class SignatureECDSASHA512 extends SignatureECDSA {
358 
359         /**
360          * Constructor SignatureECDSASHA512
361          *
362          * @throws XMLSignatureException
363          */
SignatureECDSASHA512()364         public SignatureECDSASHA512() throws XMLSignatureException {
365             super();
366         }
367 
368         /** {@inheritDoc} */
engineGetURI()369         public String engineGetURI() {
370             return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA512;
371         }
372     }
373 
374     /**
375      * Class SignatureECDSARIPEMD160
376      */
377     public static class SignatureECDSARIPEMD160 extends SignatureECDSA {
378 
379         /**
380          * Constructor SignatureECDSARIPEMD160
381          *
382          * @throws XMLSignatureException
383          */
SignatureECDSARIPEMD160()384         public SignatureECDSARIPEMD160() throws XMLSignatureException {
385             super();
386         }
387 
388         /** {@inheritDoc} */
engineGetURI()389         public String engineGetURI() {
390             return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_RIPEMD160;
391         }
392     }
393 
394 }
395