001: package org.bouncycastle.jce.provider;
002:
003: import org.bouncycastle.asn1.ASN1EncodableVector;
004: import org.bouncycastle.asn1.ASN1InputStream;
005: import org.bouncycastle.asn1.ASN1Sequence;
006: import org.bouncycastle.asn1.DERInteger;
007: import org.bouncycastle.asn1.DEROutputStream;
008: import org.bouncycastle.asn1.DERSequence;
009: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
010: import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
011: import org.bouncycastle.crypto.CipherParameters;
012: import org.bouncycastle.crypto.DSA;
013: import org.bouncycastle.crypto.Digest;
014: import org.bouncycastle.crypto.digests.RIPEMD160Digest;
015: import org.bouncycastle.crypto.digests.SHA1Digest;
016: import org.bouncycastle.crypto.digests.SHA224Digest;
017: import org.bouncycastle.crypto.digests.SHA256Digest;
018: import org.bouncycastle.crypto.digests.SHA384Digest;
019: import org.bouncycastle.crypto.digests.SHA512Digest;
020: import org.bouncycastle.crypto.params.ParametersWithRandom;
021: import org.bouncycastle.crypto.signers.DSASigner;
022: import org.bouncycastle.crypto.signers.ECDSASigner;
023: import org.bouncycastle.crypto.signers.ECNRSigner;
024: import org.bouncycastle.jce.interfaces.ECKey;
025: import org.bouncycastle.jce.interfaces.ECPublicKey;
026: import org.bouncycastle.jce.interfaces.GOST3410Key;
027:
028: import java.io.ByteArrayOutputStream;
029: import java.io.IOException;
030: import java.math.BigInteger;
031: import java.security.InvalidKeyException;
032: import java.security.PrivateKey;
033: import java.security.PublicKey;
034: import java.security.SecureRandom;
035: import java.security.Signature;
036: import java.security.SignatureException;
037: import java.security.interfaces.DSAKey;
038: import java.security.spec.AlgorithmParameterSpec;
039:
040: public class JDKDSASigner extends Signature implements
041: PKCSObjectIdentifiers, X509ObjectIdentifiers {
042: private Digest digest;
043: private DSA signer;
044: private SecureRandom random;
045:
046: protected JDKDSASigner(String name, Digest digest, DSA signer) {
047: super (name);
048:
049: this .digest = digest;
050: this .signer = signer;
051: }
052:
053: protected void engineInitVerify(PublicKey publicKey)
054: throws InvalidKeyException {
055: CipherParameters param = null;
056:
057: if (publicKey instanceof ECPublicKey) {
058: param = ECUtil.generatePublicKeyParameter(publicKey);
059: } else if (publicKey instanceof GOST3410Key) {
060: param = GOST3410Util.generatePublicKeyParameter(publicKey);
061: } else if (publicKey instanceof DSAKey) {
062: param = DSAUtil.generatePublicKeyParameter(publicKey);
063: } else {
064: try {
065: byte[] bytes = publicKey.getEncoded();
066:
067: publicKey = JDKKeyFactory
068: .createPublicKeyFromDERStream(bytes);
069:
070: if (publicKey instanceof ECPublicKey) {
071: param = ECUtil
072: .generatePublicKeyParameter(publicKey);
073: } else if (publicKey instanceof DSAKey) {
074: param = DSAUtil
075: .generatePublicKeyParameter(publicKey);
076: } else {
077: throw new InvalidKeyException(
078: "can't recognise key type in DSA based signer");
079: }
080: } catch (Exception e) {
081: throw new InvalidKeyException(
082: "can't recognise key type in DSA based signer");
083: }
084: }
085:
086: digest.reset();
087: signer.init(false, param);
088: }
089:
090: protected void engineInitSign(PrivateKey privateKey,
091: SecureRandom random) throws InvalidKeyException {
092: this .random = random;
093: engineInitSign(privateKey);
094: }
095:
096: protected void engineInitSign(PrivateKey privateKey)
097: throws InvalidKeyException {
098: CipherParameters param = null;
099:
100: if (privateKey instanceof ECKey) {
101: param = ECUtil.generatePrivateKeyParameter(privateKey);
102: } else if (privateKey instanceof GOST3410Key) {
103: param = GOST3410Util
104: .generatePrivateKeyParameter(privateKey);
105: } else {
106: param = DSAUtil.generatePrivateKeyParameter(privateKey);
107: }
108:
109: digest.reset();
110:
111: if (random != null) {
112: signer.init(true, new ParametersWithRandom(param, random));
113: } else {
114: signer.init(true, param);
115: }
116: }
117:
118: protected void engineUpdate(byte b) throws SignatureException {
119: digest.update(b);
120: }
121:
122: protected void engineUpdate(byte[] b, int off, int len)
123: throws SignatureException {
124: digest.update(b, off, len);
125: }
126:
127: protected byte[] engineSign() throws SignatureException {
128: byte[] hash = new byte[digest.getDigestSize()];
129:
130: digest.doFinal(hash, 0);
131:
132: try {
133: BigInteger[] sig = signer.generateSignature(hash);
134:
135: return derEncode(sig[0], sig[1]);
136: } catch (Exception e) {
137: throw new SignatureException(e.toString());
138: }
139: }
140:
141: protected boolean engineVerify(byte[] sigBytes)
142: throws SignatureException {
143: byte[] hash = new byte[digest.getDigestSize()];
144:
145: digest.doFinal(hash, 0);
146:
147: BigInteger[] sig;
148:
149: try {
150: sig = derDecode(sigBytes);
151: } catch (Exception e) {
152: throw new SignatureException(
153: "error decoding signature bytes.");
154: }
155:
156: return signer.verifySignature(hash, sig[0], sig[1]);
157: }
158:
159: protected void engineSetParameter(AlgorithmParameterSpec params) {
160: throw new UnsupportedOperationException(
161: "engineSetParameter unsupported");
162: }
163:
164: /**
165: * @deprecated replaced with <a href = "#engineSetParameter(java.security.spec.AlgorithmParameterSpec)">
166: */
167: protected void engineSetParameter(String param, Object value) {
168: throw new UnsupportedOperationException(
169: "engineSetParameter unsupported");
170: }
171:
172: /**
173: * @deprecated
174: */
175: protected Object engineGetParameter(String param) {
176: throw new UnsupportedOperationException(
177: "engineSetParameter unsupported");
178: }
179:
180: private byte[] derEncode(BigInteger r, BigInteger s)
181: throws IOException {
182: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
183: DEROutputStream dOut = new DEROutputStream(bOut);
184: ASN1EncodableVector v = new ASN1EncodableVector();
185:
186: v.add(new DERInteger(r));
187: v.add(new DERInteger(s));
188:
189: dOut.writeObject(new DERSequence(v));
190:
191: return bOut.toByteArray();
192: }
193:
194: private BigInteger[] derDecode(byte[] encoding) throws IOException {
195: ASN1InputStream aIn = new ASN1InputStream(encoding);
196: ASN1Sequence s = (ASN1Sequence) aIn.readObject();
197:
198: BigInteger[] sig = new BigInteger[2];
199:
200: sig[0] = ((DERInteger) s.getObjectAt(0)).getValue();
201: sig[1] = ((DERInteger) s.getObjectAt(1)).getValue();
202:
203: return sig;
204: }
205:
206: static public class stdDSA extends JDKDSASigner {
207: public stdDSA() {
208: super ("SHA1withDSA", new SHA1Digest(), new DSASigner());
209: }
210: }
211:
212: static public class dsa224 extends JDKDSASigner {
213: public dsa224() {
214: super ("SHA224withDSA", new SHA224Digest(), new DSASigner());
215: }
216: }
217:
218: static public class dsa256 extends JDKDSASigner {
219: public dsa256() {
220: super ("SHA256withDSA", new SHA256Digest(), new DSASigner());
221: }
222: }
223:
224: static public class dsa384 extends JDKDSASigner {
225: public dsa384() {
226: super ("SHA384withDSA", new SHA384Digest(), new DSASigner());
227: }
228: }
229:
230: static public class dsa512 extends JDKDSASigner {
231: public dsa512() {
232: super ("SHA512withDSA", new SHA512Digest(), new DSASigner());
233: }
234: }
235:
236: static public class noneDSA extends JDKDSASigner {
237: public noneDSA() {
238: super ("NONEwithDSA", new NullDigest(), new DSASigner());
239: }
240: }
241:
242: static public class ecDSA extends JDKDSASigner {
243: public ecDSA() {
244: super ("SHA1withECDSA", new SHA1Digest(), new ECDSASigner());
245: }
246: }
247:
248: static public class ecDSA224 extends JDKDSASigner {
249: public ecDSA224() {
250: super ("SHA224withECDSA", new SHA224Digest(),
251: new ECDSASigner());
252: }
253: }
254:
255: static public class ecDSA256 extends JDKDSASigner {
256: public ecDSA256() {
257: super ("SHA256withECDSA", new SHA256Digest(),
258: new ECDSASigner());
259: }
260: }
261:
262: static public class ecDSA384 extends JDKDSASigner {
263: public ecDSA384() {
264: super ("SHA384withECDSA", new SHA384Digest(),
265: new ECDSASigner());
266: }
267: }
268:
269: static public class ecDSA512 extends JDKDSASigner {
270: public ecDSA512() {
271: super ("SHA512withECDSA", new SHA512Digest(),
272: new ECDSASigner());
273: }
274: }
275:
276: static public class ecDSARipeMD160 extends JDKDSASigner {
277: public ecDSARipeMD160() {
278: super ("RIPEMD160withECDSA", new RIPEMD160Digest(),
279: new ECDSASigner());
280: }
281: }
282:
283: static public class ecNR extends JDKDSASigner {
284: public ecNR() {
285: super ("SHA1withECNR", new SHA1Digest(), new ECNRSigner());
286: }
287: }
288:
289: static public class ecNR224 extends JDKDSASigner {
290: public ecNR224() {
291: super ("SHA224withECNR", new SHA224Digest(),
292: new ECNRSigner());
293: }
294: }
295:
296: static public class ecNR256 extends JDKDSASigner {
297: public ecNR256() {
298: super ("SHA256withECNR", new SHA256Digest(),
299: new ECNRSigner());
300: }
301: }
302:
303: static public class ecNR384 extends JDKDSASigner {
304: public ecNR384() {
305: super ("SHA384withECNR", new SHA384Digest(),
306: new ECNRSigner());
307: }
308: }
309:
310: static public class ecNR512 extends JDKDSASigner {
311: public ecNR512() {
312: super ("SHA512withECNR", new SHA512Digest(),
313: new ECNRSigner());
314: }
315: }
316:
317: private static class NullDigest implements Digest {
318: private ByteArrayOutputStream bOut = new ByteArrayOutputStream();
319:
320: public String getAlgorithmName() {
321: return "NULL";
322: }
323:
324: public int getDigestSize() {
325: return bOut.size();
326: }
327:
328: public void update(byte in) {
329: bOut.write(in);
330: }
331:
332: public void update(byte[] in, int inOff, int len) {
333: bOut.write(in, inOff, len);
334: }
335:
336: public int doFinal(byte[] out, int outOff) {
337: byte[] res = bOut.toByteArray();
338:
339: System.arraycopy(res, 0, out, outOff, res.length);
340:
341: return res.length;
342: }
343:
344: public void reset() {
345: bOut.reset();
346: }
347: }
348: }
|