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