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 }