001/**
002 *
003 * Copyright 2017 Paul Schaub, 2019 Florian Schmaus
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.omemo.internal;
018
019import static org.jivesoftware.smackx.omemo.util.OmemoConstants.Crypto.CIPHERMODE;
020import static org.jivesoftware.smackx.omemo.util.OmemoConstants.Crypto.KEYTYPE;
021
022import java.security.InvalidAlgorithmParameterException;
023import java.security.NoSuchAlgorithmException;
024
025import javax.crypto.Cipher;
026import javax.crypto.NoSuchPaddingException;
027import javax.crypto.spec.IvParameterSpec;
028import javax.crypto.spec.SecretKeySpec;
029
030import org.jivesoftware.smackx.omemo.exceptions.CryptoFailedException;
031
032/**
033 * Encapsulate Cipher and AuthTag.
034 *
035 * @author Paul Schaub
036 */
037public class CipherAndAuthTag {
038    private final byte[] key, iv, authTag;
039    private final boolean wasPreKey;
040
041    public CipherAndAuthTag(byte[] key, byte[] iv, byte[] authTag, boolean wasPreKey) {
042        this.authTag = authTag;
043        this.key = key;
044        this.iv = iv;
045        this.wasPreKey = wasPreKey;
046    }
047
048    public Cipher getCipher() throws CryptoFailedException {
049
050        Cipher cipher;
051        try {
052            cipher = Cipher.getInstance(CIPHERMODE);
053            SecretKeySpec keySpec = new SecretKeySpec(key, KEYTYPE);
054            IvParameterSpec ivSpec = new IvParameterSpec(iv);
055            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
056        } catch (NoSuchAlgorithmException | java.security.InvalidKeyException |
057                InvalidAlgorithmParameterException |
058                NoSuchPaddingException e) {
059            throw new CryptoFailedException(e);
060        }
061
062        return cipher;
063    }
064
065    public byte[] getAuthTag() {
066        if (authTag != null) {
067            return authTag.clone();
068        }
069        return null;
070    }
071
072    public byte[] getKey() {
073        if (key != null) {
074            return key.clone();
075        }
076        return null;
077    }
078
079    public byte[] getIv() {
080        if (iv != null) {
081            return iv.clone();
082        }
083        return null;
084    }
085
086    public boolean wasPreKeyEncrypted() {
087        return wasPreKey;
088    }
089}