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