001    package railo.runtime.functions.displayFormatting;
002    
003    import java.nio.charset.Charset;
004    
005    import javax.crypto.Mac;
006    import javax.crypto.SecretKey;
007    import javax.crypto.spec.SecretKeySpec;
008    
009    import railo.commons.digest.MD5;
010    import railo.commons.io.CharsetUtil;
011    import railo.commons.lang.StringUtil;
012    import railo.runtime.PageContext;
013    import railo.runtime.exp.PageException;
014    import railo.runtime.ext.function.Function;
015    import railo.runtime.op.Caster;
016    import railo.runtime.op.Decision;
017    
018    public class HMAC implements Function {
019    
020            private static final long serialVersionUID = -1999122154087043893L;
021    
022            public static String call(PageContext pc,Object oMessage, Object oKey) throws PageException {
023                    return call(pc, oMessage, oKey, null, null);
024            }
025            
026            public static String call(PageContext pc,Object oMessage, Object oKey, String algorithm) throws PageException {
027                    return call(pc, oMessage, oKey, algorithm, null);
028            }
029            
030            public static String call(PageContext pc,Object oMessage, Object oKey, String algorithm, String charset) throws PageException {
031                    // charset
032            if(StringUtil.isEmpty(charset,true))
033                charset=pc.getConfig().getWebCharset();
034                    Charset cs = CharsetUtil.toCharset(charset);
035    
036            // message
037                    byte[] msg=toBinary(oMessage,cs);
038                    
039            // message
040                    byte[] key=toBinary(oKey,cs);
041                    
042                    // algorithm
043            if(StringUtil.isEmpty(algorithm,true)) algorithm = "HmacMD5";
044            
045            SecretKey sk = new SecretKeySpec(key, algorithm);
046                try {
047                Mac mac = Mac.getInstance(algorithm);
048                mac.init(sk);
049                mac.reset();
050                mac.update(msg);
051                msg = mac.doFinal();
052                return MD5.stringify(msg).toUpperCase();
053            }
054            catch(Exception e) {
055                throw Caster.toPageException(e);
056            }
057            }
058            
059            private static byte[] toBinary(Object obj, Charset cs) throws PageException {
060                    if(Decision.isBinary(obj)){
061                            return Caster.toBinary(obj);
062                    }
063                    return Caster.toString(obj).getBytes(cs);
064            }
065    }