001 /*
002 * Copyright (c) 2000 - 2006 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
003 *
004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this
005 * software and associated documentation files (the "Software"), to deal in the Software
006 * without restriction, including without limitation the rights to use, copy, modify,
007 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
008 * permit persons to whom the Software is furnished to do so, subject to the following
009 * conditions:
010 *
011 * The above copyright notice and this permission notice shall be included in all copies
012 * or substantial portions of the Software.
013 *
014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
015 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
016 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
017 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
018 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
019 * DEALINGS IN THE SOFTWARE.
020 *
021 */
022
023 package org.apache.directory.shared.asn1.der;
024
025
026 import java.io.ByteArrayOutputStream;
027 import java.io.IOException;
028 import java.io.OutputStream;
029
030
031 public class DERObjectIdentifier extends DERObject
032 {
033 String identifier;
034
035
036 DERObjectIdentifier(byte[] bytes)
037 {
038 super( OBJECT_IDENTIFIER, bytes );
039
040 StringBuffer objId = new StringBuffer();
041 long value = 0;
042 boolean first = true;
043
044 for ( int i = 0; i != bytes.length; i++ )
045 {
046 int b = bytes[i] & 0xff;
047
048 value = value * 128 + ( b & 0x7f );
049 if ( ( b & 0x80 ) == 0 ) // end of number reached
050 {
051 if ( first )
052 {
053 switch ( ( int ) value / 40 )
054 {
055 case 0:
056 objId.append( '0' );
057 break;
058 case 1:
059 objId.append( '1' );
060 value -= 40;
061 break;
062 default:
063 objId.append( '2' );
064 value -= 80;
065 break;
066 }
067 first = false;
068 }
069
070 objId.append( '.' );
071 objId.append( Long.toString( value ) );
072 value = 0;
073 }
074 }
075
076 this.identifier = objId.toString();
077 }
078
079
080 private void writeField( OutputStream out, long fieldValue ) throws IOException
081 {
082 if ( fieldValue >= ( 1 << 7 ) )
083 {
084 if ( fieldValue >= ( 1 << 14 ) )
085 {
086 if ( fieldValue >= ( 1 << 21 ) )
087 {
088 if ( fieldValue >= ( 1 << 28 ) )
089 {
090 if ( fieldValue >= ( 1 << 35 ) )
091 {
092 if ( fieldValue >= ( 1 << 42 ) )
093 {
094 if ( fieldValue >= ( 1 << 49 ) )
095 {
096 if ( fieldValue >= ( 1 << 56 ) )
097 {
098 out.write( ( int ) ( fieldValue >> 56 ) | 0x80 );
099 }
100 out.write( ( int ) ( fieldValue >> 49 ) | 0x80 );
101 }
102 out.write( ( int ) ( fieldValue >> 42 ) | 0x80 );
103 }
104 out.write( ( int ) ( fieldValue >> 35 ) | 0x80 );
105 }
106 out.write( ( int ) ( fieldValue >> 28 ) | 0x80 );
107 }
108 out.write( ( int ) ( fieldValue >> 21 ) | 0x80 );
109 }
110 out.write( ( int ) ( fieldValue >> 14 ) | 0x80 );
111 }
112 out.write( ( int ) ( fieldValue >> 7 ) | 0x80 );
113 }
114 out.write( ( int ) fieldValue & 0x7f );
115 }
116
117
118 public void encode( ASN1OutputStream out ) throws IOException
119 {
120 OIDTokenizer tok = new OIDTokenizer( identifier );
121 ByteArrayOutputStream baos = new ByteArrayOutputStream();
122 ASN1OutputStream aos = new ASN1OutputStream( baos );
123
124 writeField( baos, Integer.parseInt( tok.nextToken() ) * 40 + Integer.parseInt( tok.nextToken() ) );
125
126 while ( tok.hasMoreTokens() )
127 {
128 writeField( baos, Long.parseLong( tok.nextToken() ) );
129 }
130
131 aos.close();
132
133 byte[] bytes = baos.toByteArray();
134
135 out.writeEncoded( OBJECT_IDENTIFIER, bytes );
136 }
137 }