summaryrefslogtreecommitdiffstats
path: root/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java
blob: 85f3938b8b7fb59398e17862ed8a4d0c39a85ecf (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
169
170
171
172
173
174
175
176
// --- 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 com.netscape.cms.servlet.cert.scep;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.cert.CertificateException;
import java.util.Enumeration;
import java.util.Vector;

import netscape.security.util.DerInputStream;
import netscape.security.util.DerValue;
import netscape.security.x509.CertAttrSet;
import netscape.security.x509.Extension;

public class ExtensionsRequested implements CertAttrSet {

    public static final String NAME = "EXTENSIONS_REQUESTED";

    public static final String KUE_DIGITAL_SIGNATURE = "kue_digital_signature";
    public static final String KUE_KEY_ENCIPHERMENT = "kue_key_encipherment";

    private String kue_digital_signature = "false";
    private String kue_key_encipherment = "false";

    private Vector<Extension> exts = new Vector<Extension>();

    public ExtensionsRequested(Object stuff) throws IOException {
        ByteArrayInputStream is = new ByteArrayInputStream((byte[]) stuff);

        try {
            decode(is);
        } catch (Exception e) {
            e.printStackTrace();
            throw new IOException(e.getMessage());
        }
    }

    public void encode(OutputStream out)
            throws CertificateException, IOException {
    }

    public void decode(InputStream in)
            throws CertificateException, IOException {
        DerValue derVal = new DerValue(in);

        construct(derVal);
    }

    public void set(String name, Object obj)
            throws CertificateException, IOException {
    }

    public Object get(String name)
            throws CertificateException, IOException {
        if (name.equalsIgnoreCase(KUE_DIGITAL_SIGNATURE)) {
            return kue_digital_signature;
        }
        if (name.equalsIgnoreCase(KUE_KEY_ENCIPHERMENT)) {
            return kue_key_encipherment;
        }

        throw new IOException("Unsupported attribute queried");
    }

    public void delete(String name)
            throws CertificateException, IOException {
    }

    public Enumeration<String> getAttributeNames() {
        return (new Vector<String>()).elements();
    }

    public String getName() {
        return NAME;
    }

    /**
     * construct - expects this in the inputstream (from the router):
     * 
     * 211 30 31: SEQUENCE {
     * 213 06 10: OBJECT IDENTIFIER '2 16 840 1 113733 1 9 8'
     * 225 31 17: SET {
     * 227 04 15: OCTET STRING, encapsulates {
     * 229 30 13: SEQUENCE {
     * 231 30 11: SEQUENCE {
     * 233 06 3: OBJECT IDENTIFIER keyUsage (2 5 29 15)
     * 238 04 4: OCTET STRING
     * : 03 02 05 A0
     * : }
     * : }
     * : }
     * 
     * or this (from IRE client):
     * 
     * 262 30 51: SEQUENCE {
     * 264 06 9: OBJECT IDENTIFIER extensionReq (1 2 840 113549 1 9 14)
     * 275 31 38: SET {
     * 277 30 36: SEQUENCE {
     * 279 30 34: SEQUENCE {
     * 281 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17)
     * 286 04 27: OCTET STRING
     * : 30 19 87 04 D0 0C 3E 6F 81 03 61 61 61 82 0C 61
     * : 61 61 2E 6D 63 6F 6D 2E 63 6F 6D
     * : }
     * : }
     * : }
     * : }
     */
    private void construct(DerValue dv) throws IOException {

        DerInputStream stream = null;

        try { // try decoding as sequence first

            stream = dv.toDerInputStream();

            stream.getDerValue(); // consume stream
            stream.reset();

            stream.getSequence(2); // consume stream
        } catch (IOException ioe) {
            // if it failed, the outer sequence may be
            // encapsulated in an octet string, as in the first
            // example above

            byte[] octet_string = dv.getOctetString();

            // Make a new input stream from the byte array,
            // and re-parse it as a sequence.

            dv = new DerValue(octet_string);

            stream = dv.toDerInputStream();
            stream.getSequence(2); // consume stream
        }

        // now, the stream will be in the correct format
        stream.reset();

        while (true) {
            DerValue ext_dv = null;
            try {
                ext_dv = stream.getDerValue();
            } catch (IOException ex) {
                break;
            }

            Extension ext = new Extension(ext_dv);
            exts.addElement(ext);
        }

    }

    public Vector<Extension> getExtensions() {
        return exts;
    }

}