001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Boris V. Kuznetsov
020: * @version $Revision$
021: */package java.security;
022:
023: import java.nio.ByteBuffer;
024: import java.security.cert.Certificate;
025: import java.security.cert.X509Certificate;
026: import java.security.spec.AlgorithmParameterSpec;
027: import java.util.Iterator;
028: import java.util.Set;
029:
030: import org.apache.harmony.security.fortress.Engine;
031: import org.apache.harmony.security.internal.nls.Messages;
032:
033: /**
034: * @com.intel.drl.spec_ref
035: *
036: */
037:
038: public abstract class Signature extends SignatureSpi {
039:
040: // The service name.
041: private static final String SERVICE = "Signature"; //$NON-NLS-1$
042:
043: // Used to access common engine functionality
044: private static Engine engine = new Engine(SERVICE);
045:
046: // The provider
047: private Provider provider;
048:
049: // The algorithm.
050: private String algorithm;
051:
052: /**
053: * @com.intel.drl.spec_ref
054: *
055: */
056: protected static final int UNINITIALIZED = 0;
057:
058: /**
059: * @com.intel.drl.spec_ref
060: *
061: */
062: protected static final int SIGN = 2;
063:
064: /**
065: * @com.intel.drl.spec_ref
066: *
067: */
068: protected static final int VERIFY = 3;
069:
070: /**
071: * @com.intel.drl.spec_ref
072: *
073: */
074: protected int state = UNINITIALIZED;
075:
076: /**
077: * @com.intel.drl.spec_ref
078: *
079: */
080: protected Signature(String algorithm) {
081: this .algorithm = algorithm;
082: }
083:
084: /**
085: * @com.intel.drl.spec_ref
086: *
087: */
088: public static Signature getInstance(String algorithm)
089: throws NoSuchAlgorithmException {
090: if (algorithm == null) {
091: throw new NullPointerException(Messages
092: .getString("security.01")); //$NON-NLS-1$
093: }
094: Signature result;
095: synchronized (engine) {
096: engine.getInstance(algorithm, null);
097: if (engine.spi instanceof Signature) {
098: result = (Signature) engine.spi;
099: result.algorithm = algorithm;
100: result.provider = engine.provider;
101: } else {
102: result = new SignatureImpl((SignatureSpi) engine.spi,
103: engine.provider, algorithm);
104: }
105: }
106: return result;
107: }
108:
109: /**
110: * @com.intel.drl.spec_ref
111: *
112: */
113: public static Signature getInstance(String algorithm,
114: String provider) throws NoSuchAlgorithmException,
115: NoSuchProviderException {
116: if (algorithm == null) {
117: throw new NullPointerException(Messages
118: .getString("security.01")); //$NON-NLS-1$
119: }
120: if ((provider == null) || (provider.length() == 0)) {
121: throw new IllegalArgumentException(Messages
122: .getString("security.02")); //$NON-NLS-1$
123: }
124: Provider p = Security.getProvider(provider);
125: if (p == null) {
126: throw new NoSuchProviderException(Messages.getString(
127: "security.03", provider)); //$NON-NLS-1$
128: }
129: return getSignatureInstance(algorithm, p);
130: }
131:
132: /**
133: * @com.intel.drl.spec_ref
134: *
135: */
136: public static Signature getInstance(String algorithm,
137: Provider provider) throws NoSuchAlgorithmException {
138: if (algorithm == null) {
139: throw new NullPointerException(Messages
140: .getString("security.01")); //$NON-NLS-1$
141: }
142: if (provider == null) {
143: throw new IllegalArgumentException(Messages
144: .getString("security.04")); //$NON-NLS-1$
145: }
146: return getSignatureInstance(algorithm, provider);
147: }
148:
149: private static Signature getSignatureInstance(String algorithm,
150: Provider provider) throws NoSuchAlgorithmException {
151: Signature result;
152: synchronized (engine) {
153: engine.getInstance(algorithm, provider, null);
154: if (engine.spi instanceof Signature) {
155: result = (Signature) engine.spi;
156: result.algorithm = algorithm;
157: result.provider = provider;
158: } else {
159: result = new SignatureImpl((SignatureSpi) engine.spi,
160: provider, algorithm);
161: }
162: }
163: return result;
164: }
165:
166: /**
167: * @com.intel.drl.spec_ref
168: *
169: */
170: public final Provider getProvider() {
171: return provider;
172: }
173:
174: /**
175: * @com.intel.drl.spec_ref
176: *
177: */
178: public final String getAlgorithm() {
179: return algorithm;
180: }
181:
182: /**
183: * @com.intel.drl.spec_ref
184: *
185: */
186: public final void initVerify(PublicKey publicKey)
187: throws InvalidKeyException {
188: engineInitVerify(publicKey);
189: state = VERIFY;
190: }
191:
192: /**
193: * @com.intel.drl.spec_ref
194: *
195: */
196: public final void initVerify(Certificate certificate)
197: throws InvalidKeyException {
198: if (certificate instanceof X509Certificate) {
199: Set ce = ((X509Certificate) certificate)
200: .getCriticalExtensionOIDs();
201: boolean critical = false;
202: if (ce != null && !ce.isEmpty()) {
203: for (Iterator i = ce.iterator(); i.hasNext();) {
204: if ("2.5.29.15".equals(i.next())) { //$NON-NLS-1$
205: //KeyUsage OID = 2.5.29.15
206: critical = true;
207: break;
208: }
209: }
210: if (critical) {
211: boolean[] keyUsage = ((X509Certificate) certificate)
212: .getKeyUsage();
213: // As specified in RFC 3280 -
214: // Internet X.509 Public Key Infrastructure
215: // Certificate and Certificate Revocation List (CRL) Profile.
216: // (http://www.ietf.org/rfc/rfc3280.txt)
217: //
218: // KeyUsage ::= BIT STRING { digitalSignature (0), <skipped> }
219: if ((keyUsage != null) && (!keyUsage[0])) { // digitalSignature
220: throw new InvalidKeyException(Messages
221: .getString("security.26")); //$NON-NLS-1$
222: }
223: }
224: }
225: }
226: engineInitVerify(certificate.getPublicKey());
227: state = VERIFY;
228: }
229:
230: /**
231: * @com.intel.drl.spec_ref
232: *
233: */
234: public final void initSign(PrivateKey privateKey)
235: throws InvalidKeyException {
236: engineInitSign(privateKey);
237: state = SIGN;
238: }
239:
240: /**
241: * @com.intel.drl.spec_ref
242: *
243: */
244: public final void initSign(PrivateKey privateKey,
245: SecureRandom random) throws InvalidKeyException {
246: engineInitSign(privateKey, random);
247: state = SIGN;
248: }
249:
250: /**
251: * @com.intel.drl.spec_ref
252: *
253: */
254: public final byte[] sign() throws SignatureException {
255: if (state != SIGN) {
256: throw new SignatureException(Messages
257: .getString("security.27")); //$NON-NLS-1$
258: }
259: return engineSign();
260: }
261:
262: /**
263: * @com.intel.drl.spec_ref
264: *
265: */
266: public final int sign(byte[] outbuf, int offset, int len)
267: throws SignatureException {
268: if (outbuf == null || offset < 0 || len < 0
269: || offset + len > outbuf.length) {
270: throw new IllegalArgumentException(Messages
271: .getString("security.05")); //$NON-NLS-1$
272: }
273: if (state != SIGN) {
274: throw new SignatureException(Messages
275: .getString("security.27")); //$NON-NLS-1$
276: }
277: return engineSign(outbuf, offset, len);
278: }
279:
280: /**
281: * @com.intel.drl.spec_ref
282: *
283: */
284: public final boolean verify(byte[] signature)
285: throws SignatureException {
286: if (state != VERIFY) {
287: throw new SignatureException(Messages
288: .getString("security.27")); //$NON-NLS-1$
289: }
290: return engineVerify(signature);
291: }
292:
293: /**
294: * @com.intel.drl.spec_ref
295: *
296: */
297: public final boolean verify(byte[] signature, int offset, int length)
298: throws SignatureException {
299: if (state != VERIFY) {
300: throw new SignatureException(Messages
301: .getString("security.27")); //$NON-NLS-1$
302: }
303: if (signature == null || offset < 0 || length < 0
304: || offset + length > signature.length) {
305: throw new IllegalArgumentException(Messages
306: .getString("security.05")); //$NON-NLS-1$
307: }
308: return engineVerify(signature, offset, length);
309: }
310:
311: /**
312: * @com.intel.drl.spec_ref
313: *
314: */
315: public final void update(byte b) throws SignatureException {
316: if (state == UNINITIALIZED) {
317: throw new SignatureException(Messages
318: .getString("security.27")); //$NON-NLS-1$
319: }
320: engineUpdate(b);
321: }
322:
323: /**
324: * @com.intel.drl.spec_ref
325: *
326: */
327: public final void update(byte[] data) throws SignatureException {
328: if (state == UNINITIALIZED) {
329: throw new SignatureException(Messages
330: .getString("security.27")); //$NON-NLS-1$
331: }
332: engineUpdate(data, 0, data.length);
333: }
334:
335: /**
336: * @com.intel.drl.spec_ref
337: *
338: */
339: public final void update(byte[] data, int off, int len)
340: throws SignatureException {
341: if (state == UNINITIALIZED) {
342: throw new SignatureException(Messages
343: .getString("security.27")); //$NON-NLS-1$
344: }
345: if (data == null || off < 0 || len < 0
346: || off + len > data.length) {
347: throw new IllegalArgumentException(Messages
348: .getString("security.05")); //$NON-NLS-1$
349: }
350: engineUpdate(data, off, len);
351: }
352:
353: /**
354: * @com.intel.drl.spec_ref
355: *
356: */
357: public final void update(ByteBuffer data) throws SignatureException {
358: if (state == UNINITIALIZED) {
359: throw new SignatureException(Messages
360: .getString("security.27")); //$NON-NLS-1$
361: }
362: engineUpdate(data);
363: }
364:
365: /**
366: * @com.intel.drl.spec_ref
367: *
368: */
369: public String toString() {
370: return "SIGNATURE " + algorithm + " state: " + stateToString(state); //$NON-NLS-1$ //$NON-NLS-2$
371: }
372:
373: // Convert state to string
374: private String stateToString(int state) {
375: switch (state) {
376: case UNINITIALIZED:
377: return "UNINITIALIZED"; //$NON-NLS-1$
378: case SIGN:
379: return "SIGN"; //$NON-NLS-1$
380: case VERIFY:
381: return "VERIFY"; //$NON-NLS-1$
382: default:
383: return ""; //$NON-NLS-1$
384: }
385: }
386:
387: /**
388: * @com.intel.drl.spec_ref
389: *
390: * @deprecated Use {@link Signature#setParameter(AlgorithmParameterSpec) setParameter}
391: */
392: @Deprecated
393: public final void setParameter(String param, Object value)
394: throws InvalidParameterException {
395: engineSetParameter(param, value);
396: }
397:
398: /**
399: * @com.intel.drl.spec_ref
400: *
401: */
402: public final void setParameter(AlgorithmParameterSpec params)
403: throws InvalidAlgorithmParameterException {
404: engineSetParameter(params);
405: }
406:
407: /**
408: * @com.intel.drl.spec_ref
409: *
410: */
411: public final AlgorithmParameters getParameters() {
412: return engineGetParameters();
413: }
414:
415: /**
416: * @com.intel.drl.spec_ref
417: *
418: * @deprecated There is no generally accepted parameter naming convention.
419: */
420: @Deprecated
421: public final Object getParameter(String param)
422: throws InvalidParameterException {
423: return engineGetParameter(param);
424: }
425:
426: /**
427: * @com.intel.drl.spec_ref
428: *
429: */
430: public Object clone() throws CloneNotSupportedException {
431: if (this instanceof Cloneable) {
432: return super .clone();
433: } else {
434: throw new CloneNotSupportedException();
435: }
436: }
437:
438: /**
439: *
440: * Internal Signature implementation
441: *
442: */
443: private static class SignatureImpl extends Signature {
444:
445: private SignatureSpi spiImpl;
446:
447: // Constructor
448: public SignatureImpl(SignatureSpi signatureSpi,
449: Provider provider, String algorithm) {
450: super (algorithm);
451: super .provider = provider;
452: spiImpl = signatureSpi;
453: }
454:
455: // engineSign() implementation
456: protected byte[] engineSign() throws SignatureException {
457: return spiImpl.engineSign();
458: }
459:
460: // engineUpdate() implementation
461: protected void engineUpdate(byte arg0)
462: throws SignatureException {
463: spiImpl.engineUpdate(arg0);
464: }
465:
466: // engineVerify() implementation
467: protected boolean engineVerify(byte[] arg0)
468: throws SignatureException {
469: return spiImpl.engineVerify(arg0);
470: }
471:
472: // engineUpdate() implementation
473: protected void engineUpdate(byte[] arg0, int arg1, int arg2)
474: throws SignatureException {
475: spiImpl.engineUpdate(arg0, arg1, arg2);
476: }
477:
478: // engineInitSign() implementation
479: protected void engineInitSign(PrivateKey arg0)
480: throws InvalidKeyException {
481: spiImpl.engineInitSign(arg0);
482: }
483:
484: // engineInitVerify() implementation
485: protected void engineInitVerify(PublicKey arg0)
486: throws InvalidKeyException {
487: spiImpl.engineInitVerify(arg0);
488: }
489:
490: // engineGetParameter() implementation
491: protected Object engineGetParameter(String arg0)
492: throws InvalidParameterException {
493: return spiImpl.engineGetParameter(arg0);
494: }
495:
496: // engineSetParameter() implementation
497: protected void engineSetParameter(String arg0, Object arg1)
498: throws InvalidParameterException {
499: spiImpl.engineSetParameter(arg0, arg1);
500: }
501:
502: // Returns a clone if the spiImpl is cloneable
503: public Object clone() throws CloneNotSupportedException {
504: if (spiImpl instanceof Cloneable) {
505: SignatureSpi spi = (SignatureSpi) spiImpl.clone();
506: return new SignatureImpl(spi, getProvider(),
507: getAlgorithm());
508: } else {
509: throw new CloneNotSupportedException();
510: }
511: }
512: }
513: }
|