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