001package com.nimbusds.jose.jwk; 002 003 004import java.io.Serializable; 005import java.security.Key; 006 007import com.nimbusds.jose.Algorithm; 008import com.nimbusds.jose.JWEAlgorithm; 009import com.nimbusds.jose.JWSAlgorithm; 010import net.jcip.annotations.Immutable; 011 012import net.minidev.json.JSONAware; 013import net.minidev.json.JSONObject; 014 015import com.nimbusds.jose.Requirement; 016 017 018/** 019 * Key type. Represents the {@code kty} parameter in a JSON Web Key (JWK). 020 * This class is immutable. 021 * 022 * <p>Includes constants for the following standard key types: 023 * 024 * <ul> 025 * <li>{@link #EC} 026 * <li>{@link #RSA} 027 * <li>{@link #OCT} 028 * </ul> 029 * 030 * <p>Additional key types can be defined using the constructor. 031 * 032 * @author Vladimir Dzhuvinov 033 * @author Justin Richer 034 * @version 2015-11-30 035 */ 036@Immutable 037public final class KeyType implements JSONAware, Serializable { 038 039 040 private static final long serialVersionUID = 1L; 041 042 043 /** 044 * The key type value. 045 */ 046 private final String value; 047 048 049 /** 050 * The implementation requirement, {@code null} if not known. 051 */ 052 private final Requirement requirement; 053 054 055 /** 056 * Elliptic Curve (DSS) key type (recommended). 057 */ 058 public static final KeyType EC = new KeyType("EC", Requirement.RECOMMENDED); 059 060 061 /** 062 * RSA (RFC 3447) key type (required). 063 */ 064 public static final KeyType RSA = new KeyType("RSA", Requirement.REQUIRED); 065 066 067 /** 068 * Octet sequence key type (optional) 069 */ 070 public static final KeyType OCT = new KeyType("oct", Requirement.OPTIONAL); 071 072 073 /** 074 * Creates a new key type with the specified value and implementation 075 * requirement. 076 * 077 * @param value The key type value. Values are case sensitive. Must not 078 * be {@code null}. 079 * @param req The implementation requirement, {@code null} if not 080 * known. 081 */ 082 public KeyType(final String value, final Requirement req) { 083 084 if (value == null) { 085 086 throw new IllegalArgumentException("The key type value must not be null"); 087 } 088 089 this.value = value; 090 091 requirement = req; 092 } 093 094 095 /** 096 * Gets the value of this key type. Values are case sensitive. 097 * 098 * @return The key type. 099 */ 100 public String getValue() { 101 102 return value; 103 } 104 105 106 /** 107 * Gets the implementation requirement of this key type. 108 * 109 * @return The implementation requirement, {@code null} if not known. 110 */ 111 public Requirement getRequirement() { 112 113 return requirement; 114 } 115 116 117 /** 118 * Overrides {@code Object.hashCode()}. 119 * 120 * @return The object hash code. 121 */ 122 @Override 123 public int hashCode() { 124 125 return value.hashCode(); 126 } 127 128 129 /** 130 * Overrides {@code Object.equals()}. 131 * 132 * @param object The object to compare to. 133 * 134 * @return {@code true} if the objects have the same value, otherwise 135 * {@code false}. 136 */ 137 @Override 138 public boolean equals(final Object object) { 139 140 return object != null && 141 object instanceof KeyType && 142 this.toString().equals(object.toString()); 143 } 144 145 146 /** 147 * Returns the string representation of this key type. 148 * 149 * @see #getValue 150 * 151 * @return The string representation. 152 */ 153 @Override 154 public String toString() { 155 156 return value; 157 } 158 159 160 /** 161 * Returns the JSON string representation of this key type. 162 * 163 * @return The JSON string representation. 164 */ 165 @Override 166 public String toJSONString() { 167 168 return "\"" + JSONObject.escape(value) + '"'; 169 } 170 171 172 /** 173 * Parses a key type from the specified {@code kty} parameter value. 174 * 175 * @param s The string to parse. Must not be {@code null}. 176 * 177 * @return The key type (matching standard key type constant, else a 178 * newly created one). 179 */ 180 public static KeyType parse(final String s) { 181 182 if (s.equals(EC.getValue())) { 183 184 return EC; 185 186 } else if (s.equals(RSA.getValue())) { 187 188 return RSA; 189 190 } else if (s.equals(OCT.getValue())) { 191 192 return OCT; 193 194 } else { 195 196 return new KeyType(s, null); 197 } 198 } 199 200 201 /** 202 * Infers the key type for the specified JOSE algorithm. 203 * 204 * @param alg The JOSE algorithm. May be {@code null}. 205 * 206 * @return The key type, {@code null} if it couldn't be inferred. 207 */ 208 public static KeyType forAlgorithm(final Algorithm alg) { 209 210 if (alg == null) { 211 return null; 212 } 213 214 if (JWSAlgorithm.Family.RSA.contains(alg)) { 215 return KeyType.RSA; 216 } else if (JWSAlgorithm.Family.EC.contains(alg)) { 217 return KeyType.EC; 218 } else if (JWSAlgorithm.Family.HMAC_SHA.contains(alg)) { 219 return KeyType.OCT; 220 } else if (JWEAlgorithm.Family.RSA.contains(alg)) { 221 return KeyType.RSA; 222 } else if (JWEAlgorithm.Family.ECDH_ES.contains(alg)) { 223 return KeyType.EC; 224 } else if (JWEAlgorithm.DIR.equals(alg)) { 225 return KeyType.OCT; 226 } else if (JWEAlgorithm.Family.AES_GCM_KW.contains(alg)) { 227 return KeyType.OCT; 228 } else if (JWEAlgorithm.Family.AES_KW.contains(alg)) { 229 return KeyType.OCT; 230 } else if (JWEAlgorithm.Family.PBES2.contains(alg)) { 231 return KeyType.OCT; 232 } else { 233 return null; 234 } 235 } 236}