// 
// Decompiled by Procyon v0.6.0
// 

package com.nimbusds.jose.crypto.impl;

import com.nimbusds.jose.util.StandardCharset;
import javax.crypto.spec.SecretKeySpec;
import com.nimbusds.jose.KeyLengthException;
import com.nimbusds.jose.util.ByteUtils;
import com.nimbusds.jose.JOSEException;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import javax.crypto.SecretKey;
import com.nimbusds.jose.JWSAlgorithm;
import java.util.Set;

public abstract class MACProvider extends BaseJWSProvider
{
    public static final Set<JWSAlgorithm> SUPPORTED_ALGORITHMS;
    private final byte[] secret;
    private final SecretKey secretKey;
    
    public static Set<JWSAlgorithm> getCompatibleAlgorithms(final int secretLength) {
        final Set<JWSAlgorithm> hmacAlgs = new LinkedHashSet<JWSAlgorithm>();
        if (secretLength >= 256) {
            hmacAlgs.add(JWSAlgorithm.HS256);
        }
        if (secretLength >= 384) {
            hmacAlgs.add(JWSAlgorithm.HS384);
        }
        if (secretLength >= 512) {
            hmacAlgs.add(JWSAlgorithm.HS512);
        }
        return Collections.unmodifiableSet((Set<? extends JWSAlgorithm>)hmacAlgs);
    }
    
    public static int getMinRequiredSecretLength(final JWSAlgorithm alg) throws JOSEException {
        if (JWSAlgorithm.HS256.equals(alg)) {
            return 256;
        }
        if (JWSAlgorithm.HS384.equals(alg)) {
            return 384;
        }
        if (JWSAlgorithm.HS512.equals(alg)) {
            return 512;
        }
        throw new JOSEException(AlgorithmSupportMessage.unsupportedJWSAlgorithm(alg, MACProvider.SUPPORTED_ALGORITHMS));
    }
    
    protected static String getJCAAlgorithmName(final JWSAlgorithm alg) throws JOSEException {
        if (alg.equals(JWSAlgorithm.HS256)) {
            return "HMACSHA256";
        }
        if (alg.equals(JWSAlgorithm.HS384)) {
            return "HMACSHA384";
        }
        if (alg.equals(JWSAlgorithm.HS512)) {
            return "HMACSHA512";
        }
        throw new JOSEException(AlgorithmSupportMessage.unsupportedJWSAlgorithm(alg, MACProvider.SUPPORTED_ALGORITHMS));
    }
    
    protected MACProvider(final byte[] secret) throws KeyLengthException {
        super(getCompatibleAlgorithms(ByteUtils.bitLength(secret.length)));
        if (ByteUtils.bitLength(secret) < 256) {
            throw new KeyLengthException("The secret length must be at least 256 bits");
        }
        this.secret = secret;
        this.secretKey = null;
    }
    
    protected MACProvider(final SecretKey secretKey) throws KeyLengthException {
        super((secretKey.getEncoded() != null) ? getCompatibleAlgorithms(ByteUtils.bitLength(secretKey.getEncoded())) : MACProvider.SUPPORTED_ALGORITHMS);
        if (secretKey.getEncoded() != null && ByteUtils.bitLength(secretKey.getEncoded()) < 256) {
            throw new KeyLengthException("The secret length must be at least 256 bits");
        }
        this.secretKey = secretKey;
        this.secret = null;
    }
    
    public SecretKey getSecretKey() {
        if (this.secretKey != null) {
            return this.secretKey;
        }
        if (this.secret != null) {
            return new SecretKeySpec(this.secret, "MAC");
        }
        throw new IllegalStateException("Unexpected state");
    }
    
    public byte[] getSecret() {
        if (this.secretKey != null) {
            return this.secretKey.getEncoded();
        }
        if (this.secret != null) {
            return this.secret;
        }
        throw new IllegalStateException("Unexpected state");
    }
    
    public String getSecretString() {
        final byte[] secret = this.getSecret();
        if (secret == null) {
            return null;
        }
        return new String(secret, StandardCharset.UTF_8);
    }
    
    protected void ensureSecretLengthSatisfiesAlgorithm(final JWSAlgorithm alg) throws JOSEException {
        if (this.getSecret() == null) {
            return;
        }
        final int minRequiredBitLength = getMinRequiredSecretLength(alg);
        if (ByteUtils.bitLength(this.getSecret()) < minRequiredBitLength) {
            throw new KeyLengthException("The secret length for " + alg + " must be at least " + minRequiredBitLength + " bits");
        }
    }
    
    static {
        final Set<JWSAlgorithm> algs = new LinkedHashSet<JWSAlgorithm>();
        algs.add(JWSAlgorithm.HS256);
        algs.add(JWSAlgorithm.HS384);
        algs.add(JWSAlgorithm.HS512);
        SUPPORTED_ALGORITHMS = Collections.unmodifiableSet((Set<? extends JWSAlgorithm>)algs);
    }
}
