1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.location.cts.asn1.base; 18 19 import com.google.common.collect.ImmutableList; 20 21 import java.nio.ByteBuffer; 22 import java.util.Collection; 23 import java.util.NoSuchElementException; 24 25 /** 26 * Implements ASN.1 functionality. 27 * 28 */ 29 public abstract class Asn1Sequence extends Asn1Object { 30 private static final Collection<Asn1Tag> possibleFirstTags = 31 ImmutableList.of(Asn1Tag.SEQUENCE); 32 isExtensible()33 protected abstract boolean isExtensible(); 34 containsExtensionValues()35 protected abstract boolean containsExtensionValues(); 36 getComponents()37 protected abstract Iterable<? extends SequenceComponent> getComponents(); 38 getExtensionComponents()39 protected abstract Iterable<? extends SequenceComponent> getExtensionComponents(); 40 getPossibleFirstTags()41 public static Collection<Asn1Tag> getPossibleFirstTags() { 42 return possibleFirstTags; 43 } 44 getDefaultTag()45 @Override Asn1Tag getDefaultTag() { 46 return Asn1Tag.SEQUENCE; 47 } 48 isConstructed()49 @Override boolean isConstructed() { 50 return true; 51 } 52 53 @Override getBerValueLength()54 public int getBerValueLength() { 55 int length = 0; 56 for (SequenceComponent component : getComponents()) { 57 if (component.isExplicitlySet()) { 58 Asn1Tag tag = component.getTag(); 59 Asn1Object value = component.getComponentValue(); 60 if (tag == null) { 61 length += value.getBerLength(); 62 } else { 63 int valueLen = component.isImplicitTagging() 64 ? value.getBerValueLength() : value.getBerLength(); 65 length += tag.getTaggedLength(valueLen); 66 } 67 } 68 } 69 return length; 70 } 71 72 @Override encodeBerValue(ByteBuffer buf)73 public void encodeBerValue(ByteBuffer buf) { 74 for (SequenceComponent component : getComponents()) { 75 if (component.isExplicitlySet()) { 76 Asn1Object obj = component.getComponentValue(); 77 Asn1Tag componentTag = component.getTag(); 78 if (componentTag == null) { 79 obj.encodeBer(buf); 80 } else { 81 if (component.isImplicitTagging()) { 82 componentTag.writeTagAndLength(buf, obj.isConstructed(), obj.getBerValueLength()); 83 obj.encodeBerValue(buf); 84 } else { 85 componentTag.writeTagAndLength(buf, true, obj.getBerLength()); 86 obj.encodeBer(buf); 87 } 88 } 89 } else if (!component.isOptional() && !component.hasDefaultValue()) { 90 throw new IllegalStateException("Mandatory component " 91 + component.getClass().getName() 92 + " not set."); 93 } 94 } 95 } 96 97 @Override decodeBerValue(ByteBuffer buf)98 public void decodeBerValue(ByteBuffer buf) { 99 Iterable<? extends SequenceComponent> components = getComponents(); 100 101 while (buf.hasRemaining()) { 102 int bufStartPos = buf.position(); 103 int bufEndPos = buf.limit(); 104 Asn1Tag tag = Asn1Tag.readTag(buf); 105 SequenceComponent component = getComponent(components, tag); 106 if (component.isExplicitlySet()) { 107 throw new IllegalArgumentException("Encountered duplicate field"); 108 } 109 component.setToNewInstance(); 110 int valueLength = Asn1Tag.readLength(buf); 111 buf.limit(buf.position() + valueLength); 112 if (component.getTag() != null) { 113 if (component.isImplicitTagging()) { 114 component.getComponentValue().decodeBerValue(buf); 115 } else { 116 component.getComponentValue().decodeBer(buf); 117 } 118 } else { 119 buf.position(bufStartPos); // rewind to before tag 120 component.getComponentValue().decodeBer(buf); 121 } 122 buf.limit(bufEndPos); // set the limit back to the real end position 123 } 124 125 checkMandatoryFieldsPresent(components); 126 } 127 128 /** 129 * Throws {@link IllegalArgumentException} if all mandatory fields not set on this sequence. 130 */ checkMandatoryFieldsPresent(Iterable<? extends SequenceComponent> components)131 private void checkMandatoryFieldsPresent(Iterable<? extends SequenceComponent> components) { 132 for (SequenceComponent component : components) { 133 if (!component.isOptional() && !component.isExplicitlySet()) { 134 throw new IllegalArgumentException("Mandatory field not present"); 135 } 136 } 137 } 138 139 /** 140 * Returns the child component that can start with the specified tag. 141 * @throws NoSuchElementException if no child component can start with the tag 142 */ getComponent(Iterable<? extends SequenceComponent> components, Asn1Tag tag)143 private SequenceComponent getComponent(Iterable<? extends SequenceComponent> components, 144 Asn1Tag tag) { 145 for (SequenceComponent component : components) { 146 if (component.getPossibleFirstTags().contains(tag)) { 147 return component; 148 } 149 } 150 throw new NoSuchElementException("SEQUENCE=" + this + ", tag=" + tag); 151 } 152 encodePerImpl(boolean aligned)153 private Iterable<BitStream> encodePerImpl(boolean aligned) { 154 ImmutableList.Builder<BitStream> listBuilder = ImmutableList.builder(); 155 BitStream prefix = new BitStream(); 156 157 if (isExtensible()) { 158 prefix.appendBit(containsExtensionValues()); 159 } 160 161 Iterable<? extends SequenceComponent> components = getComponents(); 162 int bitFieldSize = calculateBitFieldSize(components); 163 if (bitFieldSize >= PerAlignedUtils.SIXTYFOUR_K) { 164 throw new UnsupportedOperationException("unimplemented"); 165 } 166 for (SequenceComponent component : components) { 167 if (component.isOptional() || component.hasDefaultValue()) { 168 prefix.appendBit(component.isExplicitlySet()); 169 } else if (!component.isExplicitlySet()) { 170 throw new IllegalStateException("Mandatory component " 171 + component.getClass().getName() 172 + " not set."); 173 } 174 } 175 listBuilder.add(prefix); 176 177 for (SequenceComponent component : components) { 178 if (component.isExplicitlySet()) { 179 Asn1Object value = component.getComponentValue(); 180 Iterable<BitStream> encodedValue = null; 181 if (aligned) { 182 encodedValue = value.encodePerAligned(); 183 } else { 184 encodedValue = value.encodePerUnaligned(); 185 } 186 listBuilder.addAll(encodedValue); 187 } 188 } 189 190 if (isExtensible() && containsExtensionValues()) { 191 Iterable<? extends SequenceComponent> extensionComponents = 192 getExtensionComponents(); 193 BitStream extensions = new BitStream(); 194 int extensionBitFieldSize = 0; 195 /* 196 * Adding a bit marker per extension addition as ITU spec, however some 197 * H323 implementations seem to only add markers up to the last set 198 * extension. 199 */ 200 for (SequenceComponent component : extensionComponents) { 201 if (!component.isOptional() && !component.isExplicitlySet()) { 202 throw new IllegalStateException("Mandatory extension component " 203 + component.getClass().getName() 204 + " not set."); 205 } 206 extensions.appendBit(component.isExplicitlySet()); 207 extensionBitFieldSize++; 208 } 209 if (extensionBitFieldSize <= 64) { 210 //encode length to x.691-0207 10.9.3.4 (i.e. length -1) 211 BitStream lengthDeterminant = new BitStream(); 212 lengthDeterminant.appendBit(false); 213 lengthDeterminant.appendLowBits(6, (byte) (extensionBitFieldSize - 1)); 214 listBuilder.add(lengthDeterminant); 215 } else { 216 BitStream marker = new BitStream(); 217 marker.appendBit(true); 218 listBuilder.add(marker); 219 BitStream lengthDeterminant = null; 220 if (aligned) { 221 lengthDeterminant = 222 PerAlignedUtils.encodeSemiConstrainedLength(extensionBitFieldSize); 223 lengthDeterminant.setBeginByteAligned(); 224 } else { 225 lengthDeterminant = 226 PerUnalignedUtils.encodeSemiConstrainedLength(extensionBitFieldSize); 227 } 228 listBuilder.add(lengthDeterminant); 229 } 230 listBuilder.add(extensions); 231 for (SequenceComponent component : extensionComponents) { 232 if (component.isExplicitlySet()) { 233 Iterable<BitStream> extensionValues = null; 234 if (aligned) { 235 extensionValues = PerAlignedUtils. 236 encodeOpenTypeField(component.getComponentValue()); 237 } else { 238 extensionValues = PerUnalignedUtils.encodeOpenTypeField(component.getComponentValue()); 239 } 240 listBuilder.addAll(extensionValues); 241 } 242 } 243 } 244 return listBuilder.build(); 245 } 246 encodePerUnaligned()247 @Override public Iterable<BitStream> encodePerUnaligned() { 248 return encodePerImpl(false); 249 } 250 251 @Override encodePerAligned()252 public Iterable<BitStream> encodePerAligned() { 253 return encodePerImpl(true); 254 } 255 calculateBitFieldSize( Iterable<? extends SequenceComponent> components)256 private int calculateBitFieldSize( 257 Iterable<? extends SequenceComponent> components) { 258 int bitFieldSize = 0; 259 for (SequenceComponent component : components) { 260 if (component.isOptional() || component.hasDefaultValue()) { 261 bitFieldSize++; 262 } 263 } 264 return bitFieldSize; 265 } 266 decodePerImpl(BitStreamReader reader, boolean aligned)267 private void decodePerImpl(BitStreamReader reader, boolean aligned) { 268 boolean hasExtensionValuesToDecode = false; 269 if (isExtensible()) { 270 hasExtensionValuesToDecode = reader.readBit(); 271 } 272 273 Iterable<? extends SequenceComponent> components = getComponents(); 274 int bitFieldSize = calculateBitFieldSize(components); 275 if (bitFieldSize >= PerAlignedUtils.SIXTYFOUR_K) { 276 throw new UnsupportedOperationException("unimplemented"); 277 } 278 for (SequenceComponent component : components) { 279 if (component.isOptional() || component.hasDefaultValue()) { 280 if (reader.readBit()) { 281 component.setToNewInstance(); 282 } 283 } else { 284 component.setToNewInstance(); 285 } 286 } 287 288 for (SequenceComponent component : components) { 289 if (component.isExplicitlySet()) { 290 if (aligned) { 291 component.getComponentValue().decodePerAligned(reader); 292 } else { 293 component.getComponentValue().decodePerUnaligned(reader); 294 } 295 } 296 } 297 298 if (hasExtensionValuesToDecode) { 299 Iterable<? extends SequenceComponent> extensionComponents = 300 getExtensionComponents(); 301 int extensionBitFieldSize; 302 if (reader.readBit()) { 303 if (aligned) { 304 reader.spoolToByteBoundary(); 305 extensionBitFieldSize = 306 PerAlignedUtils.decodeSemiConstrainedLength(reader); 307 } else { 308 extensionBitFieldSize = 309 PerUnalignedUtils.decodeSemiConstrainedLength(reader); 310 } 311 } else { 312 extensionBitFieldSize = 1 + reader.readLowBits(6); 313 } 314 for (SequenceComponent component : extensionComponents) { 315 if (extensionBitFieldSize > 0) { 316 --extensionBitFieldSize; 317 if (reader.readBit()) { 318 component.setToNewInstance(); 319 } 320 } 321 } 322 int unknownExtensionCount = 0; 323 for (; extensionBitFieldSize > 0; --extensionBitFieldSize) { 324 if (reader.readBit()) { 325 ++unknownExtensionCount; 326 } 327 } 328 for (SequenceComponent component : extensionComponents) { 329 if (component.isExplicitlySet()) { 330 if (aligned) { 331 byte[] encodedComponent = 332 PerAlignedUtils.decodeSemiConstrainedLengthOfBytes(reader); 333 component.getComponentValue().decodePerAligned(new BitStreamReader(encodedComponent)); 334 } else { 335 byte[] encodedComponent = 336 PerUnalignedUtils.decodeSemiConstrainedLengthOfBytes(reader); 337 component.getComponentValue().decodePerUnaligned(new BitStreamReader(encodedComponent)); 338 } 339 } 340 } 341 for (; unknownExtensionCount > 0; --unknownExtensionCount) { 342 if (aligned) { 343 byte[] unknownEncodedExtension = 344 PerAlignedUtils.decodeSemiConstrainedLengthOfBytes(reader); 345 } else { 346 byte[] unknownEncodedExtension = 347 PerUnalignedUtils.decodeSemiConstrainedLengthOfBytes(reader); 348 } 349 } 350 } 351 } 352 decodePerUnaligned(BitStreamReader reader)353 @Override public void decodePerUnaligned(BitStreamReader reader) { 354 decodePerImpl(reader, false); 355 } 356 decodePerAligned(BitStreamReader reader)357 @Override public void decodePerAligned(BitStreamReader reader) { 358 decodePerImpl(reader, true); 359 } 360 } 361 362