summaryrefslogtreecommitdiff
path: root/gnu/java/security/provider/DERWriter.java
blob: 037274d1e27896eeaa05d167fc101e41071ad655 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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;
		//System.out.println("Identifier1: " + b[0]);
		return b;
	} else {
		b = new byte[1];
		b[0] = (byte)((translateLeadIdentifierByte(identifierencoding)
		| (byte)( identifier & 0x1f )) & 0xdf);
		//System.out.println("Identifier2: " + b[0]);
		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 ));
		//System.out.println("Length byte count: " + count);
		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) ));
			//System.out.println("Length1 byte1: " + (length >>> (8 * ( count - i) )));
			//System.out.println("Length1 byte2: " + b[i]);
		}

		//System.out.println("Length1: " + length);
		return b;
	} else {
		b = new byte[1];
		b[0] = (byte)( length & 0x7f );
		//System.out.println("Length2: " + length);
		return b;
	}
}
}