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
18package org.apache.harmony.security.x509;
19
20import java.io.IOException;
21import java.util.Iterator;
22import java.util.List;
23import org.apache.harmony.security.asn1.ASN1Oid;
24import org.apache.harmony.security.asn1.ASN1SequenceOf;
25import org.apache.harmony.security.asn1.ASN1Type;
26import org.apache.harmony.security.asn1.BerInputStream;
27import org.apache.harmony.security.asn1.ObjectIdentifier;
28
29/**
30 * Extended Key Usage Extension (OID == 2.5.29.37).
31 *
32 * The ASN.1 definition for Extended Key Usage Extension is:
33 *
34 * <pre>
35 *  id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
36 *
37 *  ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
38 *
39 *  KeyPurposeId ::= OBJECT IDENTIFIER
40 * </pre>
41 * (as specified in RFC 3280  http://www.ietf.org/rfc/rfc3280.txt
42 */
43public final class ExtendedKeyUsage extends ExtensionValue {
44
45    // the value of extension
46    private List<String> keys;
47
48    /**
49     * Creates the extension object on the base of its encoded form.
50     */
51    public ExtendedKeyUsage(byte[] encoding) {
52        super(encoding);
53    }
54
55    /**
56     * Returns the list of string representation of OIDs corresponding
57     * to key purpose IDs.
58     */
59    public List<String> getExtendedKeyUsage() throws IOException {
60        if (keys == null) {
61            keys = (List<String>) ASN1.decode(getEncoded());
62        }
63        return keys;
64    }
65
66    @Override public byte[] getEncoded() {
67        if (encoding == null) {
68            encoding = ASN1.encode(keys);
69        }
70        return encoding;
71    }
72
73    @Override public void dumpValue(StringBuilder sb, String prefix) {
74        sb.append(prefix).append("Extended Key Usage: ");
75        if (keys == null) {
76            try {
77                keys = getExtendedKeyUsage();
78            } catch (IOException e) {
79                // incorrect extension value encoding
80                super.dumpValue(sb);
81                return;
82            }
83        }
84        sb.append('[');
85        for (Iterator<?> it = keys.iterator(); it.hasNext();) {
86            sb.append(" \"").append(it.next()).append('"');
87            if (it.hasNext()) {
88                sb.append(',');
89            }
90        }
91        sb.append(" ]\n");
92    }
93
94    /**
95     * ASN.1 Encoder/Decoder.
96     */
97    public static final ASN1Type ASN1 = new ASN1SequenceOf(new ASN1Oid() {
98        public Object getDecodedObject(BerInputStream in) throws IOException {
99            int[] oid = (int[]) super.getDecodedObject(in);
100            return ObjectIdentifier.toString(oid);
101        }
102    });
103}
104