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