001/*
002 * Syncany, www.syncany.org
003 * Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com>
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package org.syncany.crypto;
019
020import java.util.Arrays;
021
022import javax.crypto.SecretKey;
023
024import org.syncany.util.StringUtil;
025
026/**
027 * A salted secret key is a convenience class to bundle a {@link SecretKey} with
028 * its corresponding salt. It is mainly used to represent the master key and the
029 * master key salt.
030 *
031 * @author Philipp C. Heckel (philipp.heckel@gmail.com)
032 */
033public class SaltedSecretKey implements SecretKey {
034        private static final long serialVersionUID = 1216126055360327470L;
035
036        private SecretKey secretKey;
037        private byte[] salt;
038
039        public SaltedSecretKey(SecretKey secretKey, byte[] salt) {
040                this.secretKey = secretKey;
041                this.salt = salt;
042        }
043
044        public byte[] getSalt() {
045                return salt;
046        }
047
048        @Override
049        public String getAlgorithm() {
050                return secretKey.getAlgorithm();
051        }
052
053        @Override
054        public String getFormat() {
055                return secretKey.getFormat();
056        }
057
058        @Override
059        public byte[] getEncoded() {
060                return secretKey.getEncoded();
061        }
062
063        @Override
064        public String toString() {
065                return "[secretKey={algorithm=" + getAlgorithm() + ", format=" + getFormat() + ", encoded=" + StringUtil.toHex(getEncoded()) + "}, salt="
066                                + StringUtil.toHex(getSalt()) + "]";
067        }
068
069        @Override
070        public int hashCode() {
071                final int prime = 31;
072                int result = 1;
073                result = prime * result + Arrays.hashCode(salt);
074                result = prime * result + ((secretKey == null) ? 0 : secretKey.hashCode());
075                return result;
076        }
077
078        @Override
079        public boolean equals(Object obj) {
080                if (this == obj) {
081                        return true;
082                }
083                if (obj == null) {
084                        return false;
085                }
086                if (!(obj instanceof SaltedSecretKey)) {
087                        return false;
088                }
089                SaltedSecretKey other = (SaltedSecretKey) obj;
090                if (!Arrays.equals(salt, other.salt)) {
091                        return false;
092                }
093                if (secretKey == null) {
094                        if (other.secretKey != null) {
095                                return false;
096                        }
097                }
098                else if (!secretKey.equals(other.secretKey)) {
099                        return false;
100                }
101                return true;
102        }
103}