package org.apache.commons.ssl.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/** Base class for an application specific object */
public class DERApplicationSpecific
extends ASN1Object {
private int tag;
private byte[] octets;
public DERApplicationSpecific(
int tag,
byte[] octets) {
this.tag = tag;
this.octets = octets;
}
public DERApplicationSpecific(
int tag,
DEREncodable object)
throws IOException {
this(true, tag, object);
}
public DERApplicationSpecific(
boolean explicit,
int tag,
DEREncodable object)
throws IOException {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DEROutputStream dos = new DEROutputStream(bOut);
dos.writeObject(object);
byte[] data = bOut.toByteArray();
if (tag >= 0x1f) {
throw new IOException("unsupported tag number");
}
if (explicit) {
this.tag = tag | DERTags.CONSTRUCTED;
this.octets = data;
} else {
this.tag = tag;
int lenBytes = getLengthOfLength(data);
byte[] tmp = new byte[data.length - lenBytes];
System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
this.octets = tmp;
}
}
private int getLengthOfLength(byte[] data) {
int count = 2; // TODO: assumes only a 1 byte tag number
while ((data[count - 1] & 0x80) != 0) {
count++;
}
return count;
}
public boolean isConstructed() {
return (tag & DERTags.CONSTRUCTED) != 0;
}
public byte[] getContents() {
return octets;
}
public int getApplicationTag() {
return tag;
}
public DERObject getObject()
throws IOException {
return new ASN1InputStream(getContents()).readObject();
}
/**
* Return the enclosed object assuming implicit tagging.
*
* @param derTagNo the type tag that should be applied to the object's contents.
* @return the resulting object
* @throws java.io.IOException if reconstruction fails.
*/
public DERObject getObject(int derTagNo)
throws IOException {
if (tag >= 0x1f) {
throw new IOException("unsupported tag number");
}
byte[] tmp = this.getEncoded();
tmp[0] = (byte) derTagNo;
return new ASN1InputStream(tmp).readObject();
}
/* (non-Javadoc)
* @see org.apache.commons.ssl.asn1.DERObject#encode(org.apache.commons.ssl.asn1.DEROutputStream)
*/
void encode(DEROutputStream out) throws IOException {
out.writeEncoded(DERTags.APPLICATION | tag, octets);
}
boolean asn1Equals(
DERObject o) {
if (!(o instanceof DERApplicationSpecific)) {
return false;
}
DERApplicationSpecific other = (DERApplicationSpecific) o;
if (tag != other.tag) {
return false;
}
if (octets.length != other.octets.length) {
return false;
}
for (int i = 0; i < octets.length; i++) {
if (octets[i] != other.octets[i]) {
return false;
}
}
return true;
}
public int hashCode() {
byte[] b = this.getContents();
int value = 0;
for (int i = 0; i != b.length; i++) {
value ^= (b[i] & 0xff) << (i % 4);
}
return value ^ this.getApplicationTag();
}
}