org.bouncycastle.asn1.pkcs.PBKDF2Params.java Source code

Java tutorial

Introduction

Here is the source code for org.bouncycastle.asn1.pkcs.PBKDF2Params.java

Source

package org.bouncycastle.asn1.pkcs;

import java.math.BigInteger;
import java.util.Enumeration;

import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.util.Arrays;

/**
 * <pre>
 *     PBKDF2-params ::= SEQUENCE {
 *               salt CHOICE {
 *                      specified OCTET STRING,
 *                      otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}}
 *               },
 *              iterationCount INTEGER (1..MAX),
 *              keyLength INTEGER (1..MAX) OPTIONAL,
 *              prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
 * </pre>
 */
public class PBKDF2Params extends ASN1Object {
    private static final AlgorithmIdentifier algid_hmacWithSHA1 = new AlgorithmIdentifier(
            PKCSObjectIdentifiers.id_hmacWithSHA1, DERNull.INSTANCE);

    private final ASN1OctetString octStr;
    private final ASN1Integer iterationCount;
    private final ASN1Integer keyLength;
    private final AlgorithmIdentifier prf;

    /**
     * Create PBKDF2Params from the passed in object,
     *
     * @param obj either PBKDF2Params or an ASN1Sequence.
     * @return a PBKDF2Params instance.
     */
    public static PBKDF2Params getInstance(Object obj) {
        if (obj instanceof PBKDF2Params) {
            return (PBKDF2Params) obj;
        }

        if (obj != null) {
            return new PBKDF2Params(ASN1Sequence.getInstance(obj));
        }

        return null;
    }

    /**
     * Create a PBKDF2Params with the specified salt, iteration count, and algid-hmacWithSHA1 for the prf.
     *
     * @param salt           input salt.
     * @param iterationCount input iteration count.
     */
    public PBKDF2Params(byte[] salt, int iterationCount) {
        this(salt, iterationCount, 0);
    }

    /**
     * Create a PBKDF2Params with the specified salt, iteration count, keyLength, and algid-hmacWithSHA1 for the prf.
     *
     * @param salt           input salt.
     * @param iterationCount input iteration count.
     * @param keyLength      intended key length to be produced.
     */
    public PBKDF2Params(byte[] salt, int iterationCount, int keyLength) {
        this(salt, iterationCount, keyLength, null);
    }

    /**
     * Create a PBKDF2Params with the specified salt, iteration count, keyLength, and a defined prf.
     *
     * @param salt           input salt.
     * @param iterationCount input iteration count.
     * @param keyLength      intended key length to be produced.
     * @param prf            the pseudo-random function to use.
     */
    public PBKDF2Params(byte[] salt, int iterationCount, int keyLength, AlgorithmIdentifier prf) {
        this.octStr = new DEROctetString(Arrays.clone(salt));
        this.iterationCount = new ASN1Integer(iterationCount);

        if (keyLength > 0) {
            this.keyLength = new ASN1Integer(keyLength);
        } else {
            this.keyLength = null;
        }

        this.prf = prf;
    }

    /**
     * Create a PBKDF2Params with the specified salt, iteration count, and a defined prf.
     *
     * @param salt           input salt.
     * @param iterationCount input iteration count.
     * @param prf            the pseudo-random function to use.
     */
    public PBKDF2Params(byte[] salt, int iterationCount, AlgorithmIdentifier prf) {
        this(salt, iterationCount, 0, prf);
    }

    private PBKDF2Params(ASN1Sequence seq) {
        Enumeration e = seq.getObjects();

        octStr = (ASN1OctetString) e.nextElement();
        iterationCount = (ASN1Integer) e.nextElement();

        if (e.hasMoreElements()) {
            Object o = e.nextElement();

            if (o instanceof ASN1Integer) {
                keyLength = ASN1Integer.getInstance(o);
                if (e.hasMoreElements()) {
                    o = e.nextElement();
                } else {
                    o = null;
                }
            } else {
                keyLength = null;
            }

            if (o != null) {
                prf = AlgorithmIdentifier.getInstance(o);
            } else {
                prf = null;
            }
        } else {
            keyLength = null;
            prf = null;
        }
    }

    /**
     * Return the salt to use.
     *
     * @return the input salt.
     */
    public byte[] getSalt() {
        return octStr.getOctets();
    }

    /**
     * Return the iteration count to use.
     *
     * @return the input iteration count.
     */
    public BigInteger getIterationCount() {
        return iterationCount.getValue();
    }

    /**
     * Return the intended length in octets of the derived key.
     *
     * @return length in octets for derived key, if specified.
     */
    public BigInteger getKeyLength() {
        if (keyLength != null) {
            return keyLength.getValue();
        }

        return null;
    }

    /**
     * Return true if the PRF is the default (hmacWithSHA1)
     *
     * @return true if PRF is default, false otherwise.
     */
    public boolean isDefaultPrf() {
        return prf == null || prf.equals(algid_hmacWithSHA1);
    }

    /**
     * Return the algId of the underlying pseudo random function to use.
     *
     * @return the prf algorithm identifier.
     */
    public AlgorithmIdentifier getPrf() {
        if (prf != null) {
            return prf;
        }

        return algid_hmacWithSHA1;
    }

    /**
     * Return an ASN.1 structure suitable for encoding.
     *
     * @return the object as an ASN.1 encodable structure.
     */
    public ASN1Primitive toASN1Primitive() {
        ASN1EncodableVector v = new ASN1EncodableVector(4);

        v.add(octStr);
        v.add(iterationCount);

        if (keyLength != null) {
            v.add(keyLength);
        }

        if (prf != null && !prf.equals(algid_hmacWithSHA1)) {
            v.add(prf);
        }

        return new DERSequence(v);
    }
}