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