1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.asn1.util;
21
22
23 import java.io.IOException;
24 import java.io.OutputStream;
25 import java.math.BigInteger;
26 import java.nio.ByteBuffer;
27 import java.util.Arrays;
28
29 import org.apache.directory.api.asn1.DecoderException;
30 import org.apache.directory.api.i18n.I18n;
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 public final class Oid
77 {
78
79 private byte[] oidBytes;
80
81
82 private String oidString;
83
84 private static final BigInteger JOINT_ISO_ITU_T = BigInteger.valueOf( 80 );
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 private enum OidFSAState
137 {
138 START,
139 STATE_A,
140 STATE_B,
141 STATE_C,
142 STATE_D,
143 STATE_E,
144 STATE_F,
145 STATE_G,
146 STATE_H,
147 STATE_I,
148 STATE_J,
149 STATE_K,
150 STATE_L,
151 STATE_M,
152 }
153
154
155
156
157
158
159
160
161 private Oid( String oidString, byte[] oidBytes )
162 {
163 this.oidString = oidString;
164 this.oidBytes = new byte[oidBytes.length];
165 System.arraycopy( oidBytes, 0, this.oidBytes, 0, oidBytes.length );
166 }
167
168
169
170
171
172 @Override
173 public boolean equals( Object other )
174 {
175 return ( other instanceof Oid )
176 && oidString.equals( ( ( Oid ) other ).oidString );
177 }
178
179
180
181
182
183
184
185
186
187 public static Oid fromBytes( byte[] oidBytes ) throws DecoderException
188 {
189 if ( ( oidBytes == null ) || ( oidBytes.length < 1 ) )
190 {
191 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, Arrays.toString( oidBytes ) ) );
192 }
193
194 StringBuilder builder = new StringBuilder();
195 long value = 0;
196 int valStart = 0;
197 int valLength = 0;
198 boolean firstArc = true;
199
200 for ( int i = 0; i < oidBytes.length; i++ )
201 {
202 value |= oidBytes[i] & 0x7F;
203
204 if ( oidBytes[i] < 0 )
205 {
206
207 value = value << 7;
208 valLength++;
209 }
210 else
211 {
212 valLength++;
213
214 if ( valLength > 8 )
215 {
216
217
218 int nbBytes = valLength * 7 / 8;
219
220 if ( valLength % 7 != 0 )
221 {
222 nbBytes++;
223 }
224
225 byte[] result = new byte[nbBytes];
226
227
228 int pos = nbBytes - 1;
229 int valEnd = valStart + valLength - 1;
230 int j = 0;
231
232 while ( j < valLength - 8 )
233 {
234 result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 1] << 7 ) | ( oidBytes[valEnd - j] & 0x7F ) );
235 result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 2] << 6 ) | ( ( oidBytes[valEnd - j - 1] & 0x7E ) >> 1 ) );
236 result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 3] << 5 ) | ( ( oidBytes[valEnd - j - 2] & 0x7C ) >> 2 ) );
237 result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 4] << 4 ) | ( ( oidBytes[valEnd - j - 3] & 0x78 ) >> 3 ) );
238 result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 5] << 3 ) | ( ( oidBytes[valEnd - j - 4] & 0x70 ) >> 4 ) );
239 result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 6] << 2 ) | ( ( oidBytes[valEnd - j - 5] & 0x60 ) >> 5 ) );
240 result[pos--] = ( byte ) ( ( oidBytes[valEnd - j - 7] << 1 ) | ( ( oidBytes[valEnd - j - 6] & 0x40 ) >> 6 ) );
241 j += 8;
242 }
243
244 switch ( valLength - j )
245 {
246 case 7 :
247 result[pos--] = ( byte ) ( ( oidBytes[5] << 7 ) | ( oidBytes[6] & 0x7F ) );
248 result[pos--] = ( byte ) ( ( oidBytes[4] << 6 ) | ( ( oidBytes[5] & 0x7E ) >> 1 ) );
249 result[pos--] = ( byte ) ( ( oidBytes[3] << 5 ) | ( ( oidBytes[4] & 0x7C ) >> 2 ) );
250 result[pos--] = ( byte ) ( ( oidBytes[2] << 4 ) | ( ( oidBytes[3] & 0x78 ) >> 3 ) );
251 result[pos--] = ( byte ) ( ( oidBytes[1] << 3 ) | ( ( oidBytes[2] & 0x70 ) >> 4 ) );
252 result[pos--] = ( byte ) ( ( oidBytes[0] << 2 ) | ( ( oidBytes[1] & 0x60 ) >> 5 ) );
253 result[pos] = ( byte ) ( ( oidBytes[0] & 0x40 ) >> 6 );
254 break;
255
256 case 6 :
257 result[pos--] = ( byte ) ( ( oidBytes[4] << 7 ) | ( oidBytes[5] & 0x7F ) );
258 result[pos--] = ( byte ) ( ( oidBytes[3] << 6 ) | ( ( oidBytes[4] & 0x7E ) >> 1 ) );
259 result[pos--] = ( byte ) ( ( oidBytes[2] << 5 ) | ( ( oidBytes[3] & 0x7C ) >> 2 ) );
260 result[pos--] = ( byte ) ( ( oidBytes[1] << 4 ) | ( ( oidBytes[2] & 0x78 ) >> 3 ) );
261 result[pos--] = ( byte ) ( ( oidBytes[0] << 3 ) | ( ( oidBytes[1] & 0x70 ) >> 4 ) );
262 result[pos] = ( byte ) ( ( oidBytes[0] & 0x60 ) >> 5 );
263 break;
264
265 case 5 :
266 result[pos--] = ( byte ) ( ( oidBytes[3] << 7 ) | ( oidBytes[4] & 0x7F ) );
267 result[pos--] = ( byte ) ( ( oidBytes[2] << 6 ) | ( ( oidBytes[3] & 0x7E ) >> 1 ) );
268 result[pos--] = ( byte ) ( ( oidBytes[1] << 5 ) | ( ( oidBytes[2] & 0x7C ) >> 2 ) );
269 result[pos--] = ( byte ) ( ( oidBytes[0] << 4 ) | ( ( oidBytes[1] & 0x78 ) >> 3 ) );
270 result[pos] = ( byte ) ( ( oidBytes[0] & 0x70 ) >> 4 );
271 break;
272
273 case 4 :
274 result[pos--] = ( byte ) ( ( oidBytes[2] << 7 ) | ( oidBytes[3] & 0x7F ) );
275 result[pos--] = ( byte ) ( ( oidBytes[1] << 6 ) | ( ( oidBytes[2] & 0x7E ) >> 1 ) );
276 result[pos--] = ( byte ) ( ( oidBytes[0] << 5 ) | ( ( oidBytes[1] & 0x7C ) >> 2 ) );
277 result[pos] = ( byte ) ( ( oidBytes[0] & 0x78 ) >> 3 );
278 break;
279
280 case 3 :
281 result[pos--] = ( byte ) ( ( oidBytes[1] << 7 ) | ( oidBytes[2] & 0x7F ) );
282 result[pos--] = ( byte ) ( ( oidBytes[0] << 6 ) | ( ( oidBytes[1] & 0x7E ) >> 1 ) );
283 result[pos] = ( byte ) ( ( oidBytes[0] & 0x7C ) >> 2 );
284 break;
285
286 case 2 :
287 result[pos--] = ( byte ) ( ( oidBytes[0] << 7 ) | ( oidBytes[1] & 0x7F ) );
288 result[pos] = ( byte ) ( ( oidBytes[0] & 0x7E ) >> 1 );
289 break;
290
291 case 1 :
292 result[pos] = ( byte ) ( oidBytes[0] & 0x7F );
293 break;
294
295 default :
296
297 break;
298 }
299
300 BigInteger bigInteger;
301
302 if ( ( result[0] & 0x80 ) == 0x80 )
303 {
304 byte[] newResult = new byte[result.length + 1];
305 System.arraycopy( result, 0, newResult, 1, result.length );
306 result = newResult;
307 }
308
309 bigInteger = new BigInteger( result );
310
311 if ( firstArc )
312 {
313
314 bigInteger = bigInteger.subtract( JOINT_ISO_ITU_T );
315 builder.append( '2' );
316 }
317
318 builder.append( '.' ).append( bigInteger.toString() );
319 }
320 else
321 {
322
323 if ( firstArc )
324 {
325
326 if ( value >= 80 )
327 {
328
329 builder.append( '2' );
330 value = value - 80;
331 }
332 else
333 {
334
335 long one = value / 40;
336 long two = value % 40;
337
338 if ( ( one < 0 ) || ( one > 2 ) || ( two < 0 ) || ( ( one < 2 ) && ( two > 39 ) ) )
339 {
340 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID,
341 Arrays.toString( oidBytes ) ) );
342 }
343
344 if ( one < 2 )
345 {
346 builder.append( one );
347 value = two;
348 }
349 }
350
351 firstArc = false;
352 }
353
354
355 builder.append( '.' ).append( value );
356 }
357
358 valStart = i;
359 valLength = 0;
360 value = 0;
361 }
362 }
363
364 return new Oid( builder.toString(), oidBytes );
365 }
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381 private static OidFSAState processStateStart( String oid, byte[] buffer, int pos ) throws DecoderException
382 {
383 char c = oid.charAt( pos );
384
385 switch ( c )
386 {
387 case '0' :
388 case '1' :
389 buffer[0] = ( byte ) ( ( c - '0' ) * 40 );
390 return OidFSAState.STATE_A;
391
392 case '2' :
393 return OidFSAState.STATE_F;
394
395 default :
396
397 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "Should start with 0, 1 or 2" ) );
398 }
399 }
400
401
402
403
404
405
406
407
408
409
410
411
412
413 private static OidFSAState processStateA( String oid, int pos ) throws DecoderException
414 {
415 if ( oid.charAt( pos ) != '.' )
416 {
417
418 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a '.' is expected" ) );
419 }
420
421 return OidFSAState.STATE_B;
422 }
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439 private static OidFSAState processStateB( String oid, byte[] buffer, int pos ) throws DecoderException
440 {
441 char c = oid.charAt( pos );
442
443 switch ( c )
444 {
445 case '0' :
446 return OidFSAState.STATE_D;
447
448 case '1' :
449 case '2' :
450 case '3' :
451
452 buffer[1] = ( byte ) ( c - '0' );
453
454 return OidFSAState.STATE_C;
455
456 case '4' :
457 case '5' :
458 case '6' :
459 case '7' :
460 case '8' :
461 case '9' :
462 buffer[0] += ( byte ) ( c - '0' );
463 return OidFSAState.STATE_E;
464
465 default :
466
467 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a digit is expected" ) );
468 }
469 }
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485 private static OidFSAState processStateC( String oid, byte[] buffer, int pos ) throws DecoderException
486 {
487 char c = oid.charAt( pos );
488
489 switch ( c )
490 {
491 case '0' :
492 case '1' :
493 case '2' :
494 case '3' :
495 case '4' :
496 case '5' :
497 case '6' :
498 case '7' :
499 case '8' :
500 case '9' :
501 buffer[0] += ( byte ) ( buffer[1] * 10 + ( c - '0' ) );
502 buffer[1] = 0;
503 return OidFSAState.STATE_E;
504
505 case '.' :
506 buffer[0] += buffer[1];
507 buffer[1] = 0;
508 return OidFSAState.STATE_K;
509
510 default :
511
512 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a digit is expected" ) );
513 }
514 }
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530 private static OidFSAState processStateDE( String oid, byte[] buffer, int pos ) throws DecoderException
531 {
532 char c = oid.charAt( pos );
533
534 if ( c != '.' )
535 {
536
537 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a dot is expected" ) );
538 }
539
540
541 buffer[0] = ( byte ) ( buffer[0] | buffer[1] );
542 buffer[1] = 0;
543
544 return OidFSAState.STATE_K;
545 }
546
547
548
549
550
551
552
553
554
555
556
557
558
559 private static OidFSAState processStateF( String oid, int pos ) throws DecoderException
560 {
561 if ( oid.charAt( pos ) != '.' )
562 {
563
564 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a '.' is expected" ) );
565 }
566
567 return OidFSAState.STATE_G;
568 }
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584 private static OidFSAState processStateG( String oid, byte[] buffer, int pos ) throws DecoderException
585 {
586 char c = oid.charAt( pos );
587
588 switch ( c )
589 {
590 case '0' :
591 buffer[0] = ( byte ) 80;
592 return OidFSAState.STATE_I;
593
594 case '1' :
595 case '2' :
596 case '3' :
597 case '4' :
598 case '5' :
599 case '6' :
600 case '7' :
601 case '8' :
602 case '9' :
603
604 buffer[0] = ( byte ) ( c - '0' );
605 return OidFSAState.STATE_H;
606
607 default :
608
609 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a digit is expected" ) );
610 }
611 }
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627 private static OidFSAState processStateH( String oid, byte[] buffer, int pos ) throws DecoderException
628 {
629 char c = oid.charAt( pos );
630
631 switch ( c )
632 {
633 case '0' :
634 case '1' :
635 case '2' :
636 case '3' :
637 case '4' :
638 case '5' :
639 case '6' :
640 case '7' :
641 case '8' :
642 case '9' :
643
644 buffer[1] = ( byte ) ( c - '0' );
645 return OidFSAState.STATE_J;
646
647 case '.' :
648
649 buffer[0] = ( byte ) ( 80 + buffer[0] );
650
651 return OidFSAState.STATE_K;
652
653 default :
654
655 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a digit is expected" ) );
656 }
657 }
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672 private static OidFSAState processStateI( String oid, byte[] buffer, int pos ) throws DecoderException
673 {
674 char c = oid.charAt( pos );
675
676 if ( c == '.' )
677 {
678
679 buffer[0] = ( byte ) ( 80 + buffer[1] );
680 return OidFSAState.STATE_K;
681 }
682 else
683 {
684
685 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a digit is expected" ) );
686 }
687 }
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704 private static OidFSAState processStateJ( String oid, byte[] buffer, int bufferPos, int pos ) throws DecoderException
705 {
706 char c = oid.charAt( pos );
707
708 switch ( c )
709 {
710 case '.' :
711 return OidFSAState.STATE_K;
712
713 case '0' :
714 case '1' :
715 case '2' :
716 case '3' :
717 case '4' :
718 case '5' :
719 case '6' :
720 case '7' :
721 case '8' :
722 case '9' :
723
724 buffer[bufferPos] = ( byte ) ( c - '0' );
725 return OidFSAState.STATE_J;
726
727 default :
728
729 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a digit is expected" ) );
730 }
731 }
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748 private static OidFSAState processStateK( String oid, byte[] buffer, int bufferPos, int pos ) throws DecoderException
749 {
750 char c = oid.charAt( pos );
751
752 switch ( c )
753 {
754 case '0' :
755 buffer[bufferPos] = 0x00;
756 return OidFSAState.STATE_M;
757
758 case '1' :
759 case '2' :
760 case '3' :
761 case '4' :
762 case '5' :
763 case '6' :
764 case '7' :
765 case '8' :
766 case '9' :
767
768 return OidFSAState.STATE_L;
769
770 default :
771
772 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a digit is expected" ) );
773 }
774 }
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791 private static OidFSAState processStateL( String oid, byte[] buffer, int bufferPos, int pos ) throws DecoderException
792 {
793 char c = oid.charAt( pos );
794
795 switch ( c )
796 {
797 case '.' :
798 return OidFSAState.STATE_K;
799
800 case '0' :
801 case '1' :
802 case '2' :
803 case '3' :
804 case '4' :
805 case '5' :
806 case '6' :
807 case '7' :
808 case '8' :
809 case '9' :
810
811 buffer[bufferPos] = ( byte ) ( c - '0' );
812
813 return OidFSAState.STATE_L;
814
815 default :
816
817 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a digit or a dot is expected" ) );
818 }
819 }
820
821
822
823
824
825
826
827
828
829
830
831
832
833 private static OidFSAState processStateM( String oid, int pos ) throws DecoderException
834 {
835 char c = oid.charAt( pos );
836
837 if ( c == '.' )
838 {
839 return OidFSAState.STATE_K;
840 }
841 else
842 {
843
844 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "a '.' is expected" ) );
845 }
846 }
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861 private static int convert( String oid, byte[] buffer, int start, int nbDigits, int posBuffer, boolean isJointIsoItuT )
862 {
863 if ( nbDigits < 3 )
864 {
865
866
867 if ( isJointIsoItuT )
868 {
869
870 buffer[0] = ( byte ) ( 80 + ( oid.charAt( 2 ) - '0' ) * 10 + ( oid.charAt( 3 ) - '0' ) );
871
872 if ( buffer[0] < 0 )
873 {
874
875 buffer[1] = ( byte ) ( buffer[0] & 0x007F );
876 buffer[0] = ( byte ) 0x81;
877
878 return 2;
879 }
880 else
881 {
882 return 1;
883 }
884 }
885 else
886 {
887 if ( nbDigits == 1 )
888 {
889 buffer[posBuffer] = ( byte ) ( oid.charAt( start ) - '0' );
890 }
891 else
892 {
893 buffer[posBuffer] = ( byte ) ( ( oid.charAt( start ) - '0' ) * 10 + ( oid.charAt( start + 1 ) - '0' ) );
894
895 }
896 return 1;
897 }
898
899 }
900 else if ( nbDigits < 19 )
901 {
902
903
904 String number = oid.substring( start, start + nbDigits );
905
906 long value = Long.parseLong( number );
907
908 if ( isJointIsoItuT )
909 {
910 value += 80L;
911 }
912
913
914 if ( ( value & 0xFFFFFFFFFFFFFF80L ) == 0 )
915 {
916
917 buffer[posBuffer] = ( byte ) ( value );
918
919 return 1;
920 }
921
922 if ( ( value & 0xFFFFFFFFFFFFC000L ) == 0 )
923 {
924
925 buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
926 buffer[posBuffer + 1] = ( byte ) ( value & 0x000000000000007FL );
927
928 return 2;
929 }
930
931 if ( ( value & 0xFFFFFFFFFFE00000L ) == 0 )
932 {
933
934 buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
935 buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
936 buffer[posBuffer + 2] = ( byte ) ( value & 0x000000000000007FL );
937
938 return 3;
939 }
940
941 if ( ( value & 0xFFFFFFFFF0000000L ) == 0 )
942 {
943
944 buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
945 buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
946 buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
947 buffer[posBuffer + 3] = ( byte ) ( value & 0x000000000000007FL );
948
949 return 4;
950 }
951
952 if ( ( value & 0xFFFFFFF800000000L ) == 0 )
953 {
954
955 buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x00000007F0000000L ) >> 28 ) | 0x80 );
956 buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
957 buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
958 buffer[posBuffer + 3] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
959 buffer[posBuffer + 4] = ( byte ) ( value & 0x000000000000007FL );
960
961 return 5;
962 }
963
964 if ( ( value & 0xFFFFFC0000000000L ) == 0 )
965 {
966
967 buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x000003F800000000L ) >> 35 ) | 0x80 );
968 buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x00000007F0000000L ) >> 28 ) | 0x80 );
969 buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
970 buffer[posBuffer + 3] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
971 buffer[posBuffer + 4] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
972 buffer[posBuffer + 5] = ( byte ) ( value & 0x000000000000007FL );
973
974 return 6;
975 }
976
977 if ( ( value & 0xFFFE000000000000L ) == 0 )
978 {
979
980 buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x0001FC0000000000L ) >> 42 ) | 0x80 );
981 buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x000003F800000000L ) >> 35 ) | 0x80 );
982 buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x00000007F0000000L ) >> 28 ) | 0x80 );
983 buffer[posBuffer + 3] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
984 buffer[posBuffer + 4] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
985 buffer[posBuffer + 5] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
986 buffer[posBuffer + 6] = ( byte ) ( value & 0x000000000000007FL );
987
988 return 7;
989 }
990
991 if ( ( value & 0xFF00000000000000L ) == 0 )
992 {
993
994 buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x00FE000000000000L ) >> 49 ) | 0x80 );
995 buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x0001FC0000000000L ) >> 42 ) | 0x80 );
996 buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x000003F800000000L ) >> 35 ) | 0x80 );
997 buffer[posBuffer + 3] = ( byte ) ( ( byte ) ( ( value & 0x00000007F0000000L ) >> 28 ) | 0x80 );
998 buffer[posBuffer + 4] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
999 buffer[posBuffer + 5] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
1000 buffer[posBuffer + 6] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
1001 buffer[posBuffer + 7] = ( byte ) ( value & 0x000000000000007FL );
1002
1003 return 8;
1004 }
1005 else
1006 {
1007
1008 buffer[posBuffer] = ( byte ) ( ( byte ) ( ( value & 0x7F00000000000000L ) >> 56 ) | 0x80 );
1009 buffer[posBuffer + 1] = ( byte ) ( ( byte ) ( ( value & 0x00FE000000000000L ) >> 49 ) | 0x80 );
1010 buffer[posBuffer + 2] = ( byte ) ( ( byte ) ( ( value & 0x0001FC0000000000L ) >> 42 ) | 0x80 );
1011 buffer[posBuffer + 3] = ( byte ) ( ( byte ) ( ( value & 0x000003F800000000L ) >> 35 ) | 0x80 );
1012 buffer[posBuffer + 4] = ( byte ) ( ( byte ) ( ( value & 0x00000007F0000000L ) >> 28 ) | 0x80 );
1013 buffer[posBuffer + 5] = ( byte ) ( ( byte ) ( ( value & 0x000000000FE00000L ) >> 21 ) | 0x80 );
1014 buffer[posBuffer + 6] = ( byte ) ( ( byte ) ( ( value & 0x00000000001FC000L ) >> 14 ) | 0x80 );
1015 buffer[posBuffer + 7] = ( byte ) ( ( byte ) ( ( value & 0x0000000000003F80L ) >> 7 ) | 0x80 );
1016 buffer[posBuffer + 8] = ( byte ) ( value & 0x000000000000007FL );
1017
1018 return 9;
1019 }
1020 }
1021 else
1022 {
1023
1024
1025 String number = oid.substring( start, start + nbDigits );
1026 BigInteger bigInteger = new BigInteger( number );
1027
1028 if ( isJointIsoItuT )
1029 {
1030 bigInteger = bigInteger.add( JOINT_ISO_ITU_T );
1031 posBuffer = 0;
1032 }
1033
1034 byte[] bytes = bigInteger.toByteArray();
1035
1036
1037
1038 int nbNeededBytes = ( bytes.length * 8 ) / 7;
1039
1040 switch ( ( bytes.length - 1 ) % 7 )
1041 {
1042 case 0 :
1043 if ( ( bytes[0] & 0x0080 ) != 0 )
1044 {
1045 nbNeededBytes++;
1046 }
1047
1048 break;
1049
1050 case 1 :
1051 if ( ( bytes[0] & 0x00C0 ) != 0 )
1052 {
1053 nbNeededBytes++;
1054 }
1055
1056 break;
1057
1058 case 2 :
1059 if ( ( bytes[0] & 0x00E0 ) != 0 )
1060 {
1061 nbNeededBytes++;
1062 }
1063
1064 break;
1065
1066 case 3 :
1067 if ( ( bytes[0] & 0x00F0 ) != 0 )
1068 {
1069 nbNeededBytes++;
1070 }
1071
1072 break;
1073
1074 case 4 :
1075 if ( ( bytes[0] & 0x00F8 ) != 0 )
1076 {
1077 nbNeededBytes++;
1078 }
1079
1080 break;
1081
1082 case 5 :
1083 if ( ( bytes[0] & 0x00FC ) != 0 )
1084 {
1085 nbNeededBytes++;
1086 }
1087
1088 break;
1089
1090 case 6 :
1091 if ( ( bytes[0] & 0x00FE ) != 0 )
1092 {
1093 nbNeededBytes++;
1094 }
1095
1096 break;
1097
1098 default :
1099
1100 break;
1101 }
1102
1103 byte[] converted = new byte[nbNeededBytes];
1104
1105 int posConverted = nbNeededBytes - 1;
1106 int posBytes = bytes.length - 1;
1107 int counter = 0;
1108 byte reminder = 0;
1109
1110 while ( posBytes >= 0 )
1111 {
1112 byte newByte = ( byte ) ( ( bytes[posBytes] & 0x00FF ) << counter );
1113 converted[posConverted] = ( byte ) ( reminder | newByte | 0x0080 );
1114 reminder = ( byte ) ( ( bytes[posBytes] & 0x00FF ) >> ( 7 - counter ) );
1115 counter = ( counter + 1 ) % 8;
1116 posConverted--;
1117
1118 if ( counter != 0 )
1119 {
1120 posBytes--;
1121 }
1122 else
1123 {
1124 reminder = 0;
1125 }
1126 }
1127
1128 converted[nbNeededBytes - 1] &= 0x7F;
1129
1130
1131 System.arraycopy( converted, 0, buffer, posBuffer, nbNeededBytes );
1132
1133 return nbNeededBytes;
1134 }
1135 }
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145 public static Oid fromString( String oidString ) throws DecoderException
1146 {
1147 if ( ( oidString == null ) || oidString.isEmpty() )
1148 {
1149 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "empty" ) );
1150 }
1151
1152
1153 byte[] buffer = new byte[oidString.length()];
1154
1155 OidFSAState state = OidFSAState.START;
1156
1157
1158 int arcNbChars = 0;
1159
1160
1161 int bufPos = 0;
1162
1163
1164 int startArc = 0;
1165
1166
1167 int nbBytes;
1168
1169 for ( int i = 0; i < oidString.length(); i++ )
1170 {
1171 switch ( state )
1172 {
1173 case START :
1174
1175
1176 state = processStateStart( oidString, buffer, i );
1177 break;
1178
1179 case STATE_A :
1180
1181 state = processStateA( oidString, i );
1182
1183
1184 break;
1185
1186 case STATE_B :
1187
1188
1189
1190 state = processStateB( oidString, buffer, i );
1191
1192 break;
1193
1194 case STATE_C :
1195
1196
1197 state = processStateC( oidString, buffer, i );
1198
1199
1200 bufPos = 1;
1201
1202 break;
1203
1204 case STATE_D :
1205
1206
1207
1208 case STATE_E :
1209
1210 state = processStateDE( oidString, buffer, i );
1211
1212
1213 bufPos = 1;
1214
1215 break;
1216
1217 case STATE_F :
1218
1219 state = processStateF( oidString, i );
1220
1221 break;
1222
1223 case STATE_G :
1224
1225
1226 state = processStateG( oidString, buffer, i );
1227 arcNbChars = 1;
1228 startArc = i;
1229
1230 break;
1231
1232 case STATE_H :
1233
1234
1235 state = processStateH( oidString, buffer, i );
1236
1237 if ( state == OidFSAState.STATE_J )
1238 {
1239
1240 arcNbChars = 2;
1241 bufPos = 0;
1242 }
1243
1244 break;
1245
1246 case STATE_I :
1247
1248 state = processStateI( oidString, buffer, i );
1249
1250
1251 bufPos = 1;
1252
1253 break;
1254
1255 case STATE_J :
1256
1257
1258 state = processStateJ( oidString, buffer, arcNbChars + bufPos, i );
1259
1260 if ( state == OidFSAState.STATE_J )
1261 {
1262
1263 arcNbChars++;
1264 }
1265 else
1266 {
1267
1268 bufPos += convert( oidString, buffer, bufPos, arcNbChars, 0, true );
1269 }
1270
1271 break;
1272
1273 case STATE_K :
1274 startArc = i;
1275 state = processStateK( oidString, buffer, bufPos, i );
1276
1277 if ( state == OidFSAState.STATE_M )
1278 {
1279 bufPos++;
1280 }
1281 else
1282 {
1283 arcNbChars = 1;
1284 }
1285
1286 break;
1287
1288 case STATE_L :
1289 state = processStateL( oidString, buffer, arcNbChars + bufPos, i );
1290
1291 if ( state == OidFSAState.STATE_L )
1292 {
1293 arcNbChars++;
1294 break;
1295 }
1296 else
1297 {
1298
1299 bufPos += convert( oidString, buffer, startArc, arcNbChars, bufPos, false );
1300 }
1301
1302 break;
1303
1304 case STATE_M :
1305 state = processStateM( oidString, i );
1306 break;
1307
1308 default :
1309
1310 break;
1311 }
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324 switch ( state )
1325 {
1326 case STATE_C :
1327
1328
1329
1330 case STATE_D :
1331
1332
1333
1334 case STATE_E :
1335
1336
1337
1338 case STATE_H :
1339
1340
1341
1342 case STATE_I :
1343
1344 byte[] bytes = new byte[1];
1345 bytes[0] = ( byte ) ( buffer[0] | buffer[1] );
1346
1347 return new Oid( oidString, bytes );
1348
1349 case STATE_J :
1350
1351 nbBytes = convert( oidString, buffer, 2, arcNbChars, 0, true );
1352 bytes = new byte[nbBytes];
1353 System.arraycopy( buffer, 0, bytes, 0, nbBytes );
1354
1355 return new Oid( oidString, bytes );
1356
1357 case STATE_L :
1358 bufPos += convert( oidString, buffer, startArc, arcNbChars, bufPos, false );
1359 bytes = new byte[bufPos];
1360 System.arraycopy( buffer, 0, bytes, 0, bufPos );
1361
1362 return new Oid( oidString, bytes );
1363
1364 case STATE_M :
1365 bytes = new byte[bufPos];
1366 System.arraycopy( buffer, 0, bytes, 0, bufPos );
1367
1368 return new Oid( oidString, bytes );
1369
1370 default :
1371
1372 throw new DecoderException( I18n.err( I18n.ERR_00003_INVALID_OID, "Wrong OID" ) );
1373 }
1374 }
1375
1376
1377
1378
1379
1380
1381
1382 public int getEncodedLength()
1383 {
1384 return oidBytes.length;
1385 }
1386
1387
1388
1389
1390
1391 @Override
1392 public int hashCode()
1393 {
1394 return oidString.hashCode();
1395 }
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408 public static boolean isOid( String oidString )
1409 {
1410 try
1411 {
1412 Oid.fromString( oidString );
1413
1414 return true;
1415 }
1416 catch ( DecoderException e )
1417 {
1418 return false;
1419 }
1420 }
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433 public byte[] toBytes()
1434 {
1435 return Arrays.copyOf( oidBytes, oidBytes.length );
1436 }
1437
1438
1439
1440
1441
1442
1443
1444 @Override
1445 public String toString()
1446 {
1447 return oidString;
1448 }
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458 public void writeBytesTo( ByteBuffer buffer )
1459 {
1460 buffer.put( oidBytes );
1461 }
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472 public void writeBytesTo( OutputStream outputStream ) throws IOException
1473 {
1474 outputStream.write( oidBytes );
1475 }
1476 }