001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.util;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
020    import com.liferay.portal.kernel.util.Base64;
021    import com.liferay.portal.kernel.util.Digester;
022    import com.liferay.portal.kernel.util.StreamUtil;
023    import com.liferay.portal.kernel.util.StringBundler;
024    import com.liferay.portal.kernel.util.StringPool;
025    
026    import java.io.IOException;
027    import java.io.InputStream;
028    import java.io.UnsupportedEncodingException;
029    
030    import java.nio.ByteBuffer;
031    
032    import java.security.MessageDigest;
033    import java.security.NoSuchAlgorithmException;
034    
035    import org.apache.commons.codec.binary.Hex;
036    
037    /**
038     * @author Brian Wing Shun Chan
039     * @author Alexander Chow
040     * @author Connor McKay
041     */
042    @DoPrivileged
043    public class DigesterImpl implements Digester {
044    
045            @Override
046            public String digest(ByteBuffer byteBuffer) {
047                    return digest(Digester.DEFAULT_ALGORITHM, byteBuffer);
048            }
049    
050            @Override
051            public String digest(InputStream inputStream) {
052                    return digest(Digester.DEFAULT_ALGORITHM, inputStream);
053            }
054    
055            @Override
056            public String digest(String text) {
057                    return digest(Digester.DEFAULT_ALGORITHM, text);
058            }
059    
060            @Override
061            public String digest(String algorithm, ByteBuffer byteBuffer) {
062                    if (_BASE_64) {
063                            return digestBase64(algorithm, byteBuffer);
064                    }
065                    else {
066                            return digestHex(algorithm, byteBuffer);
067                    }
068            }
069    
070            @Override
071            public String digest(String algorithm, InputStream inputStream) {
072                    if (_BASE_64) {
073                            return digestBase64(algorithm, inputStream);
074                    }
075                    else {
076                            return digestHex(algorithm, inputStream);
077                    }
078            }
079    
080            @Override
081            public String digest(String algorithm, String... text) {
082                    if (_BASE_64) {
083                            return digestBase64(algorithm, text);
084                    }
085                    else {
086                            return digestHex(algorithm, text);
087                    }
088            }
089    
090            @Override
091            public String digestBase64(ByteBuffer byteBuffer) {
092                    return digestBase64(Digester.DEFAULT_ALGORITHM, byteBuffer);
093            }
094    
095            @Override
096            public String digestBase64(InputStream inputStream) {
097                    return digestBase64(Digester.DEFAULT_ALGORITHM, inputStream);
098            }
099    
100            @Override
101            public String digestBase64(String text) {
102                    return digestBase64(Digester.DEFAULT_ALGORITHM, text);
103            }
104    
105            @Override
106            public String digestBase64(String algorithm, ByteBuffer byteBuffer) {
107                    byte[] bytes = digestRaw(algorithm, byteBuffer);
108    
109                    return Base64.encode(bytes);
110            }
111    
112            @Override
113            public String digestBase64(String algorithm, InputStream inputStream) {
114                    byte[] bytes = digestRaw(algorithm, inputStream);
115    
116                    return Base64.encode(bytes);
117            }
118    
119            @Override
120            public String digestBase64(String algorithm, String... text) {
121                    byte[] bytes = digestRaw(algorithm, text);
122    
123                    return Base64.encode(bytes);
124            }
125    
126            @Override
127            public String digestHex(ByteBuffer byteBuffer) {
128                    return digestHex(Digester.DEFAULT_ALGORITHM, byteBuffer);
129            }
130    
131            @Override
132            public String digestHex(InputStream inputStream) {
133                    return digestHex(Digester.DEFAULT_ALGORITHM, inputStream);
134            }
135    
136            @Override
137            public String digestHex(String text) {
138                    return digestHex(Digester.DEFAULT_ALGORITHM, text);
139            }
140    
141            @Override
142            public String digestHex(String algorithm, ByteBuffer byteBuffer) {
143                    byte[] bytes = digestRaw(algorithm, byteBuffer);
144    
145                    return Hex.encodeHexString(bytes);
146            }
147    
148            @Override
149            public String digestHex(String algorithm, InputStream inputStream) {
150                    byte[] bytes = digestRaw(algorithm, inputStream);
151    
152                    return Hex.encodeHexString(bytes);
153            }
154    
155            @Override
156            public String digestHex(String algorithm, String... text) {
157                    byte[] bytes = digestRaw(algorithm, text);
158    
159                    return Hex.encodeHexString(bytes);
160            }
161    
162            @Override
163            public byte[] digestRaw(ByteBuffer byteBuffer) {
164                    return digestRaw(Digester.DEFAULT_ALGORITHM, byteBuffer);
165            }
166    
167            @Override
168            public byte[] digestRaw(String text) {
169                    return digestRaw(Digester.DEFAULT_ALGORITHM, text);
170            }
171    
172            @Override
173            public byte[] digestRaw(String algorithm, ByteBuffer byteBuffer) {
174                    MessageDigest messageDigest = null;
175    
176                    try {
177                            messageDigest = MessageDigest.getInstance(algorithm);
178    
179                            messageDigest.update(byteBuffer);
180                    }
181                    catch (NoSuchAlgorithmException nsae) {
182                            _log.error(nsae, nsae);
183                    }
184    
185                    return messageDigest.digest();
186            }
187    
188            @Override
189            public byte[] digestRaw(String algorithm, InputStream inputStream) {
190                    MessageDigest messageDigest = null;
191    
192                    try {
193                            messageDigest = MessageDigest.getInstance(algorithm);
194    
195                            byte[] buffer = new byte[StreamUtil.BUFFER_SIZE];
196    
197                            int read = 0;
198    
199                            while ((read = inputStream.read(buffer)) != -1) {
200                                    if (read > 0) {
201                                            messageDigest.update(buffer, 0, read);
202                                    }
203                            }
204                    }
205                    catch (IOException ioe) {
206                            _log.error(ioe, ioe);
207                    }
208                    catch (NoSuchAlgorithmException nsae) {
209                            _log.error(nsae, nsae);
210                    }
211                    finally {
212                            StreamUtil.cleanUp(inputStream);
213                    }
214    
215                    return messageDigest.digest();
216            }
217    
218            @Override
219            public byte[] digestRaw(String algorithm, String... text) {
220                    MessageDigest messageDigest = null;
221    
222                    try {
223                            messageDigest = MessageDigest.getInstance(algorithm);
224    
225                            StringBundler sb = new StringBundler(text.length * 2 - 1);
226    
227                            for (String t : text) {
228                                    if (sb.length() > 0) {
229                                            sb.append(StringPool.COLON);
230                                    }
231    
232                                    sb.append(t);
233                            }
234    
235                            String s = sb.toString();
236    
237                            messageDigest.update(s.getBytes(Digester.ENCODING));
238                    }
239                    catch (NoSuchAlgorithmException nsae) {
240                            _log.error(nsae, nsae);
241                    }
242                    catch (UnsupportedEncodingException uee) {
243                            _log.error(uee, uee);
244                    }
245    
246                    return messageDigest.digest();
247            }
248    
249            private static final boolean _BASE_64 =
250                    PropsValues.PASSWORDS_DIGEST_ENCODING.equals("base64");
251    
252            private static Log _log = LogFactoryUtil.getLog(DigesterImpl.class);
253    
254    }