001: package org.bouncycastle.jce.provider;
002:
003: import org.bouncycastle.asn1.ASN1Encodable;
004: import org.bouncycastle.asn1.DERObjectIdentifier;
005: import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
006: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
007: import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
008: import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
009: import org.bouncycastle.asn1.x509.DigestInfo;
010: import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
011: import org.bouncycastle.crypto.AsymmetricBlockCipher;
012: import org.bouncycastle.crypto.CipherParameters;
013: import org.bouncycastle.crypto.Digest;
014: import org.bouncycastle.crypto.digests.MD2Digest;
015: import org.bouncycastle.crypto.digests.MD4Digest;
016: import org.bouncycastle.crypto.digests.MD5Digest;
017: import org.bouncycastle.crypto.digests.RIPEMD128Digest;
018: import org.bouncycastle.crypto.digests.RIPEMD160Digest;
019: import org.bouncycastle.crypto.digests.RIPEMD256Digest;
020: import org.bouncycastle.crypto.digests.SHA1Digest;
021: import org.bouncycastle.crypto.digests.SHA224Digest;
022: import org.bouncycastle.crypto.digests.SHA256Digest;
023: import org.bouncycastle.crypto.digests.SHA384Digest;
024: import org.bouncycastle.crypto.digests.SHA512Digest;
025: import org.bouncycastle.crypto.encodings.PKCS1Encoding;
026: import org.bouncycastle.crypto.engines.RSABlindedEngine;
027:
028: import java.io.IOException;
029: import java.security.InvalidKeyException;
030: import java.security.PrivateKey;
031: import java.security.PublicKey;
032: import java.security.Signature;
033: import java.security.SignatureException;
034: import java.security.interfaces.RSAPrivateKey;
035: import java.security.interfaces.RSAPublicKey;
036: import java.security.spec.AlgorithmParameterSpec;
037:
038: public class JDKDigestSignature extends Signature implements
039: PKCSObjectIdentifiers, X509ObjectIdentifiers {
040: private Digest digest;
041: private AsymmetricBlockCipher cipher;
042: private AlgorithmIdentifier algId;
043:
044: protected JDKDigestSignature(String name,
045: DERObjectIdentifier objId, Digest digest,
046: AsymmetricBlockCipher cipher) {
047: super (name);
048:
049: this .digest = digest;
050: this .cipher = cipher;
051: this .algId = new AlgorithmIdentifier(objId, null);
052: }
053:
054: protected void engineInitVerify(PublicKey publicKey)
055: throws InvalidKeyException {
056: if (!(publicKey instanceof RSAPublicKey)) {
057: throw new InvalidKeyException("Supplied key ("
058: + getType(publicKey)
059: + ") is not a RSAPublicKey instance");
060: }
061:
062: CipherParameters param = RSAUtil
063: .generatePublicKeyParameter((RSAPublicKey) publicKey);
064:
065: digest.reset();
066: cipher.init(false, param);
067: }
068:
069: protected void engineInitSign(PrivateKey privateKey)
070: throws InvalidKeyException {
071: if (!(privateKey instanceof RSAPrivateKey)) {
072: throw new InvalidKeyException("Supplied key ("
073: + getType(privateKey)
074: + ") is not a RSAPrivateKey instance");
075: }
076:
077: CipherParameters param = RSAUtil
078: .generatePrivateKeyParameter((RSAPrivateKey) privateKey);
079:
080: digest.reset();
081:
082: cipher.init(true, param);
083: }
084:
085: private String getType(Object o) {
086: if (o == null) {
087: return null;
088: }
089:
090: return o.getClass().getName();
091: }
092:
093: protected void engineUpdate(byte b) throws SignatureException {
094: digest.update(b);
095: }
096:
097: protected void engineUpdate(byte[] b, int off, int len)
098: throws SignatureException {
099: digest.update(b, off, len);
100: }
101:
102: protected byte[] engineSign() throws SignatureException {
103: byte[] hash = new byte[digest.getDigestSize()];
104:
105: digest.doFinal(hash, 0);
106:
107: try {
108: byte[] bytes = derEncode(hash);
109:
110: return cipher.processBlock(bytes, 0, bytes.length);
111: } catch (ArrayIndexOutOfBoundsException e) {
112: throw new SignatureException(
113: "key too small for signature type");
114: } catch (Exception e) {
115: throw new SignatureException(e.toString());
116: }
117: }
118:
119: protected boolean engineVerify(byte[] sigBytes)
120: throws SignatureException {
121: byte[] hash = new byte[digest.getDigestSize()];
122:
123: digest.doFinal(hash, 0);
124:
125: byte[] sig;
126: byte[] expected;
127:
128: try {
129: sig = cipher.processBlock(sigBytes, 0, sigBytes.length);
130:
131: expected = derEncode(hash);
132: } catch (Exception e) {
133: return false;
134: }
135:
136: if (sig.length == expected.length) {
137: for (int i = 0; i < sig.length; i++) {
138: if (sig[i] != expected[i]) {
139: return false;
140: }
141: }
142: } else if (sig.length == expected.length - 2) // NULL left out
143: {
144: int sigOffset = sig.length - hash.length - 2;
145: int expectedOffset = expected.length - hash.length - 2;
146:
147: expected[1] -= 2; // adjust lengths
148: expected[3] -= 2;
149:
150: for (int i = 0; i < hash.length; i++) {
151: if (sig[sigOffset + i] != expected[expectedOffset + i]) // check hash
152: {
153: return false;
154: }
155: }
156:
157: for (int i = 0; i < sigOffset; i++) {
158: if (sig[i] != expected[i]) // check header less NULL
159: {
160: return false;
161: }
162: }
163: } else {
164: return false;
165: }
166:
167: return true;
168: }
169:
170: protected void engineSetParameter(AlgorithmParameterSpec params) {
171: throw new UnsupportedOperationException(
172: "engineSetParameter unsupported");
173: }
174:
175: /**
176: * @deprecated replaced with <a href = "#engineSetParameter(java.security.spec.AlgorithmParameterSpec)">
177: */
178: protected void engineSetParameter(String param, Object value) {
179: throw new UnsupportedOperationException(
180: "engineSetParameter unsupported");
181: }
182:
183: /**
184: * @deprecated
185: */
186: protected Object engineGetParameter(String param) {
187: throw new UnsupportedOperationException(
188: "engineSetParameter unsupported");
189: }
190:
191: private byte[] derEncode(byte[] hash) throws IOException {
192: DigestInfo dInfo = new DigestInfo(algId, hash);
193:
194: return dInfo.getEncoded(ASN1Encodable.DER);
195: }
196:
197: static public class SHA1WithRSAEncryption extends
198: JDKDigestSignature {
199: public SHA1WithRSAEncryption() {
200: super ("SHA1withRSA", id_SHA1, new SHA1Digest(),
201: new PKCS1Encoding(new RSABlindedEngine()));
202: }
203: }
204:
205: static public class SHA224WithRSAEncryption extends
206: JDKDigestSignature {
207: public SHA224WithRSAEncryption() {
208: super ("SHA224withRSA", NISTObjectIdentifiers.id_sha224,
209: new SHA224Digest(), new PKCS1Encoding(
210: new RSABlindedEngine()));
211: }
212: }
213:
214: static public class SHA256WithRSAEncryption extends
215: JDKDigestSignature {
216: public SHA256WithRSAEncryption() {
217: super ("SHA256withRSA", NISTObjectIdentifiers.id_sha256,
218: new SHA256Digest(), new PKCS1Encoding(
219: new RSABlindedEngine()));
220: }
221: }
222:
223: static public class SHA384WithRSAEncryption extends
224: JDKDigestSignature {
225: public SHA384WithRSAEncryption() {
226: super ("SHA384withRSA", NISTObjectIdentifiers.id_sha384,
227: new SHA384Digest(), new PKCS1Encoding(
228: new RSABlindedEngine()));
229: }
230: }
231:
232: static public class SHA512WithRSAEncryption extends
233: JDKDigestSignature {
234: public SHA512WithRSAEncryption() {
235: super ("SHA512withRSA", NISTObjectIdentifiers.id_sha512,
236: new SHA512Digest(), new PKCS1Encoding(
237: new RSABlindedEngine()));
238: }
239: }
240:
241: static public class MD2WithRSAEncryption extends JDKDigestSignature {
242: public MD2WithRSAEncryption() {
243: super ("MD2withRSA", md2, new MD2Digest(),
244: new PKCS1Encoding(new RSABlindedEngine()));
245: }
246: }
247:
248: static public class MD4WithRSAEncryption extends JDKDigestSignature {
249: public MD4WithRSAEncryption() {
250: super ("MD4withRSA", md4, new MD4Digest(),
251: new PKCS1Encoding(new RSABlindedEngine()));
252: }
253: }
254:
255: static public class MD5WithRSAEncryption extends JDKDigestSignature {
256: public MD5WithRSAEncryption() {
257: super ("MD5withRSA", md5, new MD5Digest(),
258: new PKCS1Encoding(new RSABlindedEngine()));
259: }
260: }
261:
262: static public class RIPEMD160WithRSAEncryption extends
263: JDKDigestSignature {
264: public RIPEMD160WithRSAEncryption() {
265: super ("RIPEMD160withRSA",
266: TeleTrusTObjectIdentifiers.ripemd160,
267: new RIPEMD160Digest(), new PKCS1Encoding(
268: new RSABlindedEngine()));
269: }
270: }
271:
272: static public class RIPEMD128WithRSAEncryption extends
273: JDKDigestSignature {
274: public RIPEMD128WithRSAEncryption() {
275: super ("RIPEMD128withRSA",
276: TeleTrusTObjectIdentifiers.ripemd128,
277: new RIPEMD128Digest(), new PKCS1Encoding(
278: new RSABlindedEngine()));
279: }
280: }
281:
282: static public class RIPEMD256WithRSAEncryption extends
283: JDKDigestSignature {
284: public RIPEMD256WithRSAEncryption() {
285: super ("RIPEMD256withRSA",
286: TeleTrusTObjectIdentifiers.ripemd256,
287: new RIPEMD256Digest(), new PKCS1Encoding(
288: new RSABlindedEngine()));
289: }
290: }
291: }
|