001/* 002 * Copyright 2007-2017 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2008-2017 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.asn1; 022 023 024 025import java.io.InputStream; 026import java.io.IOException; 027import java.io.OutputStream; 028import java.io.Serializable; 029import java.util.Arrays; 030 031import com.unboundid.util.ByteStringBuffer; 032import com.unboundid.util.NotExtensible; 033import com.unboundid.util.NotMutable; 034import com.unboundid.util.ThreadSafety; 035import com.unboundid.util.ThreadSafetyLevel; 036 037import static com.unboundid.asn1.ASN1Constants.*; 038import static com.unboundid.asn1.ASN1Messages.*; 039import static com.unboundid.util.Debug.*; 040import static com.unboundid.util.StaticUtils.*; 041 042 043 044/** 045 * This class defines a generic ASN.1 BER element, which has a type and value. 046 * It provides a framework for encoding and decoding BER elements, both as 047 * generic elements and more specific subtypes. 048 */ 049@NotExtensible() 050@NotMutable() 051@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 052public class ASN1Element 053 implements Serializable 054{ 055 /** 056 * The serial version UID for this serializable class. 057 */ 058 private static final long serialVersionUID = -1871166128693521335L; 059 060 061 062 // The BER type for this element. 063 private final byte type; 064 065 // The encoded value for this element. 066 private final byte[] value; 067 068 // The cached hashCode for this element. 069 private int hashCode = -1; 070 071 // The number of bytes contained in the value. 072 private final int valueLength; 073 074 // The offset within the value array at which the value begins. 075 private final int valueOffset; 076 077 078 079 /** 080 * Creates a new ASN.1 BER element with the specified type and no value. 081 * 082 * @param type The BER type for this element. 083 */ 084 public ASN1Element(final byte type) 085 { 086 this.type = type; 087 value = NO_VALUE; 088 valueOffset = 0; 089 valueLength = 0; 090 } 091 092 093 094 /** 095 * Creates a new ASN1 BER element with the specified type and value. 096 * 097 * @param type The BER type for this element. 098 * @param value The encoded value for this element. 099 */ 100 public ASN1Element(final byte type, final byte[] value) 101 { 102 this.type = type; 103 104 if (value == null) 105 { 106 this.value = NO_VALUE; 107 } 108 else 109 { 110 this.value = value; 111 } 112 113 valueOffset = 0; 114 valueLength = this.value.length; 115 } 116 117 118 119 /** 120 * Creates a new ASN1 BER element with the specified type and value. 121 * 122 * @param type The BER type for this element. 123 * @param value The array containing the encoded value for this element. 124 * It must not be {@code null}. 125 * @param offset The offset within the array at which the value begins. 126 * @param length The number of bytes contained in the value. 127 */ 128 public ASN1Element(final byte type, final byte[] value, final int offset, 129 final int length) 130 { 131 this.type = type; 132 this.value = value; 133 134 valueOffset = offset; 135 valueLength = length; 136 } 137 138 139 140 /** 141 * Retrieves the BER type for this element. 142 * 143 * @return The BER type for this element. 144 */ 145 public final byte getType() 146 { 147 return type; 148 } 149 150 151 152 /** 153 * Retrieves the array containing the value. The returned array may be 154 * larger than the actual value, so it must be used in conjunction with the 155 * values returned by the {@link #getValueOffset} and {@link #getValueLength} 156 * methods. 157 * 158 * @return The array containing the value. 159 */ 160 byte[] getValueArray() 161 { 162 return value; 163 } 164 165 166 167 /** 168 * Retrieves the position in the value array at which the value actually 169 * begins. 170 * 171 * @return The position in the value array at which the value actually 172 * begins. 173 */ 174 int getValueOffset() 175 { 176 return valueOffset; 177 } 178 179 180 181 /** 182 * Retrieves the number of bytes contained in the value. 183 * 184 * @return The number of bytes contained in the value. 185 */ 186 public int getValueLength() 187 { 188 return valueLength; 189 } 190 191 192 193 /** 194 * Retrieves the encoded value for this element. 195 * 196 * @return The encoded value for this element. 197 */ 198 public byte[] getValue() 199 { 200 if ((valueOffset == 0) && (valueLength == value.length)) 201 { 202 return value; 203 } 204 else 205 { 206 final byte[] returnValue = new byte[valueLength]; 207 System.arraycopy(value, valueOffset, returnValue, 0, valueLength); 208 return returnValue; 209 } 210 } 211 212 213 214 /** 215 * Encodes this ASN.1 element to a byte array. 216 * 217 * @return A byte array containing the encoded representation of this ASN.1 218 * element. 219 */ 220 public final byte[] encode() 221 { 222 final byte[] valueArray = getValueArray(); 223 final int length = getValueLength(); 224 final int offset = getValueOffset(); 225 226 if (length == 0) 227 { 228 return new byte[] { type, 0x00 }; 229 } 230 231 final byte[] lengthBytes = encodeLength(length); 232 final byte[] elementBytes = new byte[1 + lengthBytes.length + length]; 233 234 elementBytes[0] = type; 235 System.arraycopy(lengthBytes, 0, elementBytes, 1, lengthBytes.length); 236 System.arraycopy(valueArray, offset, elementBytes, 1+lengthBytes.length, 237 length); 238 239 return elementBytes; 240 } 241 242 243 244 /** 245 * Encodes the provided length to the given buffer. 246 * 247 * @param length The length to be encoded. 248 * @param buffer The buffer to which the length should be appended. 249 */ 250 static void encodeLengthTo(final int length, final ByteStringBuffer buffer) 251 { 252 if ((length & 0x7F) == length) 253 { 254 buffer.append((byte) length); 255 } 256 else if ((length & 0xFF) == length) 257 { 258 buffer.append((byte) 0x81); 259 buffer.append((byte) (length & 0xFF)); 260 } 261 else if ((length & 0xFFFF) == length) 262 { 263 buffer.append((byte) 0x82); 264 buffer.append((byte) ((length >> 8) & 0xFF)); 265 buffer.append((byte) (length & 0xFF)); 266 } 267 else if ((length & 0xFFFFFF) == length) 268 { 269 buffer.append((byte) 0x83); 270 buffer.append((byte) ((length >> 16) & 0xFF)); 271 buffer.append((byte) ((length >> 8) & 0xFF)); 272 buffer.append((byte) (length & 0xFF)); 273 } 274 else 275 { 276 buffer.append((byte) 0x84); 277 buffer.append((byte) ((length >> 24) & 0xFF)); 278 buffer.append((byte) ((length >> 16) & 0xFF)); 279 buffer.append((byte) ((length >> 8) & 0xFF)); 280 buffer.append((byte) (length & 0xFF)); 281 } 282 } 283 284 285 286 /** 287 * Appends an encoded representation of this ASN.1 element to the provided 288 * buffer. 289 * 290 * @param buffer The buffer to which the encoded representation should be 291 * appended. 292 */ 293 public void encodeTo(final ByteStringBuffer buffer) 294 { 295 final byte[] valueArray = getValueArray(); 296 final int length = getValueLength(); 297 final int offset = getValueOffset(); 298 299 buffer.append(type); 300 if (length == 0) 301 { 302 buffer.append((byte) 0x00); 303 } 304 else 305 { 306 encodeLengthTo(length, buffer); 307 buffer.append(valueArray, offset, length); 308 } 309 } 310 311 312 313 /** 314 * Encodes the provided length to a byte array. 315 * 316 * @param length The length to be encoded. 317 * 318 * @return A byte array containing the encoded length. 319 */ 320 public static byte[] encodeLength(final int length) 321 { 322 switch (length) 323 { 324 case 0: return LENGTH_0; 325 case 1: return LENGTH_1; 326 case 2: return LENGTH_2; 327 case 3: return LENGTH_3; 328 case 4: return LENGTH_4; 329 case 5: return LENGTH_5; 330 case 6: return LENGTH_6; 331 case 7: return LENGTH_7; 332 case 8: return LENGTH_8; 333 case 9: return LENGTH_9; 334 case 10: return LENGTH_10; 335 case 11: return LENGTH_11; 336 case 12: return LENGTH_12; 337 case 13: return LENGTH_13; 338 case 14: return LENGTH_14; 339 case 15: return LENGTH_15; 340 case 16: return LENGTH_16; 341 case 17: return LENGTH_17; 342 case 18: return LENGTH_18; 343 case 19: return LENGTH_19; 344 case 20: return LENGTH_20; 345 case 21: return LENGTH_21; 346 case 22: return LENGTH_22; 347 case 23: return LENGTH_23; 348 case 24: return LENGTH_24; 349 case 25: return LENGTH_25; 350 case 26: return LENGTH_26; 351 case 27: return LENGTH_27; 352 case 28: return LENGTH_28; 353 case 29: return LENGTH_29; 354 case 30: return LENGTH_30; 355 case 31: return LENGTH_31; 356 case 32: return LENGTH_32; 357 case 33: return LENGTH_33; 358 case 34: return LENGTH_34; 359 case 35: return LENGTH_35; 360 case 36: return LENGTH_36; 361 case 37: return LENGTH_37; 362 case 38: return LENGTH_38; 363 case 39: return LENGTH_39; 364 case 40: return LENGTH_40; 365 case 41: return LENGTH_41; 366 case 42: return LENGTH_42; 367 case 43: return LENGTH_43; 368 case 44: return LENGTH_44; 369 case 45: return LENGTH_45; 370 case 46: return LENGTH_46; 371 case 47: return LENGTH_47; 372 case 48: return LENGTH_48; 373 case 49: return LENGTH_49; 374 case 50: return LENGTH_50; 375 case 51: return LENGTH_51; 376 case 52: return LENGTH_52; 377 case 53: return LENGTH_53; 378 case 54: return LENGTH_54; 379 case 55: return LENGTH_55; 380 case 56: return LENGTH_56; 381 case 57: return LENGTH_57; 382 case 58: return LENGTH_58; 383 case 59: return LENGTH_59; 384 case 60: return LENGTH_60; 385 case 61: return LENGTH_61; 386 case 62: return LENGTH_62; 387 case 63: return LENGTH_63; 388 case 64: return LENGTH_64; 389 case 65: return LENGTH_65; 390 case 66: return LENGTH_66; 391 case 67: return LENGTH_67; 392 case 68: return LENGTH_68; 393 case 69: return LENGTH_69; 394 case 70: return LENGTH_70; 395 case 71: return LENGTH_71; 396 case 72: return LENGTH_72; 397 case 73: return LENGTH_73; 398 case 74: return LENGTH_74; 399 case 75: return LENGTH_75; 400 case 76: return LENGTH_76; 401 case 77: return LENGTH_77; 402 case 78: return LENGTH_78; 403 case 79: return LENGTH_79; 404 case 80: return LENGTH_80; 405 case 81: return LENGTH_81; 406 case 82: return LENGTH_82; 407 case 83: return LENGTH_83; 408 case 84: return LENGTH_84; 409 case 85: return LENGTH_85; 410 case 86: return LENGTH_86; 411 case 87: return LENGTH_87; 412 case 88: return LENGTH_88; 413 case 89: return LENGTH_89; 414 case 90: return LENGTH_90; 415 case 91: return LENGTH_91; 416 case 92: return LENGTH_92; 417 case 93: return LENGTH_93; 418 case 94: return LENGTH_94; 419 case 95: return LENGTH_95; 420 case 96: return LENGTH_96; 421 case 97: return LENGTH_97; 422 case 98: return LENGTH_98; 423 case 99: return LENGTH_99; 424 case 100: return LENGTH_100; 425 case 101: return LENGTH_101; 426 case 102: return LENGTH_102; 427 case 103: return LENGTH_103; 428 case 104: return LENGTH_104; 429 case 105: return LENGTH_105; 430 case 106: return LENGTH_106; 431 case 107: return LENGTH_107; 432 case 108: return LENGTH_108; 433 case 109: return LENGTH_109; 434 case 110: return LENGTH_110; 435 case 111: return LENGTH_111; 436 case 112: return LENGTH_112; 437 case 113: return LENGTH_113; 438 case 114: return LENGTH_114; 439 case 115: return LENGTH_115; 440 case 116: return LENGTH_116; 441 case 117: return LENGTH_117; 442 case 118: return LENGTH_118; 443 case 119: return LENGTH_119; 444 case 120: return LENGTH_120; 445 case 121: return LENGTH_121; 446 case 122: return LENGTH_122; 447 case 123: return LENGTH_123; 448 case 124: return LENGTH_124; 449 case 125: return LENGTH_125; 450 case 126: return LENGTH_126; 451 case 127: return LENGTH_127; 452 } 453 454 if ((length & 0x000000FF) == length) 455 { 456 return new byte[] 457 { 458 (byte) 0x81, 459 (byte) (length & 0xFF) 460 }; 461 } 462 else if ((length & 0x0000FFFF) == length) 463 { 464 return new byte[] 465 { 466 (byte) 0x82, 467 (byte) ((length >> 8) & 0xFF), 468 (byte) (length & 0xFF) 469 }; 470 } 471 else if ((length & 0x00FFFFFF) == length) 472 { 473 return new byte[] 474 { 475 (byte) 0x83, 476 (byte) ((length >> 16) & 0xFF), 477 (byte) ((length >> 8) & 0xFF), 478 (byte) (length & 0xFF) 479 }; 480 } 481 else 482 { 483 return new byte[] 484 { 485 (byte) 0x84, 486 (byte) ((length >> 24) & 0xFF), 487 (byte) ((length >> 16) & 0xFF), 488 (byte) ((length >> 8) & 0xFF), 489 (byte) (length & 0xFF) 490 }; 491 } 492 } 493 494 495 496 /** 497 * Decodes the content in the provided byte array as an ASN.1 element. 498 * 499 * @param elementBytes The byte array containing the data to decode. 500 * 501 * @return The decoded ASN.1 BER element. 502 * 503 * @throws ASN1Exception If the provided byte array does not represent a 504 * valid ASN.1 element. 505 */ 506 public static ASN1Element decode(final byte[] elementBytes) 507 throws ASN1Exception 508 { 509 try 510 { 511 int valueStartPos = 2; 512 int length = (elementBytes[1] & 0x7F); 513 if (length != elementBytes[1]) 514 { 515 final int numLengthBytes = length; 516 517 length = 0; 518 for (int i=0; i < numLengthBytes; i++) 519 { 520 length <<= 8; 521 length |= (elementBytes[valueStartPos++] & 0xFF); 522 } 523 } 524 525 if ((elementBytes.length - valueStartPos) != length) 526 { 527 throw new ASN1Exception(ERR_ELEMENT_LENGTH_MISMATCH.get(length, 528 (elementBytes.length - valueStartPos))); 529 } 530 531 final byte[] value = new byte[length]; 532 System.arraycopy(elementBytes, valueStartPos, value, 0, length); 533 return new ASN1Element(elementBytes[0], value); 534 } 535 catch (final ASN1Exception ae) 536 { 537 debugException(ae); 538 throw ae; 539 } 540 catch (final Exception e) 541 { 542 debugException(e); 543 throw new ASN1Exception(ERR_ELEMENT_DECODE_EXCEPTION.get(e), e); 544 } 545 } 546 547 548 549 /** 550 * Decodes this ASN.1 element as a Boolean element. 551 * 552 * @return The decoded Boolean element. 553 * 554 * @throws ASN1Exception If this element cannot be decoded as a Boolean 555 * element. 556 */ 557 public final ASN1Boolean decodeAsBoolean() 558 throws ASN1Exception 559 { 560 return ASN1Boolean.decodeAsBoolean(this); 561 } 562 563 564 565 /** 566 * Decodes this ASN.1 element as an enumerated element. 567 * 568 * @return The decoded enumerated element. 569 * 570 * @throws ASN1Exception If this element cannot be decoded as an enumerated 571 * element. 572 */ 573 public final ASN1Enumerated decodeAsEnumerated() 574 throws ASN1Exception 575 { 576 return ASN1Enumerated.decodeAsEnumerated(this); 577 } 578 579 580 581 /** 582 * Decodes this ASN.1 element as an integer element. 583 * 584 * @return The decoded integer element. 585 * 586 * @throws ASN1Exception If this element cannot be decoded as an integer 587 * element. 588 */ 589 public final ASN1Integer decodeAsInteger() 590 throws ASN1Exception 591 { 592 return ASN1Integer.decodeAsInteger(this); 593 } 594 595 596 597 /** 598 * Decodes this ASN.1 element as a long element. 599 * 600 * @return The decoded long element. 601 * 602 * @throws ASN1Exception If this element cannot be decoded as a long 603 * element. 604 */ 605 public final ASN1Long decodeAsLong() 606 throws ASN1Exception 607 { 608 return ASN1Long.decodeAsLong(this); 609 } 610 611 612 613 /** 614 * Decodes this ASN.1 element as a null element. 615 * 616 * @return The decoded null element. 617 * 618 * @throws ASN1Exception If this element cannot be decoded as a null 619 * element. 620 */ 621 public final ASN1Null decodeAsNull() 622 throws ASN1Exception 623 { 624 return ASN1Null.decodeAsNull(this); 625 } 626 627 628 629 /** 630 * Decodes this ASN.1 element as an octet string element. 631 * 632 * @return The decoded octet string element. 633 */ 634 public final ASN1OctetString decodeAsOctetString() 635 { 636 return ASN1OctetString.decodeAsOctetString(this); 637 } 638 639 640 641 /** 642 * Decodes this ASN.1 element as a sequence element. 643 * 644 * @return The decoded sequence element. 645 * 646 * @throws ASN1Exception If this element cannot be decoded as a sequence 647 * element. 648 */ 649 public final ASN1Sequence decodeAsSequence() 650 throws ASN1Exception 651 { 652 return ASN1Sequence.decodeAsSequence(this); 653 } 654 655 656 657 /** 658 * Decodes this ASN.1 element as a set element. 659 * 660 * @return The decoded set element. 661 * 662 * @throws ASN1Exception If this element cannot be decoded as a set 663 * element. 664 */ 665 public final ASN1Set decodeAsSet() 666 throws ASN1Exception 667 { 668 return ASN1Set.decodeAsSet(this); 669 } 670 671 672 673 /** 674 * Reads an ASN.1 element from the provided input stream. 675 * 676 * @param inputStream The input stream from which to read the element. 677 * 678 * @return The element read from the input stream, or {@code null} if the end 679 * of the input stream is reached without reading any data. 680 * 681 * @throws IOException If a problem occurs while attempting to read from the 682 * input stream. 683 * 684 * @throws ASN1Exception If a problem occurs while attempting to decode the 685 * element. 686 */ 687 public static ASN1Element readFrom(final InputStream inputStream) 688 throws IOException, ASN1Exception 689 { 690 return readFrom(inputStream, -1); 691 } 692 693 694 695 /** 696 * Reads an ASN.1 element from the provided input stream. 697 * 698 * @param inputStream The input stream from which to read the element. 699 * @param maxSize The maximum value size in bytes that will be allowed. 700 * A value less than or equal to zero indicates that no 701 * maximum size should be enforced. An attempt to read 702 * an element with a value larger than this will cause an 703 * {@code ASN1Exception} to be thrown. 704 * 705 * @return The element read from the input stream, or {@code null} if the end 706 * of the input stream is reached without reading any data. 707 * 708 * @throws IOException If a problem occurs while attempting to read from the 709 * input stream. 710 * 711 * @throws ASN1Exception If a problem occurs while attempting to decode the 712 * element. 713 */ 714 public static ASN1Element readFrom(final InputStream inputStream, 715 final int maxSize) 716 throws IOException, ASN1Exception 717 { 718 final int typeInt = inputStream.read(); 719 if (typeInt < 0) 720 { 721 return null; 722 } 723 724 final byte type = (byte) typeInt; 725 726 int length = inputStream.read(); 727 if (length < 0) 728 { 729 throw new ASN1Exception(ERR_READ_END_BEFORE_FIRST_LENGTH.get()); 730 } 731 else if (length > 127) 732 { 733 final int numLengthBytes = length & 0x7F; 734 length = 0; 735 if ((numLengthBytes < 1) || (numLengthBytes > 4)) 736 { 737 throw new ASN1Exception(ERR_READ_LENGTH_TOO_LONG.get(numLengthBytes)); 738 } 739 740 for (int i=0; i < numLengthBytes; i++) 741 { 742 final int lengthInt = inputStream.read(); 743 if (lengthInt < 0) 744 { 745 throw new ASN1Exception(ERR_READ_END_BEFORE_LENGTH_END.get()); 746 } 747 748 length <<= 8; 749 length |= (lengthInt & 0xFF); 750 } 751 } 752 753 if ((length < 0) || ((maxSize > 0) && (length > maxSize))) 754 { 755 throw new ASN1Exception(ERR_READ_LENGTH_EXCEEDS_MAX.get(length, maxSize)); 756 } 757 758 int totalBytesRead = 0; 759 int bytesRemaining = length; 760 final byte[] value = new byte[length]; 761 while (totalBytesRead < length) 762 { 763 final int bytesRead = 764 inputStream.read(value, totalBytesRead, bytesRemaining); 765 if (bytesRead < 0) 766 { 767 throw new ASN1Exception(ERR_READ_END_BEFORE_VALUE_END.get()); 768 } 769 770 totalBytesRead += bytesRead; 771 bytesRemaining -= bytesRead; 772 } 773 774 final ASN1Element e = new ASN1Element(type, value); 775 debugASN1Read(e); 776 return e; 777 } 778 779 780 781 /** 782 * Writes an encoded representation of this ASN.1 element to the provided 783 * output stream. 784 * 785 * @param outputStream The output stream to which the element should be 786 * written. 787 * 788 * @return The total number of bytes written to the output stream. 789 * 790 * @throws IOException If a problem occurs while attempting to write to the 791 * provided output stream. 792 * 793 * @see ASN1Writer#writeElement(ASN1Element,OutputStream) 794 */ 795 public final int writeTo(final OutputStream outputStream) 796 throws IOException 797 { 798 debugASN1Write(this); 799 800 final ByteStringBuffer buffer = new ByteStringBuffer(); 801 encodeTo(buffer); 802 buffer.write(outputStream); 803 return buffer.length(); 804 } 805 806 807 808 /** 809 * Retrieves a hash code for this ASN.1 BER element. 810 * 811 * @return A hash code for this ASN.1 BER element. 812 */ 813 @Override() 814 public final int hashCode() 815 { 816 if (hashCode == -1) 817 { 818 int hash = 0; 819 for (final byte b : getValue()) 820 { 821 hash = hash * 31 + b; 822 } 823 hashCode = hash; 824 } 825 826 return hashCode; 827 } 828 829 830 831 /** 832 * Indicates whether the provided object is equal to this ASN.1 BER element. 833 * The object will only be considered equal to this ASN.1 element if it is a 834 * non-null ASN.1 element with the same type and value as this element. 835 * 836 * @param o The object for which to make the determination. 837 * 838 * @return {@code true} if the provided object is considered equal to this 839 * ASN.1 element, or {@code false} if not. 840 */ 841 @Override() 842 public final boolean equals(final Object o) 843 { 844 if (o == null) 845 { 846 return false; 847 } 848 849 if (o == this) 850 { 851 return true; 852 } 853 854 try 855 { 856 final ASN1Element e = (ASN1Element) o; 857 return ((type == e.getType()) && Arrays.equals(getValue(), e.getValue())); 858 } 859 catch (final Exception e) 860 { 861 debugException(e); 862 return false; 863 } 864 } 865 866 867 868 /** 869 * Indicates whether the provided ASN.1 element is equal to this element, 870 * ignoring any potential difference in the BER type. 871 * 872 * @param element The ASN.1 BER element for which to make the determination. 873 * 874 * @return {@code true} if the provided ASN.1 element is considered equal to 875 * this element (ignoring type differences), or {@code false} if not. 876 */ 877 public final boolean equalsIgnoreType(final ASN1Element element) 878 { 879 if (element == null) 880 { 881 return false; 882 } 883 884 if (element == this) 885 { 886 return true; 887 } 888 889 return Arrays.equals(getValue(), element.getValue()); 890 } 891 892 893 894 /** 895 * Retrieves a string representation of the value for ASN.1 element. 896 * 897 * @return A string representation of the value for this ASN.1 element. 898 */ 899 @Override() 900 public final String toString() 901 { 902 final StringBuilder buffer = new StringBuilder(); 903 toString(buffer); 904 return buffer.toString(); 905 } 906 907 908 909 /** 910 * Appends a string representation of the value for this ASN.1 element to the 911 * provided buffer. 912 * 913 * @param buffer The buffer to which to append the information. 914 */ 915 public void toString(final StringBuilder buffer) 916 { 917 final byte[] v = getValue(); 918 buffer.append("ASN1Element(type="); 919 toHex(type, buffer); 920 buffer.append(", valueLength="); 921 buffer.append(v.length); 922 buffer.append(", valueBytes='"); 923 toHex(v, buffer); 924 buffer.append("')"); 925 } 926}