001: package org.bouncycastle.jce.provider;
002:
003: import java.math.BigInteger;
004: import java.security.InvalidKeyException;
005: import java.security.PrivateKey;
006: import java.security.PublicKey;
007: import java.security.SecureRandom;
008: import java.security.Signature;
009: import java.security.SignatureException;
010: import java.security.spec.AlgorithmParameterSpec;
011:
012: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
013: import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
014: import org.bouncycastle.crypto.CipherParameters;
015: import org.bouncycastle.crypto.DSA;
016: import org.bouncycastle.crypto.Digest;
017: import org.bouncycastle.crypto.digests.GOST3411Digest;
018: import org.bouncycastle.crypto.params.ParametersWithRandom;
019: import org.bouncycastle.crypto.signers.ECGOST3410Signer;
020: import org.bouncycastle.crypto.signers.GOST3410Signer;
021: import org.bouncycastle.jce.interfaces.ECKey;
022: import org.bouncycastle.jce.interfaces.ECPublicKey;
023: import org.bouncycastle.jce.interfaces.GOST3410Key;
024:
025: public class JDKGOST3410Signer extends Signature implements
026: PKCSObjectIdentifiers, X509ObjectIdentifiers {
027: private Digest digest;
028: private DSA signer;
029: private SecureRandom random;
030:
031: protected JDKGOST3410Signer(String name, Digest digest, DSA signer) {
032: super (name);
033:
034: this .digest = digest;
035: this .signer = signer;
036: }
037:
038: protected void engineInitVerify(PublicKey publicKey)
039: throws InvalidKeyException {
040: CipherParameters param;
041:
042: if (publicKey instanceof ECPublicKey) {
043: param = ECUtil.generatePublicKeyParameter(publicKey);
044: } else if (publicKey instanceof GOST3410Key) {
045: param = GOST3410Util.generatePublicKeyParameter(publicKey);
046: } else {
047: try {
048: byte[] bytes = publicKey.getEncoded();
049:
050: publicKey = JDKKeyFactory
051: .createPublicKeyFromDERStream(bytes);
052:
053: if (publicKey instanceof ECPublicKey) {
054: param = ECUtil
055: .generatePublicKeyParameter(publicKey);
056: } else {
057: throw new InvalidKeyException(
058: "can't recognise key type in DSA based signer");
059: }
060: } catch (Exception e) {
061: throw new InvalidKeyException(
062: "can't recognise key type in DSA based signer");
063: }
064: }
065:
066: digest.reset();
067: signer.init(false, param);
068: }
069:
070: protected void engineInitSign(PrivateKey privateKey,
071: SecureRandom random) throws InvalidKeyException {
072: this .random = random;
073: engineInitSign(privateKey);
074: }
075:
076: protected void engineInitSign(PrivateKey privateKey)
077: throws InvalidKeyException {
078: CipherParameters param;
079:
080: if (privateKey instanceof ECKey) {
081: param = ECUtil.generatePrivateKeyParameter(privateKey);
082: } else {
083: param = GOST3410Util
084: .generatePrivateKeyParameter(privateKey);
085: }
086:
087: digest.reset();
088:
089: if (random != null) {
090: signer.init(true, new ParametersWithRandom(param, random));
091: } else {
092: signer.init(true, param);
093: }
094: }
095:
096: protected void engineUpdate(byte b) throws SignatureException {
097: digest.update(b);
098: }
099:
100: protected void engineUpdate(byte[] b, int off, int len)
101: throws SignatureException {
102: digest.update(b, off, len);
103: }
104:
105: protected byte[] engineSign() throws SignatureException {
106: byte[] hash = new byte[digest.getDigestSize()];
107:
108: digest.doFinal(hash, 0);
109:
110: try {
111: byte[] sigBytes = new byte[64];
112: BigInteger[] sig = signer.generateSignature(hash);
113: byte[] r = sig[0].toByteArray();
114: byte[] s = sig[1].toByteArray();
115:
116: if (s[0] != 0) {
117: System.arraycopy(s, 0, sigBytes, 32 - s.length,
118: s.length);
119: } else {
120: System.arraycopy(s, 1, sigBytes, 32 - (s.length - 1),
121: s.length - 1);
122: }
123:
124: if (r[0] != 0) {
125: System.arraycopy(r, 0, sigBytes, 64 - r.length,
126: r.length);
127: } else {
128: System.arraycopy(r, 1, sigBytes, 64 - (r.length - 1),
129: r.length - 1);
130: }
131:
132: return sigBytes;
133: } catch (Exception e) {
134: throw new SignatureException(e.toString());
135: }
136: }
137:
138: protected boolean engineVerify(byte[] sigBytes)
139: throws SignatureException {
140: byte[] hash = new byte[digest.getDigestSize()];
141:
142: digest.doFinal(hash, 0);
143:
144: BigInteger[] sig;
145:
146: try {
147: byte[] r = new byte[32];
148: byte[] s = new byte[32];
149:
150: System.arraycopy(sigBytes, 0, s, 0, 32);
151:
152: System.arraycopy(sigBytes, 32, r, 0, 32);
153:
154: sig = new BigInteger[2];
155: sig[0] = new BigInteger(1, r);
156: sig[1] = new BigInteger(1, s);
157: } catch (Exception e) {
158: throw new SignatureException(
159: "error decoding signature bytes.");
160: }
161:
162: return signer.verifySignature(hash, sig[0], sig[1]);
163: }
164:
165: protected void engineSetParameter(AlgorithmParameterSpec params) {
166: throw new UnsupportedOperationException(
167: "engineSetParameter unsupported");
168: }
169:
170: /**
171: * @deprecated replaced with <a href = "#engineSetParameter(java.security.spec.AlgorithmParameterSpec)">
172: */
173: protected void engineSetParameter(String param, Object value) {
174: throw new UnsupportedOperationException(
175: "engineSetParameter unsupported");
176: }
177:
178: /**
179: * @deprecated
180: */
181: protected Object engineGetParameter(String param) {
182: throw new UnsupportedOperationException(
183: "engineSetParameter unsupported");
184: }
185:
186: static public class gost3410 extends JDKGOST3410Signer {
187: public gost3410() {
188: super ("GOST3411withGOST3410", new GOST3411Digest(),
189: new GOST3410Signer());
190: }
191: }
192:
193: static public class ecgost3410 extends JDKGOST3410Signer {
194: public ecgost3410() {
195: super ("GOST3411withECGOST3410", new GOST3411Digest(),
196: new ECGOST3410Signer());
197: }
198: }
199: }
|