1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52:
53:
61: public class SRP6TLSClient
62: extends SRP6KeyAgreement
63: {
64:
65: private String I;
66:
67: private byte[] p;
68:
69: private KeyPair userKeyPair;
70:
71:
72:
73: protected void engineInit(final Map attributes) throws KeyAgreementException
74: {
75: rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS);
76: final String md = (String) attributes.get(HASH_FUNCTION);
77: if (md == null || md.trim().length() == 0)
78: throw new KeyAgreementException("missing hash function");
79: srp = SRP.instance(md);
80: I = (String) attributes.get(USER_IDENTITY);
81: if (I == null)
82: throw new KeyAgreementException("missing user identity");
83: p = (byte[]) attributes.get(USER_PASSWORD);
84: if (p == null)
85: throw new KeyAgreementException("missing user password");
86: }
87:
88: protected OutgoingMessage engineProcessMessage(final IncomingMessage in)
89: throws KeyAgreementException
90: {
91: switch (step)
92: {
93: case 0:
94: return sendIdentity(in);
95: case 1:
96: return computeSharedSecret(in);
97: default:
98: throw new IllegalStateException("unexpected state");
99: }
100: }
101:
102: protected void engineReset()
103: {
104: I = null;
105: p = null;
106: userKeyPair = null;
107: super.engineReset();
108: }
109:
110: private OutgoingMessage sendIdentity(final IncomingMessage in)
111: throws KeyAgreementException
112: {
113: final OutgoingMessage result = new OutgoingMessage();
114: result.writeString(I);
115: return result;
116: }
117:
118: protected OutgoingMessage computeSharedSecret(final IncomingMessage in)
119: throws KeyAgreementException
120: {
121: N = in.readMPI();
122: g = in.readMPI();
123: final BigInteger s = in.readMPI();
124: final BigInteger B = in.readMPI();
125:
126: final SRPKeyPairGenerator kpg = new SRPKeyPairGenerator();
127: final Map attributes = new HashMap();
128: if (rnd != null)
129: attributes.put(SRPKeyPairGenerator.SOURCE_OF_RANDOMNESS, rnd);
130: attributes.put(SRPKeyPairGenerator.SHARED_MODULUS, N);
131: attributes.put(SRPKeyPairGenerator.GENERATOR, g);
132: kpg.setup(attributes);
133: userKeyPair = kpg.generate();
134: final BigInteger A = ((SRPPublicKey) userKeyPair.getPublic()).getY();
135: final BigInteger u = uValue(A, B);
136: final BigInteger x;
137: try
138: {
139: x = new BigInteger(1, srp.computeX(Util.trim(s), I, p));
140: }
141: catch (Exception e)
142: {
143: throw new KeyAgreementException("computeSharedSecret()", e);
144: }
145:
146: final BigInteger a = ((SRPPrivateKey) userKeyPair.getPrivate()).getX();
147: final BigInteger S = B.subtract(THREE.multiply(g.modPow(x, N)))
148: .modPow(a.add(u.multiply(x)), N);
149: K = S;
150: final OutgoingMessage result = new OutgoingMessage();
151: result.writeMPI(A);
152: complete = true;
153: return result;
154: }
155: }