1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45:
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64:
65: public class DSASignature extends SignatureSpi
66: {
67: private DSAPublicKey publicKey;
68: private DSAPrivateKey privateKey;
69: private final MessageDigest digest;
70: private final SecureRandom random;
71:
72: public DSASignature() throws NoSuchAlgorithmException
73: {
74: random = new SecureRandom();
75: digest = MessageDigest.getInstance ("SHA1");
76: }
77:
78: private void init()
79: {
80: digest.reset();
81: }
82:
83: public void engineInitVerify (PublicKey publicKey)
84: throws InvalidKeyException
85: {
86: if (publicKey instanceof DSAPublicKey)
87: this.publicKey = (DSAPublicKey) publicKey;
88: else
89: throw new InvalidKeyException();
90: init();
91: }
92:
93: public void engineInitSign (PrivateKey privateKey)
94: throws InvalidKeyException
95: {
96: if (privateKey instanceof DSAPrivateKey)
97: this.privateKey = (DSAPrivateKey) privateKey;
98: else
99: throw new InvalidKeyException ("not a DSA private key");
100:
101: init();
102: }
103:
104: public void engineInitSign (PrivateKey privateKey,
105: SecureRandom random)
106: throws InvalidKeyException
107: {
108: if (privateKey instanceof DSAPrivateKey)
109: this.privateKey = (DSAPrivateKey) privateKey;
110: else
111: throw new InvalidKeyException ("not a DSA private key");
112:
113: appRandom = random;
114: init();
115: }
116:
117: public void engineUpdate(byte b)
118: throws SignatureException
119: {
120: digest.update (b);
121: }
122:
123: public void engineUpdate (byte[] b, int off, int len)
124: throws SignatureException
125: {
126: digest.update (b, off, len);
127: }
128:
129: public byte[] engineSign() throws SignatureException
130: {
131: if (privateKey == null)
132: throw new SignatureException ("not initialized for signing");
133:
134: try
135: {
136: BigInteger g = privateKey.getParams().getG();
137: BigInteger p = privateKey.getParams().getP();
138: BigInteger q = privateKey.getParams().getQ();
139:
140: BigInteger x = privateKey.getX();
141:
142: BigInteger k = new BigInteger (159, appRandom != null ? appRandom : random);
143:
144: BigInteger r = g.modPow(k, p);
145: r = r.mod(q);
146:
147: byte bytes[] = digest.digest();
148: BigInteger sha = new BigInteger (1, bytes);
149:
150: BigInteger s = sha.add (x.multiply (r));
151: s = s.multiply (k.modInverse(q)).mod (q);
152:
153: ByteArrayOutputStream bout = new ByteArrayOutputStream();
154: ArrayList seq = new ArrayList (2);
155: seq.add(0, new DERValue (DER.INTEGER, r));
156: seq.add(1, new DERValue (DER.INTEGER, s));
157: DERWriter.write (bout, new DERValue (DER.CONSTRUCTED | DER.SEQUENCE, seq));
158: return bout.toByteArray();
159: }
160: catch (IOException ioe)
161: {
162: SignatureException se = new SignatureException();
163: se.initCause (ioe);
164: throw se;
165: }
166: catch (ArithmeticException ae)
167: {
168: SignatureException se = new SignatureException();
169: se.initCause (ae);
170: throw se;
171: }
172: }
173:
174: public int engineSign (byte[] outbuf, int offset, int len)
175: throws SignatureException
176: {
177: byte tmp[] = engineSign();
178: if (tmp.length > len)
179: throw new SignatureException ("output buffer too short");
180: System.arraycopy (tmp, 0, outbuf, offset, tmp.length);
181: return tmp.length;
182: }
183:
184: public boolean engineVerify (byte[] sigBytes)
185: throws SignatureException
186: {
187:
188: try
189: {
190: DERReader in = new DERReader (sigBytes);
191: DERValue val = in.read();
192: if (!val.isConstructed())
193: throw new SignatureException ("badly formed signature");
194: BigInteger r = (BigInteger) in.read().getValue();
195: BigInteger s = (BigInteger) in.read().getValue();
196:
197: BigInteger g = publicKey.getParams().getG();
198: BigInteger p = publicKey.getParams().getP();
199: BigInteger q = publicKey.getParams().getQ();
200:
201: BigInteger y = publicKey.getY();
202:
203: BigInteger w = s.modInverse (q);
204:
205: byte bytes[] = digest.digest();
206: BigInteger sha = new BigInteger (1, bytes);
207:
208: BigInteger u1 = w.multiply (sha).mod ( q );
209:
210: BigInteger u2 = r.multiply (w).mod(q);
211:
212: BigInteger v = g.modPow (u1, p).multiply (y.modPow (u2, p)).mod (p).mod (q);
213:
214: if (v.equals (r))
215: return true;
216: else
217: return false;
218: }
219: catch (IOException ioe)
220: {
221: SignatureException se = new SignatureException ("badly formed signature");
222: se.initCause (ioe);
223: throw se;
224: }
225: }
226:
227: public void engineSetParameter (String param,
228: Object value)
229: throws InvalidParameterException
230: {
231: throw new InvalidParameterException();
232: }
233:
234: public void engineSetParameter (AlgorithmParameterSpec params)
235: throws InvalidAlgorithmParameterException
236: {
237: throw new InvalidParameterException();
238:
239: }
240:
241: public Object engineGetParameter (String param)
242: throws InvalidParameterException
243: {
244: throw new InvalidParameterException();
245: }
246:
247: public Object clone() throws CloneNotSupportedException
248: {
249: return super.clone();
250: }
251: }