// // (C) Copyright 2007 VeriSign, Inc. All Rights Reserved. // // VeriSign, Inc. shall have no responsibility, financial or // otherwise, for any consequences arising out of the use of // this material. The program material is provided on an "AS IS" // BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either // express or implied. // // Distributed under an Apache License // http://www.apache.org/licenses/LICENSE-2.0 // package org.verisign.joid; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.Log; /** * Represents an OpenID association response. */ public class AssociationResponse extends Response { private final static Log log = LogFactory.getLog(AssociationResponse.class); // package scope so that ResponseFactory can trigger on this key static String OPENID_SESSION_TYPE = "session_type"; static String OPENID_ASSOCIATION_TYPE = "assoc_type"; private static String OPENID_ASSOC_NS = "ns"; private static String OPENID_ERROR_CODE = "error_code"; private static String OPENID_ASSOCIATION_HANDLE = "assoc_handle"; private static String OPENID_MAC_KEY = "mac_key"; // package scope so that ResponseFactory can trigger on this key static String OPENID_ENC_MAC_KEY = "enc_mac_key"; private static String OPENID_DH_SERVER_PUBLIC = "dh_server_public"; private static String OPENID_EXPIRES_IN = "expires_in"; private String sessionType; private String associationType; private String associationHandle; private int expiresIn; private byte[] macKey; private BigInteger dhServerPublic; private byte[] encryptedMacKey; private String errorCode; /** * Returns the error code (if any) occured while processing this response. * @return the error code; null if none. */ public String getErrorCode(){return errorCode;} /** * Returns the association handle in this response. * @return the association handle in this response. */ public String getAssociationHandle(){return associationHandle;} /** * Returns the Diffie-Hellman public server key in this response. * @return the Diffie-Hellman public server key in this response. */ public BigInteger getDhServerPublic(){return dhServerPublic;} /** * Returns the MAC key in this response. See also * {@link #getEncryptedMacKey()} * @return the MAC key in this response; null if none. */ public byte[] getMacKey(){return macKey;} /** * Returns the encrypted MAC key in this response. See also * {@link #getMacKey()} * @return the encrypted MAC key in this response; null if none. */ public byte[] getEncryptedMacKey(){return encryptedMacKey;} /** * Returns the static number of seconds this association expires in. * @return the number of seconds until expiration. */ public int getExpiresIn(){return expiresIn;} /** * Returns the association type in this response. * @return the association type in this response. */ public String getAssociationType(){return associationType;} /** * Returns the session type in this response. * @return the session type in this response. */ public String getSessionType(){return sessionType;} Map toMap() { Map map = super.toMap(); // remove "openid.ns" from map and replace with just "ns" // openid prefix is invalid for association responses String ns = (String)map.get(Message.OPENID_NS); if (ns != null) { map.put(OPENID_ASSOC_NS, ns); map.remove(Message.OPENID_NS); } if (errorCode != null){ map.put(AssociationResponse.OPENID_ERROR_CODE, errorCode); } else { if (!(!isVersion2() // OpenID 1.x && AssociationRequest.NO_ENCRYPTION.equals(sessionType))) { // do not send session type for 1.1 responses if it is no-encryption map.put(AssociationResponse.OPENID_SESSION_TYPE, sessionType); } map.put(AssociationResponse.OPENID_ASSOCIATION_HANDLE, associationHandle); map.put(AssociationResponse.OPENID_ASSOCIATION_TYPE, associationType); map.put(AssociationResponse.OPENID_EXPIRES_IN, ""+expiresIn); if (macKey != null){ map.put(AssociationResponse.OPENID_MAC_KEY, Crypto.convertToString(macKey)); } else if (encryptedMacKey != null){ map.put(AssociationResponse.OPENID_DH_SERVER_PUBLIC, Crypto.convertToString(dhServerPublic)); map.put(AssociationResponse.OPENID_ENC_MAC_KEY, Crypto.convertToString(encryptedMacKey)); } } return map; } AssociationResponse(AssociationRequest ar, Association a, Crypto crypto) { super(null); this.ns = ar.getNamespace(); if (a.isSuccessful()){ this.sessionType = a.getSessionType(); this.associationHandle = a.getHandle(); this.associationType = a.getAssociationType(); this.expiresIn = a.getLifetime().intValue(); this.dhServerPublic = a.getPublicDhKey(); if (a.isEncrypted()) { this.encryptedMacKey = a.getEncryptedMacKey(); } else { this.macKey = a.getMacKey(); } } else { this.errorCode = a.getErrorCode(); this.error = a.getError(); } } AssociationResponse(Map map) throws OpenIdException { super(map); Set set = map.entrySet(); for (Iterator iter = set.iterator(); iter.hasNext();){ Map.Entry mapEntry = (Map.Entry) iter.next(); String key = (String) mapEntry.getKey(); String value = (String) mapEntry.getValue(); if (AssociationResponse.OPENID_SESSION_TYPE.equals(key)){ sessionType = AssociationRequest.parseSessionType(value); } else if (AssociationResponse .OPENID_ASSOCIATION_TYPE.equals(key)){ associationType = AssociationRequest.parseAssociationType(value); } else if (OPENID_DH_SERVER_PUBLIC.equals(key)){ dhServerPublic = Crypto.convertToBigIntegerFromString(value); } else if (OPENID_ASSOCIATION_HANDLE.equals(key)){ associationHandle = value; } else if (OPENID_EXPIRES_IN.equals(key)){ expiresIn = Integer.parseInt(value); } else if (OPENID_MAC_KEY.equals(key)){ macKey = Crypto.convertToBytes(value); } else if (OPENID_ENC_MAC_KEY.equals(key)){ encryptedMacKey = Crypto.convertToBytes(value); } else if (OPENID_ERROR_CODE.equals(key)){ errorCode = value; } // set namespace using association ns key else if (OPENID_ASSOC_NS.equals(key)) { ns = value; } } } public String toString() { String s = "[AssociationResponse " + super.toString() +", session type="+sessionType +", association type="+associationType +", association handle="+associationHandle +", expires in="+expiresIn; if (dhServerPublic != null) { s += ", server public key="+Crypto.convertToString(dhServerPublic); } if (macKey != null) { s += ", MAC key="+Crypto.convertToString(macKey); } if (encryptedMacKey != null) { s += ", encrypted MAC key=" +Crypto.convertToString(encryptedMacKey); } if (errorCode != null) { s += ", error code="+errorCode; } s+="]"; return s; } }