package gnu.java.security.provider;
import java.math.BigInteger;
public class DERWriter
{
static final int UNIVERSAL = 1;
static final int APPLICATION = 2;
static final int CONTEXT_SPECIFIC = 3;
static final int PRIVATE = 4;
public DERWriter()
{}
public byte[] writeBigInteger( BigInteger i)
{
return writePrimitive( 0x02, UNIVERSAL, (int)Math.ceil((double)i.bitLength() / 8), i.toByteArray() );
}
private byte[] writePrimitive( int identifier, int identifierencoding,
int length, byte contents[])
{
return joinarrays( generateIdentifier( identifier, identifierencoding ), generateLength( length ), contents);
}
public byte[] joinarrays( byte a[], byte b[])
{
byte d[] = new byte[ a.length + b.length];
System.arraycopy( a, 0, d, 0, a.length);
System.arraycopy( b, 0, d, a.length, b.length);
return d;
}
public byte[] joinarrays( byte a[], byte b[], byte c[])
{
byte d[] = new byte[ a.length + b.length + c.length];
System.arraycopy( a, 0, d, 0, a.length);
System.arraycopy( b, 0, d, a.length, b.length);
System.arraycopy( c, 0, d, a.length + b.length, c.length);
return d;
}
private byte[] generateIdentifier(int identifier,
int identifierencoding)
{
byte b[];
if( identifier > 31 ) {
int count = (int)(Math.log( identifier ) / Math.log( 256 ));
b = new byte[ count + 1 ];
b[0] = (byte)(translateLeadIdentifierByte(identifierencoding)
| 0x1f);
int i;
for( i = 1; i < (count + 1); i++) {
b[i] = (byte)(0x7f & ( identifier >> (7 * (count - i)) ));
b[i] |= 0x80;
}
b[i - 1] ^= 0x80;
return b;
} else {
b = new byte[1];
b[0] = (byte)((translateLeadIdentifierByte(identifierencoding)
| (byte)( identifier & 0x1f )) & 0xdf);
return b;
}
}
private byte translateLeadIdentifierByte(int b)
{
if( b == UNIVERSAL)
return (byte)0x3f;
else if( b == APPLICATION)
return (byte)0x7f;
else if( b == CONTEXT_SPECIFIC)
return (byte)0xbf;
else
return (byte)0xC0;
}
private byte[] generateLength( int length )
{
byte b[];
if( length > 127 ) {
int count = (int)Math.ceil(Math.log( length ) / Math.log( 256 ));
b = new byte[ count + 1 ];
b[0] = (byte)((count & 0x7f) | 0x80);
for( int i = 1; i < (count + 1); i++) {
b[i] = (byte)( length >>> (8 * ( count - i) ));
}
return b;
} else {
b = new byte[1];
b[0] = (byte)( length & 0x7f );
return b;
}
}
}