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