1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /** 19 * @author Vladimir N. Molotkov, Stepan M. Mishura 20 * @version $Revision$ 21 */ 22 23 package org.apache.harmony.security.asn1; 24 25 import java.io.IOException; 26 import java.nio.charset.StandardCharsets; 27 28 /** 29 * This class is the super class for all string ASN.1 types 30 * 31 * @see <a href="http://asn1.elibel.tm.fr/en/standards/index.htm">ASN.1</a> 32 */ 33 public abstract class ASN1StringType extends ASN1Type { 34 35 private static class ASN1StringUTF8Type extends ASN1StringType { 36 public ASN1StringUTF8Type(int tagNumber) { 37 super(tagNumber); 38 } 39 40 @Override 41 public Object getDecodedObject(BerInputStream in) throws IOException { 42 return new String(in.buffer, in.contentOffset, in.length, StandardCharsets.UTF_8); 43 } 44 45 @Override 46 public void setEncodingContent(BerOutputStream out) { 47 byte[] bytes = ((String) out.content).getBytes(StandardCharsets.UTF_8); 48 out.content = bytes; 49 out.length = bytes.length; 50 } 51 } 52 53 // TODO: what about defining them as separate classes? 54 // TODO: check decoded/encoded characters 55 public static final ASN1StringType BMPSTRING = new ASN1StringType(TAG_BMPSTRING) {}; 56 57 public static final ASN1StringType IA5STRING = new ASN1StringType(TAG_IA5STRING) {}; 58 59 public static final ASN1StringType GENERALSTRING = new ASN1StringType(TAG_GENERALSTRING) {}; 60 61 public static final ASN1StringType PRINTABLESTRING = new ASN1StringType(TAG_PRINTABLESTRING) {}; 62 63 public static final ASN1StringType TELETEXSTRING = new ASN1StringUTF8Type(TAG_TELETEXSTRING) {}; 64 65 public static final ASN1StringType UNIVERSALSTRING = new ASN1StringType(TAG_UNIVERSALSTRING) {}; 66 67 public static final ASN1StringType UTF8STRING = new ASN1StringUTF8Type(TAG_UTF8STRING) {}; 68 69 public ASN1StringType(int tagNumber) { 70 super(tagNumber); 71 } 72 73 /** 74 * Tests provided identifier. 75 * 76 * @param identifier identifier to be verified 77 * @return true if identifier correspond to primitive or constructed 78 * identifier of this ASN.1 string type, otherwise false 79 */ 80 public final boolean checkTag(int identifier) { 81 return this.id == identifier || this.constrId == identifier; 82 } 83 84 public Object decode(BerInputStream in) throws IOException { 85 in.readString(this); 86 87 if (in.isVerify) { 88 return null; 89 } 90 return getDecodedObject(in); 91 } 92 93 /** 94 * Extracts String object from BER input stream. 95 */ 96 public Object getDecodedObject(BerInputStream in) throws IOException { 97 /* To ensure we get the correct encoding on non-ASCII platforms, specify 98 that we wish to convert from ASCII to the default platform encoding */ 99 return new String(in.buffer, in.contentOffset, in.length, StandardCharsets.ISO_8859_1); 100 } 101 102 public void encodeASN(BerOutputStream out) { 103 out.encodeTag(id); 104 encodeContent(out); 105 } 106 107 public void encodeContent(BerOutputStream out) { 108 out.encodeString(); 109 } 110 111 public void setEncodingContent(BerOutputStream out) { 112 byte[] bytes = ((String) out.content).getBytes(StandardCharsets.UTF_8); 113 out.content = bytes; 114 out.length = bytes.length; 115 } 116 } 117