001/* 002 * Copyright 2007-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2008-2019 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 com.unboundid.util.Debug; 026import com.unboundid.util.NotMutable; 027import com.unboundid.util.StaticUtils; 028import com.unboundid.util.ThreadSafety; 029import com.unboundid.util.ThreadSafetyLevel; 030 031import static com.unboundid.asn1.ASN1Messages.*; 032 033 034 035/** 036 * This class provides an ASN.1 null element, which does not hold a value. Null 037 * elements are generally used as placeholders that can be substituted for other 038 * types of elements. 039 */ 040@NotMutable() 041@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 042public final class ASN1Null 043 extends ASN1Element 044{ 045 /** 046 * A pre-allocated ASN.1 null element with the universal null BER type. 047 */ 048 public static final ASN1Null UNIVERSAL_NULL_ELEMENT = new ASN1Null(); 049 050 051 052 /** 053 * The serial version UID for this serializable class. 054 */ 055 private static final long serialVersionUID = -3264450066845549348L; 056 057 058 059 /** 060 * Creates a new ASN.1 null element with the default BER type. 061 */ 062 public ASN1Null() 063 { 064 super(ASN1Constants.UNIVERSAL_NULL_TYPE); 065 } 066 067 068 069 /** 070 * Creates a new ASN.1 null element with the specified BER type. 071 * 072 * @param type The BER type to use for this ASN.1 null element. 073 */ 074 public ASN1Null(final byte type) 075 { 076 super(type); 077 } 078 079 080 081 /** 082 * Decodes the contents of the provided byte array as a null element. 083 * 084 * @param elementBytes The byte array to decode as an ASN.1 null element. 085 * 086 * @return The decoded ASN.1 null element. 087 * 088 * @throws ASN1Exception If the provided array cannot be decoded as a null 089 * element. 090 */ 091 public static ASN1Null decodeAsNull(final byte[] elementBytes) 092 throws ASN1Exception 093 { 094 try 095 { 096 int valueStartPos = 2; 097 int length = (elementBytes[1] & 0x7F); 098 if (length != elementBytes[1]) 099 { 100 final int numLengthBytes = length; 101 102 length = 0; 103 for (int i=0; i < numLengthBytes; i++) 104 { 105 length <<= 8; 106 length |= (elementBytes[valueStartPos++] & 0xFF); 107 } 108 } 109 110 if ((elementBytes.length - valueStartPos) != length) 111 { 112 throw new ASN1Exception(ERR_ELEMENT_LENGTH_MISMATCH.get(length, 113 (elementBytes.length - valueStartPos))); 114 } 115 116 if (length != 0) 117 { 118 throw new ASN1Exception(ERR_NULL_HAS_VALUE.get()); 119 } 120 121 return new ASN1Null(elementBytes[0]); 122 } 123 catch (final ASN1Exception ae) 124 { 125 Debug.debugException(ae); 126 throw ae; 127 } 128 catch (final Exception e) 129 { 130 Debug.debugException(e); 131 throw new ASN1Exception(ERR_ELEMENT_DECODE_EXCEPTION.get(e), e); 132 } 133 } 134 135 136 137 /** 138 * Decodes the provided ASN.1 element as a null element. 139 * 140 * @param element The ASN.1 element to be decoded. 141 * 142 * @return The decoded ASN.1 null element. 143 * 144 * @throws ASN1Exception If the provided element cannot be decoded as a null 145 * element. 146 */ 147 public static ASN1Null decodeAsNull(final ASN1Element element) 148 throws ASN1Exception 149 { 150 if (element.getValue().length != 0) 151 { 152 throw new ASN1Exception(ERR_NULL_HAS_VALUE.get()); 153 } 154 155 return new ASN1Null(element.getType()); 156 } 157 158 159 160 /** 161 * {@inheritDoc} 162 */ 163 @Override() 164 public void toString(final StringBuilder buffer) 165 { 166 buffer.append("ASN1Null(type="); 167 StaticUtils.toHex(getType(), buffer); 168 buffer.append(')'); 169 } 170}