summaryrefslogtreecommitdiffstats
path: root/pki/base/util/src/netscape/security/util/ASN1CharStrConvMap.java
blob: c9c364f4f7fefa60c12dfe982b9ac352b98f83c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// --- BEGIN COPYRIGHT BLOCK ---
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// (C) 2007 Red Hat, Inc.
// All rights reserved.
// --- END COPYRIGHT BLOCK ---
package netscape.security.util;

import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Maps a ASN.1 character string type to a charset encoder and decoder.
 * The converter is used to convert a DerValue of a ASN.1 character string type
 * from bytes to unicode characters and vice versa.
 * 
 * <p>
 * A global default ASN1CharStrConvMap is created when the class is initialized. The global default map is extensible.
 * 
 * @author Lily Hsiao
 * @author Slava Galperin
 * 
 */

public class ASN1CharStrConvMap {
    // public constructors

    /**
     * Constructs a ASN1CharStrConvMap.
     */
    public ASN1CharStrConvMap() {
    }

    /**
     * Get an encoder for the specified DER tag.
     * 
     * @param tag A DER tag of a ASN.1 character string type,
     *            for example DerValue.tag_PrintableString.
     * 
     * @return An encoder for the DER tag.
     */
    public CharsetEncoder getEncoder(byte tag) {
        Charset charset = charsets.get(tag);
        if (charset == null)
            return null;
        return charset.newEncoder();
    }

    /**
     * Get a decoder for the given DER tag.
     * 
     * @param tag A DER tag of a ASN.1 character string type,
     *            for example DerValue.tag_PrintableString.
     * 
     * @return A decoder for the DER tag.
     */
    public CharsetDecoder getDecoder(byte tag) {
        Charset charset = charsets.get(tag);
        if (charset == null)
            return null;
        return charset.newDecoder();
    }

    /**
     * Add a tag-charset entry in the map.
     * 
     * @param tag A DER tag of a ASN.1 character string type,
     *            ex. DerValue.tag_IA5String
     * @param charset A charset for the tag.
     */
    public void addEntry(byte tag, Charset charset) {

        Charset currentCharset = charsets.get(tag);

        if (currentCharset != null) {
            if (currentCharset != charset) {
                throw new IllegalArgumentException(
                        "a DER tag to converter entry already exists.");
            } else {
                return;
            }
        }

        charsets.put(tag, charset);
    }

    /**
     * Get an iterator of all tags in the map.
     * 
     * @return An Iterator of DER tags in the map as Bytes.
     */
    public Iterator<Byte> getTags() {
        return charsets.keySet().iterator();
    }

    // static public methods.

    /**
     * Get the global ASN1CharStrConvMap.
     * 
     * @return The global default ASN1CharStrConvMap.
     */
    static public ASN1CharStrConvMap getDefault() {
        return defaultMap;
    }

    /**
     * Set the global default ASN1CharStrConvMap.
     * 
     * @param newDefault The new default ASN1CharStrConvMap.
     */
    static public void setDefault(ASN1CharStrConvMap newDefault) {
        if (newDefault == null)
            throw new IllegalArgumentException(
                    "Cannot set a null default Der Tag Converter map");
        defaultMap = newDefault;
    }

    // private methods and variables.

    private Map<Byte, Charset> charsets = new HashMap<Byte, Charset>();

    private static ASN1CharStrConvMap defaultMap;

    /**
     * Create the default converter map on initialization
     */
    static {
        ASN1CharsetProvider provider = new ASN1CharsetProvider();

        defaultMap = new ASN1CharStrConvMap();
        defaultMap.addEntry(DerValue.tag_PrintableString,
                provider.charsetForName("ASN.1-Printable"));
        defaultMap.addEntry(DerValue.tag_VisibleString,
                provider.charsetForName("ASN.1-Printable"));
        defaultMap.addEntry(DerValue.tag_IA5String,
                provider.charsetForName("ASN.1-IA5"));
        defaultMap.addEntry(DerValue.tag_BMPString,
                Charset.forName("UnicodeBig"));
        defaultMap.addEntry(DerValue.tag_UniversalString,
                provider.charsetForName("ASN.1-Universal"));
        // XXX this is an oversimplified implementation of T.61 strings, it
        // doesn't handle all cases
        defaultMap.addEntry(DerValue.tag_T61String,
                Charset.forName("ISO-8859-1"));
        // UTF8String added to ASN.1 in 1998
        defaultMap.addEntry(DerValue.tag_UTF8String,
                Charset.forName("UTF-8"));
        defaultMap.addEntry(DerValue.tag_GeneralString,
                Charset.forName("UTF-8"));
    };

};