1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44:
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57:
58:
64: public class SSLRSASignatureImpl extends SignatureSpi
65: {
66: private static final SystemLogger logger = SystemLogger.SYSTEM;
67: private RSAPublicKey pubkey;
68: private RSAPrivateKey privkey;
69: private final MessageDigest md5, sha;
70: private boolean initSign = false;
71: private boolean initVerify = false;
72:
73: public SSLRSASignatureImpl() throws NoSuchAlgorithmException
74: {
75: md5 = MessageDigest.getInstance("MD5");
76: sha = MessageDigest.getInstance("SHA-1");
77: }
78:
79:
82: @Override protected void engineInitVerify(PublicKey publicKey)
83: throws InvalidKeyException
84: {
85: try
86: {
87: pubkey = (RSAPublicKey) publicKey;
88: initVerify = true;
89: initSign = false;
90: privkey = null;
91: }
92: catch (ClassCastException cce)
93: {
94: throw new InvalidKeyException(cce);
95: }
96: }
97:
98:
101: @Override protected void engineInitSign(PrivateKey privateKey)
102: throws InvalidKeyException
103: {
104: try
105: {
106: privkey = (RSAPrivateKey) privateKey;
107: initSign = true;
108: initVerify = false;
109: pubkey = null;
110: }
111: catch (ClassCastException cce)
112: {
113: throw new InvalidKeyException(cce);
114: }
115: }
116:
117:
120: @Override protected void engineUpdate(byte b) throws SignatureException
121: {
122: if (!initSign && !initVerify)
123: throw new IllegalStateException("not initialized");
124: if (Debug.DEBUG)
125: logger.log(Component.SSL_HANDSHAKE, "SSL/RSA update 0x{0}",
126: Util.formatInt(b & 0xFF, 16, 2));
127: md5.update(b);
128: sha.update(b);
129: }
130:
131:
134: @Override protected void engineUpdate(byte[] b, int off, int len)
135: throws SignatureException
136: {
137: if (!initSign && !initVerify)
138: throw new IllegalStateException("not initialized");
139: if (Debug.DEBUG)
140: logger.log(Component.SSL_HANDSHAKE, "SSL/RSA update\n{0}",
141: Util.hexDump(b, off, len, ">> "));
142: md5.update(b, off, len);
143: sha.update(b, off, len);
144: }
145:
146:
149: @Override protected byte[] engineSign() throws SignatureException
150: {
151:
152:
153: if (!initSign)
154: throw new SignatureException("not initialized for signing");
155:
156: final int k = (privkey.getModulus().bitLength() + 7) >>> 3;
157: final byte[] d = Util.concat(md5.digest(), sha.digest());
158: if (k - 11 < d.length)
159: throw new SignatureException("message too long");
160: final byte[] eb = new byte[k];
161: eb[0] = 0x00;
162: eb[1] = 0x01;
163: for (int i = 2; i < k - d.length - 1; i++)
164: eb[i] = (byte) 0xFF;
165: System.arraycopy(d, 0, eb, k - d.length, d.length);
166: BigInteger EB = new BigInteger(eb);
167:
168:
169: BigInteger EM = RSA.sign(privkey, EB);
170: return Util.trim(EM);
171: }
172:
173:
176: @Override protected boolean engineVerify(byte[] sigBytes)
177: throws SignatureException
178: {
179: if (!initVerify)
180: throw new SignatureException("not initialized for verifying");
181:
182:
183: BigInteger EM = new BigInteger(1, (byte[]) sigBytes);
184: BigInteger EB = RSA.verify(pubkey, EM);
185:
186:
187: int i = 0;
188: final byte[] eb = EB.toByteArray();
189: if (eb[0] == 0x00)
190: {
191: for (i = 0; i < eb.length && eb[i] == 0x00; i++)
192: ;
193: }
194: else if (eb[0] == 0x01)
195: {
196: for (i = 1; i < eb.length && eb[i] != 0x00; i++)
197: {
198: if (eb[i] != (byte) 0xFF)
199: {
200: throw new SignatureException("bad padding");
201: }
202: }
203: i++;
204: }
205: else
206: {
207: throw new SignatureException("decryption failed");
208: }
209: byte[] d1 = Util.trim(eb, i, eb.length - i);
210: byte[] d2 = Util.concat(md5.digest(), sha.digest());
211: if (Debug.DEBUG)
212: logger.logv(Component.SSL_HANDSHAKE, "SSL/RSA d1:{0} d2:{1}",
213: Util.toHexString(d1, ':'), Util.toHexString(d2, ':'));
214: return Arrays.equals(d1, d2);
215: }
216:
217:
220: @Override protected void engineSetParameter(String param, Object value)
221: throws InvalidParameterException
222: {
223: throw new InvalidParameterException("parameters not supported");
224: }
225:
226:
229: @Override protected Object engineGetParameter(String param)
230: throws InvalidParameterException
231: {
232: throw new InvalidParameterException("parameters not supported");
233: }
234: }