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