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