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