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.ber.tlv;
21
22
23 import java.nio.BufferOverflowException;
24 import java.nio.ByteBuffer;
25
26 import org.apache.directory.api.asn1.EncoderException;
27 import org.apache.directory.api.asn1.util.Asn1StringUtils;
28 import org.apache.directory.api.asn1.util.BitString;
29 import org.apache.directory.api.asn1.util.Oid;
30 import org.apache.directory.api.i18n.I18n;
31
32
33
34
35
36
37
38 public class BerValue
39 {
40
41 private byte[] data;
42
43
44 private int currentPos;
45
46
47 public static final byte TRUE_VALUE = ( byte ) 0xFF;
48
49
50 public static final byte FALSE_VALUE = ( byte ) 0x00;
51
52
53 private static final byte[] ENCODED_TRUE = new byte[]
54 { 0x01, 0x01, TRUE_VALUE };
55
56
57 private static final byte[] ENCODED_FALSE = new byte[]
58 { 0x01, 0x01, FALSE_VALUE };
59
60
61 private static final int ONE_BYTE_MAX = ( 1 << 7 ) - 1;
62
63
64 private static final int ONE_BYTE_MIN = -( 1 << 7 );
65
66
67 private static final int TWO_BYTE_MAX = ( 1 << 15 ) - 1;
68
69
70 private static final int TWO_BYTE_MIN = -( 1 << 15 );
71
72
73 private static final int THREE_BYTE_MAX = ( 1 << 23 ) - 1;
74
75
76 private static final int THREE_BYTE_MIN = -( 1 << 23 );
77
78
79 private static final long FOUR_BYTE_MAX = ( 1L << 31 ) - 1L;
80
81
82 private static final long FOUR_BYTE_MIN = -( 1L << 31 );
83
84
85 private static final long FIVE_BYTE_MAX = ( 1L << 39 ) - 1L;
86
87
88 private static final long FIVE_BYTE_MIN = -( 1L << 39 );
89
90
91 private static final long SIX_BYTE_MAX = ( 1L << 47 ) - 1L;
92
93
94 private static final long SIX_BYTE_MIN = -( 1L << 47 );
95
96
97 private static final long SEVEN_BYTE_MAX = ( 1L << 55 ) - 1L;
98
99
100 private static final long SEVEN_BYTE_MIN = -( 1L << 55 );
101
102
103
104
105
106
107
108 public BerValue( byte[] value )
109 {
110
111 data = new byte[value.length];
112 System.arraycopy( value, 0, data, 0, value.length );
113 currentPos = 0;
114 }
115
116
117
118
119
120 public BerValue()
121 {
122 data = null;
123 currentPos = 0;
124 }
125
126
127
128
129
130
131
132 public void init( int size )
133 {
134 data = new byte[size];
135 currentPos = 0;
136 }
137
138
139
140
141
142 public void reset()
143 {
144 data = null;
145 currentPos = 0;
146 }
147
148
149
150
151
152
153
154 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="EI_EXPOSE_REP",
155 justification="The return of the direct value (without cloning) was intended. Even if we modify the interned value, it won't have any impact")
156 public byte[] getData()
157 {
158 return data;
159 }
160
161
162
163
164
165
166
167 public void setData( ByteBuffer data )
168 {
169 int length = data.remaining();
170 data.get( this.data, 0, length );
171 currentPos = length;
172 }
173
174
175
176
177
178
179
180 public void addData( ByteBuffer buffer )
181 {
182 int length = buffer.remaining();
183 buffer.get( data, currentPos, length );
184 currentPos += length;
185 }
186
187
188
189
190
191
192
193 public void setData( byte[] data )
194 {
195 System.arraycopy( data, 0, this.data, 0, data.length );
196 currentPos = data.length;
197 }
198
199
200
201
202
203
204
205 public void addData( byte[] array )
206 {
207 System.arraycopy( array, 0, this.data, currentPos, array.length );
208 currentPos = array.length;
209 }
210
211
212
213
214
215 public int getCurrentLength()
216 {
217 return currentPos;
218 }
219
220
221
222
223
224
225
226
227
228
229 public static int getNbBytes( int value )
230 {
231 if ( ( value >= ONE_BYTE_MIN ) && ( value <= ONE_BYTE_MAX ) )
232 {
233 return 1;
234 }
235 else if ( ( value >= TWO_BYTE_MIN ) && ( value <= TWO_BYTE_MAX ) )
236 {
237 return 2;
238 }
239 else if ( ( value >= THREE_BYTE_MIN ) && ( value <= THREE_BYTE_MAX ) )
240 {
241 return 3;
242 }
243 else
244 {
245 return 4;
246 }
247 }
248
249
250
251
252
253
254
255
256
257
258 public static int getNbBytes( long value )
259 {
260 if ( ( value >= ONE_BYTE_MIN ) && ( value <= ONE_BYTE_MAX ) )
261 {
262 return 1;
263 }
264 else if ( ( value >= TWO_BYTE_MIN ) && ( value <= TWO_BYTE_MAX ) )
265 {
266 return 2;
267 }
268 else if ( ( value >= THREE_BYTE_MIN ) && ( value <= THREE_BYTE_MAX ) )
269 {
270 return 3;
271 }
272 else if ( ( value >= FOUR_BYTE_MIN ) && ( value <= FOUR_BYTE_MAX ) )
273 {
274 return 4;
275 }
276 else if ( ( value >= FIVE_BYTE_MIN ) && ( value <= FIVE_BYTE_MAX ) )
277 {
278 return 5;
279 }
280 else if ( ( value >= SIX_BYTE_MIN ) && ( value <= SIX_BYTE_MAX ) )
281 {
282 return 6;
283 }
284 else if ( ( value >= SEVEN_BYTE_MIN ) && ( value <= SEVEN_BYTE_MAX ) )
285 {
286 return 7;
287 }
288 else
289 {
290 return 8;
291 }
292 }
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313 public static byte[] getBytes( int value )
314 {
315 byte[] bytes = null;
316
317 if ( value >= 0 )
318 {
319 if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) )
320 {
321 bytes = new byte[1];
322 bytes[0] = ( byte ) value;
323 }
324 else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) )
325 {
326 bytes = new byte[2];
327 bytes[1] = ( byte ) value;
328 bytes[0] = ( byte ) ( value >> 8 );
329 }
330 else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) )
331 {
332 bytes = new byte[3];
333 bytes[2] = ( byte ) value;
334 bytes[1] = ( byte ) ( value >> 8 );
335 bytes[0] = ( byte ) ( value >> 16 );
336 }
337 else
338 {
339 bytes = new byte[4];
340 bytes[3] = ( byte ) value;
341 bytes[2] = ( byte ) ( value >> 8 );
342 bytes[1] = ( byte ) ( value >> 16 );
343 bytes[0] = ( byte ) ( value >> 24 );
344 }
345 }
346 else
347 {
348
349 if ( value == 0x80000000 )
350 {
351 bytes = new byte[4];
352 bytes[3] = ( byte ) value;
353 bytes[2] = ( byte ) ( value >> 8 );
354 bytes[1] = ( byte ) ( value >> 16 );
355 bytes[0] = ( byte ) ( value >> 24 );
356 }
357 else
358 {
359
360
361
362 if ( value >= 0xFFFFFF80 )
363 {
364 bytes = new byte[1];
365 bytes[0] = ( byte ) value;
366 }
367 else if ( value >= 0xFFFF8000 )
368 {
369 bytes = new byte[2];
370 bytes[1] = ( byte ) ( value );
371 bytes[0] = ( byte ) ( value >> 8 );
372 }
373 else if ( value >= 0xFF800000 )
374 {
375 bytes = new byte[3];
376 bytes[2] = ( byte ) value;
377 bytes[1] = ( byte ) ( value >> 8 );
378 bytes[0] = ( byte ) ( value >> 16 );
379 }
380 else
381 {
382 bytes = new byte[4];
383 bytes[3] = ( byte ) value;
384 bytes[2] = ( byte ) ( value >> 8 );
385 bytes[1] = ( byte ) ( value >> 16 );
386 bytes[0] = ( byte ) ( value >> 24 );
387 }
388 }
389 }
390
391 return bytes;
392 }
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 public static byte[] getBytes( long value )
462 {
463 byte[] bytes = null;
464
465 if ( value >= 0 )
466 {
467 if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) )
468 {
469 bytes = new byte[1];
470 bytes[0] = ( byte ) value;
471 }
472 else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) )
473 {
474 bytes = new byte[2];
475 bytes[1] = ( byte ) value;
476 bytes[0] = ( byte ) ( value >> 8 );
477 }
478 else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) )
479 {
480 bytes = new byte[3];
481 bytes[2] = ( byte ) value;
482 bytes[1] = ( byte ) ( value >> 8 );
483 bytes[0] = ( byte ) ( value >> 16 );
484 }
485 else if ( ( value > THREE_BYTE_MAX ) && ( value <= FOUR_BYTE_MAX ) )
486 {
487 bytes = new byte[4];
488 bytes[3] = ( byte ) value;
489 bytes[2] = ( byte ) ( value >> 8 );
490 bytes[1] = ( byte ) ( value >> 16 );
491 bytes[0] = ( byte ) ( value >> 24 );
492 }
493 else if ( ( value > FOUR_BYTE_MAX ) && ( value <= FIVE_BYTE_MAX ) )
494 {
495 bytes = new byte[5];
496 bytes[4] = ( byte ) value;
497 bytes[3] = ( byte ) ( value >> 8 );
498 bytes[2] = ( byte ) ( value >> 16 );
499 bytes[1] = ( byte ) ( value >> 24 );
500 bytes[0] = ( byte ) ( value >> 32 );
501 }
502 else if ( ( value > FIVE_BYTE_MAX ) && ( value <= SIX_BYTE_MAX ) )
503 {
504 bytes = new byte[6];
505 bytes[5] = ( byte ) value;
506 bytes[4] = ( byte ) ( value >> 8 );
507 bytes[3] = ( byte ) ( value >> 16 );
508 bytes[2] = ( byte ) ( value >> 24 );
509 bytes[1] = ( byte ) ( value >> 32 );
510 bytes[0] = ( byte ) ( value >> 40 );
511 }
512 else if ( ( value > SIX_BYTE_MAX ) && ( value <= SEVEN_BYTE_MAX ) )
513 {
514 bytes = new byte[7];
515 bytes[6] = ( byte ) value;
516 bytes[5] = ( byte ) ( value >> 8 );
517 bytes[4] = ( byte ) ( value >> 16 );
518 bytes[3] = ( byte ) ( value >> 24 );
519 bytes[2] = ( byte ) ( value >> 32 );
520 bytes[1] = ( byte ) ( value >> 40 );
521 bytes[0] = ( byte ) ( value >> 48 );
522 }
523 else
524 {
525 bytes = new byte[8];
526 bytes[7] = ( byte ) value;
527 bytes[6] = ( byte ) ( value >> 8 );
528 bytes[5] = ( byte ) ( value >> 16 );
529 bytes[4] = ( byte ) ( value >> 24 );
530 bytes[3] = ( byte ) ( value >> 32 );
531 bytes[2] = ( byte ) ( value >> 40 );
532 bytes[1] = ( byte ) ( value >> 48 );
533 bytes[0] = ( byte ) ( value >> 56 );
534 }
535 }
536 else
537 {
538
539 if ( value == 0x8000000000000000L )
540 {
541 bytes = new byte[8];
542 bytes[7] = ( byte ) 0x00;
543 bytes[6] = ( byte ) 0x00;
544 bytes[5] = ( byte ) 0x00;
545 bytes[4] = ( byte ) 0x00;
546 bytes[3] = ( byte ) 0x00;
547 bytes[2] = ( byte ) 0x00;
548 bytes[1] = ( byte ) 0x00;
549 bytes[0] = ( byte ) 0x80;
550 }
551 else
552 {
553
554
555
556 if ( value >= 0xFFFFFFFFFFFFFF80L )
557 {
558 bytes = new byte[1];
559 bytes[0] = ( byte ) value;
560 }
561 else if ( value >= 0xFFFFFFFFFFFF8000L )
562 {
563 bytes = new byte[2];
564 bytes[1] = ( byte ) ( value );
565 bytes[0] = ( byte ) ( value >> 8 );
566 }
567 else if ( value >= 0xFFFFFFFFFF800000L )
568 {
569 bytes = new byte[3];
570 bytes[2] = ( byte ) value;
571 bytes[1] = ( byte ) ( value >> 8 );
572 bytes[0] = ( byte ) ( value >> 16 );
573 }
574 else if ( value >= 0xFFFFFFFF80000000L )
575 {
576 bytes = new byte[4];
577 bytes[3] = ( byte ) value;
578 bytes[2] = ( byte ) ( value >> 8 );
579 bytes[1] = ( byte ) ( value >> 16 );
580 bytes[0] = ( byte ) ( value >> 24 );
581 }
582 else if ( value >= 0xFFFFFF8000000000L )
583 {
584 bytes = new byte[5];
585 bytes[4] = ( byte ) value;
586 bytes[3] = ( byte ) ( value >> 8 );
587 bytes[2] = ( byte ) ( value >> 16 );
588 bytes[1] = ( byte ) ( value >> 24 );
589 bytes[0] = ( byte ) ( value >> 32 );
590 }
591 else if ( value >= 0xFFFF800000000000L )
592 {
593 bytes = new byte[6];
594 bytes[5] = ( byte ) value;
595 bytes[4] = ( byte ) ( value >> 8 );
596 bytes[3] = ( byte ) ( value >> 16 );
597 bytes[2] = ( byte ) ( value >> 24 );
598 bytes[1] = ( byte ) ( value >> 32 );
599 bytes[0] = ( byte ) ( value >> 40 );
600 }
601 else if ( value >= 0xFF80000000000000L )
602 {
603 bytes = new byte[7];
604 bytes[6] = ( byte ) value;
605 bytes[5] = ( byte ) ( value >> 8 );
606 bytes[4] = ( byte ) ( value >> 16 );
607 bytes[3] = ( byte ) ( value >> 24 );
608 bytes[2] = ( byte ) ( value >> 32 );
609 bytes[1] = ( byte ) ( value >> 40 );
610 bytes[0] = ( byte ) ( value >> 48 );
611 }
612 else
613 {
614 bytes = new byte[8];
615 bytes[7] = ( byte ) value;
616 bytes[6] = ( byte ) ( value >> 8 );
617 bytes[5] = ( byte ) ( value >> 16 );
618 bytes[4] = ( byte ) ( value >> 24 );
619 bytes[3] = ( byte ) ( value >> 32 );
620 bytes[2] = ( byte ) ( value >> 40 );
621 bytes[1] = ( byte ) ( value >> 48 );
622 bytes[0] = ( byte ) ( value >> 56 );
623 }
624 }
625 }
626
627 return bytes;
628 }
629
630
631
632
633
634
635
636
637
638
639 public static void encode( ByteBuffer buffer, String string ) throws EncoderException
640 {
641 if ( buffer == null )
642 {
643 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
644 }
645
646 try
647 {
648 buffer.put( UniversalTag.OCTET_STRING.getValue() );
649
650 byte[] value = Asn1StringUtils.getBytesUtf8( string );
651
652 buffer.put( TLV.getBytes( value.length ) );
653
654 if ( value.length != 0 )
655 {
656 buffer.put( value );
657 }
658 }
659 catch ( BufferOverflowException boe )
660 {
661 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
662 }
663 }
664
665
666
667
668
669
670
671
672
673
674 public static void encode( ByteBuffer buffer, BitString bitString ) throws EncoderException
675 {
676 if ( buffer == null )
677 {
678 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
679 }
680
681 try
682 {
683 buffer.put( UniversalTag.BIT_STRING.getValue() );
684
685
686
687 byte[] bytes = bitString.getData();
688 int length = bytes.length;
689
690 buffer.put( TLV.getBytes( length ) );
691 buffer.put( bytes );
692 }
693 catch ( BufferOverflowException boe )
694 {
695 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
696 }
697 }
698
699
700
701
702
703
704
705
706
707
708 public static void encode( ByteBuffer buffer, byte[] bytes ) throws EncoderException
709 {
710 if ( buffer == null )
711 {
712 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
713 }
714
715 try
716 {
717 buffer.put( UniversalTag.OCTET_STRING.getValue() );
718
719 if ( ( bytes == null ) || ( bytes.length == 0 ) )
720 {
721 buffer.put( ( byte ) 0 );
722 }
723 else
724 {
725 buffer.put( TLV.getBytes( bytes.length ) );
726 buffer.put( bytes );
727 }
728 }
729 catch ( BufferOverflowException boe )
730 {
731 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
732 }
733 }
734
735
736
737
738
739
740
741
742
743
744 public static void encode( ByteBuffer buffer, Oid oid ) throws EncoderException
745 {
746 if ( buffer == null )
747 {
748 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
749 }
750
751 try
752 {
753 buffer.put( UniversalTag.OCTET_STRING.getValue() );
754 buffer.put( TLV.getBytes( oid.getEncodedLength() ) );
755
756 if ( oid.getEncodedLength() != 0 )
757 {
758 oid.writeBytesTo( buffer );
759 }
760 }
761 catch ( BufferOverflowException boe )
762 {
763 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
764 }
765 }
766
767
768
769
770
771
772
773
774
775
776 public static void encode( ByteBuffer buffer, int value ) throws EncoderException
777 {
778 if ( buffer == null )
779 {
780 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
781 }
782
783 try
784 {
785 buffer.put( UniversalTag.INTEGER.getValue() );
786 buffer.put( ( byte ) getNbBytes( value ) );
787 buffer.put( getBytes( value ) );
788 }
789 catch ( BufferOverflowException boe )
790 {
791 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
792 }
793 }
794
795
796
797
798
799
800
801
802
803
804 public static void encode( ByteBuffer buffer, long value ) throws EncoderException
805 {
806 if ( buffer == null )
807 {
808 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
809 }
810
811 try
812 {
813 buffer.put( UniversalTag.INTEGER.getValue() );
814 buffer.put( ( byte ) getNbBytes( value ) );
815 buffer.put( getBytes( value ) );
816 }
817 catch ( BufferOverflowException boe )
818 {
819 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
820 }
821 }
822
823
824
825
826
827
828
829
830
831
832
833 public static void encode( ByteBuffer buffer, byte tag, int value ) throws EncoderException
834 {
835 if ( buffer == null )
836 {
837 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
838 }
839
840 try
841 {
842 buffer.put( tag );
843 buffer.put( ( byte ) getNbBytes( value ) );
844 buffer.put( getBytes( value ) );
845 }
846 catch ( BufferOverflowException boe )
847 {
848 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
849 }
850 }
851
852
853
854
855
856
857
858
859
860
861 public static void encodeEnumerated( ByteBuffer buffer, int value ) throws EncoderException
862 {
863 if ( buffer == null )
864 {
865 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
866 }
867
868 try
869 {
870 buffer.put( UniversalTag.ENUMERATED.getValue() );
871 buffer.put( TLV.getBytes( getNbBytes( value ) ) );
872 buffer.put( getBytes( value ) );
873 }
874 catch ( BufferOverflowException boe )
875 {
876 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
877 }
878 }
879
880
881
882
883
884
885
886
887
888
889 public static void encode( ByteBuffer buffer, boolean bool ) throws EncoderException
890 {
891 if ( buffer == null )
892 {
893 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
894 }
895
896 try
897 {
898 if ( bool )
899 {
900 buffer.put( ENCODED_TRUE );
901 }
902 else
903 {
904 buffer.put( ENCODED_FALSE );
905 }
906 }
907 catch ( BufferOverflowException boe )
908 {
909 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
910 }
911 }
912
913
914
915
916
917
918
919 @Override
920 public String toString()
921 {
922 StringBuilder sb = new StringBuilder();
923 sb.append( "DATA" );
924
925 if ( data != null )
926 {
927 sb.append( '[' );
928 sb.append( Asn1StringUtils.dumpBytes( data ) );
929 sb.append( ']' );
930 }
931 else
932 {
933 return "[]";
934 }
935
936 return sb.toString();
937 }
938 }