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