001    package com.nimbusds.jose;
002    
003    
004    import java.net.URL;
005    import java.text.ParseException;
006    import java.util.Arrays;
007    
008    import net.minidev.json.JSONArray;
009    import net.minidev.json.JSONObject;
010    
011    import com.nimbusds.jose.util.Base64;
012    import com.nimbusds.jose.util.Base64URL;
013    
014    
015    /**
016     * Common class for JWS and JWE headers.
017     *
018     * <p>Supports all reserved header parameters shared by the JWS and JWE
019     * specifications:
020     *
021     * <ul>
022     *     <li>alg
023     *     <li>jku
024     *     <li>jwk
025     *     <li>x5u
026     *     <li>x5t
027     *     <li>x5c
028     *     <li>kid
029     *     <li>typ
030     *     <li>cty
031     * </ul>
032     *
033     * @author Vladimir Dzhuvinov
034     * @version $version$ (2012-09-22)
035     */
036    public abstract class CommonSEHeader extends Header implements ReadOnlyCommonSEHeader {
037    
038    
039            /**
040             * JWK Set URL, {@code null} if not specified.
041             */
042            private URL jku;
043    
044    
045            /**
046             * JWK, {@code null} if not specified.
047             */
048            private JWK jwk;
049    
050    
051            /**
052             * X.509 certificate URL, {@code null} if not specified.
053             */
054            private URL x5u;
055    
056    
057            /**
058             * X.509 certificate thumbprint, {@code null} if not specified.
059             */
060            private Base64URL x5t;
061    
062    
063            /**
064             * The X.509 certificate chain corresponding to the key used to sign or 
065             * encrypt the JWS/JWE object, {@code null} if not specified.
066             */
067            private Base64[] x5c;
068    
069    
070            /**
071             * Key ID, {@code null} if not specified.
072             */
073            private String kid;
074    
075    
076            /**
077             * Creates a new common JWS and JWE header with the specified algorithm 
078             * ({@code alg}) parameter.
079             *
080             * @param alg The algorithm parameter. Must not be {@code null}.
081             */
082            protected CommonSEHeader(final Algorithm alg) {
083    
084                    super(alg);
085            }
086    
087    
088            @Override
089            public URL getJWKURL() {
090    
091                    return jku;
092            }
093    
094    
095            /**
096             * Sets the JSON Web Key (JWK) Set URL ({@code jku}) parameter.
097             *
098             * @param jku The JSON Web Key (JWK) Set URL parameter, {@code null} if 
099             *            not specified.
100             */
101            public void setJWKURL(final URL jku) {
102    
103                    this.jku = jku;
104            }
105    
106    
107            @Override
108            public JWK getJWK() {
109    
110                    return jwk;
111            }
112    
113    
114            /**
115             * Sets the JSON Web Key (JWK) ({@code jwk}) parameter.
116             *
117             * @param jwk The JSON Web Key (JWK) ({@code jwk}) parameter, 
118             *            {@code null} if not specified.
119             */
120            public void setJWK(final JWK jwk) {
121    
122                    this.jwk = jwk;
123            }
124    
125    
126            @Override
127            public URL getX509CertURL() {
128    
129                    return x5u;
130            }
131    
132    
133            /**
134             * Sets the X.509 certificate URL ({@code x5u}) parameter.
135             *
136             * @param x5u The X.509 certificate URL parameter, {@code null} if not 
137             *            specified.
138             */
139            public void setX509CertURL(final URL x5u) {
140    
141                    this.x5u = x5u;
142            }
143    
144    
145            @Override
146            public Base64URL getX509CertThumbprint() {
147    
148                    return x5t;
149            }
150    
151    
152            /**
153             * Sets the X.509 certificate thumbprint ({@code x5t}) parameter.
154             *
155             * @param x5t The X.509 certificate thumbprint parameter, {@code null}  
156             *            if not specified.
157             */
158            public void setX509CertThumbprint(final Base64URL x5t) {
159    
160                    this.x5t = x5t;
161            }
162    
163    
164            @Override
165            public Base64[] getX509CertChain() {
166    
167                    return x5c;
168            }
169    
170    
171            /**
172             * Sets the X.509 certificate chain parameter ({@code x5c}) 
173             * corresponding to the key used to sign or encrypt the JWS/JWE object.
174             *
175             * @param x5c The X.509 certificate chain parameter, {@code null} if not
176             *            specified.
177             */
178            public void setX509CertChain(final Base64[] x5c) {
179    
180                    this.x5c = x5c;
181            }
182    
183    
184            @Override
185            public String getKeyID() {
186    
187                    return kid;
188            }
189    
190    
191            /**
192             * Sets the key ID ({@code kid}) parameter.
193             *
194             * @param kid The key ID parameter, {@code null} if not specified.
195             */
196            public void setKeyID(final String kid) {
197    
198                    this.kid = kid;
199            }
200    
201    
202            @Override
203            public JSONObject toJSONObject() {
204    
205                    JSONObject o = super.toJSONObject();
206    
207                    if (jku != null) {
208                            o.put("jku", jku.toString());
209                    }
210    
211                    if (jwk != null) {
212                            o.put("jwk", jwk.toJSONObject());
213                    }
214    
215                    if (x5u != null) {
216                            o.put("x5u", x5u.toString());
217                    }
218    
219                    if (x5t != null) {
220                            o.put("x5t", x5t.toString());
221                    }
222    
223                    if (x5c != null) {
224                            o.put("x5c", Arrays.asList(x5c));
225                    }
226    
227                    if (kid != null) {
228                            o.put("kid", kid);
229                    }
230    
231                    return o;
232            }
233    
234    
235            /**
236             * Parses an X.509 certificate chain from the specified JSON array.
237             *
238             * @param jsonArray The JSON array to parse. Must not be {@code null}.
239             *
240             * @return The X.509 certificate chain.
241             *
242             * @throws ParseException If the X.509 certificate chain couldn't be
243             *                        parsed.
244             */
245            protected static Base64[] parseX509CertChain(final JSONArray jsonArray)
246                            throws ParseException {
247    
248                    Base64[] chain = new Base64[jsonArray.size()];
249    
250                    for (int i=0; i < jsonArray.size(); i++) {
251    
252                            Object item = jsonArray.get(i);
253    
254                            if (item == null) {
255                                    throw new ParseException("The X.509 certificate at position " + i + " must not be null", 0);
256                            }
257    
258                            if  (! (item instanceof String)) {
259                                    throw new ParseException("The X.509 certificate must be encoded as a Base64 string", 0);
260                            }
261    
262                            chain[i] = new Base64((String)item);
263                    }
264    
265                    return chain;
266            }
267    }