/** * To associate with an openid server * * @param idserver server url * @return * @throws java.io.IOException * @throws org.verisign.joid.OpenIdException */ public Properties associate(String idserver) throws IOException, OpenIdException { DiffieHellman dh = DiffieHellman.getDefault(); Crypto crypto = new Crypto(); crypto.setDiffieHellman(dh); AssociationRequest ar = AssociationRequest.create(crypto); log.info("[JoidConsumer] Attempting to associate with: " + idserver); log.info("Request=" + ar); Response response = MessageFactory.send(ar, idserver); log.info("Response=" + response + "\n"); AssociationResponse asr = (AssociationResponse) response; Properties props = new Properties(); props.setProperty("idServer", idserver); props.setProperty("handle", asr.getAssociationHandle()); props.setProperty("publicKey", Crypto.convertToString(asr.getDhServerPublic())); props.setProperty("encryptedKey", Crypto.convertToString(asr.getEncryptedMacKey())); BigInteger privateKey = dh.getPrivateKey(); props.setProperty("privateKey", Crypto.convertToString(privateKey)); props.setProperty("modulus", Crypto.convertToString(DiffieHellman.DEFAULT_MODULUS)); props.setProperty("_dest", idserver); props.setProperty("expiresIn", "" + asr.getExpiresIn()); /* Crypto crypto = new Crypto(); dh = DiffieHellman.recreate(privateKey, p); crypto.setDiffieHellman(dh); byte[] clearKey = crypto.decryptSecret(asr.getDhServerPublic(), asr.getEncryptedMacKey()); System.out.println("Clear key: "+Crypto.convertToString(clearKey)); */ return props; }
/** * This method will attempt to authenticate against the OpenID server. * * @param map * @return openid.identity if authentication was successful, null if unsuccessful * @throws IOException * @throws OpenIdException * @throws NoSuchAlgorithmException */ public AuthenticationResult authenticate(Map<String, String> map) throws IOException, OpenIdException, NoSuchAlgorithmException { debug("request map in authenticate: " + map); AuthenticationResponse response = new AuthenticationResponse(map); // TODO: store nonce's to ensure we never accept the same value again - see sec 11.3 of spec 2.0 Properties props; if (response.getInvalidateHandle() != null) { // then we have to send a authentication_request (dumb mode) to verify the signature CheckAuthenticationRequest checkReq = new CheckAuthenticationRequest( response.toMap(), MessageFactory.CHECK_AUTHENTICATION_MODE); props = getPropsByHandle(response.getInvalidateHandle()); CheckAuthenticationResponse response2 = (CheckAuthenticationResponse) MessageFactory.send(checkReq, props.getProperty("idServer")); // This doesn't actually work, because for a check authentication response, the only // field returned is openid.is_valid! /*if (! response.getInvalidateHandle().equals(response2.getInvalidateHandle())) { throw new AuthenticationException("The invalidate_handles do not match, identity denied: " + response.getInvalidateHandle() + " != " + response2.getInvalidateHandle()); }*/ removeInvalidHandle(response.getInvalidateHandle()); if (response2.isValid()) { // then this is a valid request, lets send it back return new AuthenticationResult(response.getIdentity(), response); } else { throw new AuthenticationException("Signature invalid, identity denied."); } } else { // normal properties props = getPropsByHandle(response.getAssociationHandle()); // TODO: before returning a valid response, ensure return_to is a suburl of trust_root BigInteger privKey = Crypto.convertToBigIntegerFromString(props.getProperty("privateKey")); BigInteger modulus = Crypto.convertToBigIntegerFromString(props.getProperty("modulus")); BigInteger serverPublic = Crypto.convertToBigIntegerFromString(props.getProperty("publicKey")); byte[] encryptedKey = Crypto.convertToBytes(props.getProperty("encryptedKey")); /* String sig = response.sign(response.getAssociationType(), a.getMacKey(), response.getSignedList()); isValid = sig.equals(response.getSignature()); */ DiffieHellman dh = DiffieHellman.recreate(privKey, modulus); Crypto crypto = new Crypto(); crypto.setDiffieHellman(dh); byte[] clearKey = crypto.decryptSecret(serverPublic, encryptedKey); String signature = response.getSignature(); debug("Server's signature: " + signature); String sigList = response.getSignedList(); String reSigned = response.sign(clearKey, sigList); debug("Our signature: " + reSigned); String identity = response.getIdentity(); if (!signature.equals(reSigned)) { throw new AuthenticationException( "OpenID signatures do not match! " + "claimed identity: " + identity); } debug("Signatures match, identity is ok: " + identity); return new AuthenticationResult(identity, response); } }