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 com.nimbusds.jose.util.JSONStringUtils; 028 029import net.jcip.annotations.Immutable; 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 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 instanceof KeyType && 162 this.toString().equals(object.toString()); 163 } 164 165 166 /** 167 * Returns the string representation of this key type. 168 * 169 * @see #getValue 170 * 171 * @return The string representation. 172 */ 173 @Override 174 public String toString() { 175 176 return value; 177 } 178 179 180 /** 181 * Returns the JSON string representation of this key type. 182 * 183 * @return The JSON string representation. 184 */ 185 public String toJSONString() { 186 return JSONStringUtils.toJSONString(value); 187 } 188 189 190 /** 191 * Parses a key type from the specified {@code kty} parameter value. 192 * 193 * @param s The string to parse. Must not be {@code null}. 194 * 195 * @return The key type (matching standard key type constant, else a 196 * newly created one). 197 */ 198 public static KeyType parse(final String s) { 199 200 if (s == null) { 201 throw new IllegalArgumentException("The key type to parse must not be null"); 202 } 203 204 if (s.equals(EC.getValue())) { 205 return EC; 206 } else if (s.equals(RSA.getValue())) { 207 return RSA; 208 } else if (s.equals(OCT.getValue())) { 209 return OCT; 210 } else if (s.equals(OKP.getValue())) { 211 return OKP; 212 } else { 213 return new KeyType(s, null); 214 } 215 } 216 217 218 /** 219 * Infers the key type for the specified JOSE algorithm. 220 * 221 * @param alg The JOSE algorithm. May be {@code null}. 222 * 223 * @return The key type, {@code null} if it couldn't be inferred. 224 */ 225 public static KeyType forAlgorithm(final Algorithm alg) { 226 227 if (alg == null) { 228 return null; 229 } 230 231 if (JWSAlgorithm.Family.RSA.contains(alg)) { 232 return KeyType.RSA; 233 } else if (JWSAlgorithm.Family.EC.contains(alg)) { 234 return KeyType.EC; 235 } else if (JWSAlgorithm.Family.HMAC_SHA.contains(alg)) { 236 return KeyType.OCT; 237 } else if (JWEAlgorithm.Family.RSA.contains(alg)) { 238 return KeyType.RSA; 239 } else if (JWEAlgorithm.Family.ECDH_ES.contains(alg)) { 240 return KeyType.EC; 241 } else if (JWEAlgorithm.DIR.equals(alg)) { 242 return KeyType.OCT; 243 } else if (JWEAlgorithm.Family.AES_GCM_KW.contains(alg)) { 244 return KeyType.OCT; 245 } else if (JWEAlgorithm.Family.AES_KW.contains(alg)) { 246 return KeyType.OCT; 247 } else if (JWEAlgorithm.Family.PBES2.contains(alg)) { 248 return KeyType.OCT; 249 } else if (JWSAlgorithm.Family.ED.contains(alg)) { 250 return KeyType.OKP; 251 } else { 252 return null; 253 } 254 } 255}