package org.bouncycastle.crypto.util;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Strings;
Builder and holder class for preparing SP 800-56A compliant MacData. Elements in the data are encoded
as DER objects with empty octet strings used to represent nulls in compulsory fields.
/**
* Builder and holder class for preparing SP 800-56A compliant MacData. Elements in the data are encoded
* as DER objects with empty octet strings used to represent nulls in compulsory fields.
*/
public final class DERMacData
{
public enum Type
{
UNILATERALU("KC_1_U"),
UNILATERALV("KC_1_V"),
BILATERALU("KC_2_U"),
BILATERALV("KC_2_V");
private final String enc;
Type(String enc)
{
this.enc = enc;
}
public byte[] getHeader()
{
return Strings.toByteArray(enc);
}
}
Builder to create OtherInfo
/**
* Builder to create OtherInfo
*/
public static final class Builder
{
private final Type type;
private ASN1OctetString idU;
private ASN1OctetString idV;
private ASN1OctetString ephemDataU;
private ASN1OctetString ephemDataV;
private byte[] text;
Create a basic builder with just the compulsory fields.
Params: - type – the MAC header
- idU – sender party ID.
- idV – receiver party ID.
- ephemDataU – ephemeral data from sender.
- ephemDataV – ephemeral data from receiver.
/**
* Create a basic builder with just the compulsory fields.
*
* @param type the MAC header
* @param idU sender party ID.
* @param idV receiver party ID.
* @param ephemDataU ephemeral data from sender.
* @param ephemDataV ephemeral data from receiver.
*/
public Builder(Type type, byte[] idU, byte[] idV, byte[] ephemDataU, byte[] ephemDataV)
{
this.type = type;
this.idU = DerUtil.getOctetString(idU);
this.idV = DerUtil.getOctetString(idV);
this.ephemDataU = DerUtil.getOctetString(ephemDataU);
this.ephemDataV = DerUtil.getOctetString(ephemDataV);
}
Add optional text.
Params: - text – optional agreed text to add to the MAC.
Returns: the current builder instance.
/**
* Add optional text.
*
* @param text optional agreed text to add to the MAC.
* @return the current builder instance.
*/
public Builder withText(byte[] text)
{
this.text = DerUtil.toByteArray(new DERTaggedObject(false, 0, DerUtil.getOctetString(text)));
return this;
}
public DERMacData build()
{
switch (type)
{
case UNILATERALU:
case BILATERALU:
return new DERMacData(concatenate(type.getHeader(),
DerUtil.toByteArray(idU), DerUtil.toByteArray(idV),
DerUtil.toByteArray(ephemDataU), DerUtil.toByteArray(ephemDataV), text));
case UNILATERALV:
case BILATERALV:
return new DERMacData(concatenate(type.getHeader(),
DerUtil.toByteArray(idV), DerUtil.toByteArray(idU),
DerUtil.toByteArray(ephemDataV), DerUtil.toByteArray(ephemDataU), text));
}
throw new IllegalStateException("Unknown type encountered in build"); // should never happen
}
private byte[] concatenate(byte[] header, byte[] id1, byte[] id2, byte[] ed1, byte[] ed2, byte[] text)
{
return Arrays.concatenate(Arrays.concatenate(header, id1, id2), Arrays.concatenate(ed1, ed2, text));
}
}
private final byte[] macData;
private DERMacData(byte[] macData)
{
this.macData = macData;
}
public byte[] getMacData()
{
return Arrays.clone(macData);
}
}