001/* 002 * nimbus-jose-jwt 003 * 004 * Copyright 2012-2016, Connect2id Ltd and contributors. 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; 022import java.security.spec.ECParameterSpec; 023import java.util.Arrays; 024import java.util.Collections; 025import java.util.HashSet; 026import java.util.Set; 027 028import com.nimbusds.jose.JWSAlgorithm; 029import net.jcip.annotations.Immutable; 030 031 032/** 033 * Cryptographic curve. This class is immutable. 034 * 035 * <p>Includes constants for the following standard cryptographic curves: 036 * 037 * <ul> 038 * <li>{@link #P_256} 039 * <li>{@link #SECP256K1} 040 * <li>{@link #P_256K} (Deprecated) 041 * <li>{@link #P_384} 042 * <li>{@link #P_521} 043 * <li>{@link #Ed25519} 044 * <li>{@link #Ed448} 045 * <li>{@link #X25519} 046 * <li>{@link #X448} 047 * </ul> 048 * 049 * <p>See 050 * 051 * <ul> 052 * <li>"Digital Signature Standard (DSS)", FIPS PUB 186-3, June 2009, 053 * National Institute of Standards and Technology (NIST). 054 * <li>CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON 055 * Object Signing and Encryption (JOSE) (RFC 8037). 056 * </ul> 057 * 058 * @author Vladimir Dzhuvinov 059 * @author Aleksei Doroganov 060 * @version 2013-03-28 061 */ 062@Immutable 063public final class Curve implements Serializable { 064 065 066 private static final long serialVersionUID = 1L; 067 068 069 /** 070 * P-256 curve (secp256r1, also called prime256v1, OID = 071 * 1.2.840.10045.3.1.7). 072 */ 073 public static final Curve P_256 = new Curve("P-256", "secp256r1", "1.2.840.10045.3.1.7"); 074 075 076 /** 077 * secp256k1 curve (secp256k1, OID = 1.3.132.0.10). 078 */ 079 public static final Curve SECP256K1 = new Curve("secp256k1", "secp256k1", "1.3.132.0.10"); 080 081 /** 082 * P-256K curve. 083 * 084 * @deprecated Use {@link #SECP256K1}. 085 */ 086 @Deprecated 087 public static final Curve P_256K = new Curve("P-256K", "secp256k1", "1.3.132.0.10"); 088 089 /** 090 * P-384 curve (secp384r1, OID = 1.3.132.0.34). 091 */ 092 public static final Curve P_384 = new Curve("P-384", "secp384r1", "1.3.132.0.34"); 093 094 095 /** 096 * P-521 curve (secp521r1). 097 */ 098 public static final Curve P_521 = new Curve("P-521", "secp521r1", "1.3.132.0.35"); 099 100 101 /** 102 * Ed25519 signature algorithm key pairs. 103 */ 104 public static final Curve Ed25519 = new Curve("Ed25519", "Ed25519", null); 105 106 107 /** 108 * Ed448 signature algorithm key pairs. 109 */ 110 public static final Curve Ed448 = new Curve("Ed448", "Ed448", null); 111 112 113 /** 114 * X25519 function key pairs. 115 */ 116 public static final Curve X25519 = new Curve("X25519", "X25519", null); 117 118 119 /** 120 * X448 function key pairs. 121 */ 122 public static final Curve X448 = new Curve("X448", "X448", null); 123 124 125 /** 126 * The JOSE curve name. 127 */ 128 private final String name; 129 130 131 /** 132 * The standard curve name, {@code null} if not specified. 133 */ 134 private final String stdName; 135 136 137 /** 138 * The standard object identifier for the curve, {@code null} 139 * if not specified. 140 */ 141 private final String oid; 142 143 144 /** 145 * Creates a new cryptographic curve with the specified JOSE name. A 146 * standard curve name and object identifier (OID) are not unspecified. 147 * 148 * @param name The JOSE name of the cryptographic curve. Must not be 149 * {@code null}. 150 */ 151 public Curve(final String name) { 152 153 this(name, null, null); 154 } 155 156 157 /** 158 * Creates a new cryptographic curve with the specified JOSE name, 159 * standard name and object identifier (OID). 160 * 161 * @param name The JOSE name of the cryptographic curve. Must not 162 * be {@code null}. 163 * @param stdName The standard name of the cryptographic curve, 164 * {@code null} if not specified. 165 * @param oid The object identifier (OID) of the cryptographic 166 * curve, {@code null} if not specified. 167 */ 168 public Curve(final String name, final String stdName, final String oid) { 169 170 if (name == null) { 171 throw new IllegalArgumentException("The JOSE cryptographic curve name must not be null"); 172 } 173 174 this.name = name; 175 176 this.stdName = stdName; 177 178 this.oid = oid; 179 } 180 181 182 /** 183 * Returns the JOSE name of this cryptographic curve. 184 * 185 * @return The JOSE name. 186 */ 187 public String getName() { 188 189 return name; 190 } 191 192 193 /** 194 * Returns the standard name of this cryptographic curve. 195 * 196 * @return The standard name, {@code null} if not specified. 197 */ 198 public String getStdName() { 199 200 return stdName; 201 } 202 203 204 /** 205 * Returns the standard object identifier (OID) of this cryptographic 206 * curve. 207 * 208 * @return The OID, {@code null} if not specified. 209 */ 210 public String getOID() { 211 212 return oid; 213 } 214 215 216 /** 217 * Returns the parameter specification for this cryptographic curve. 218 * 219 * @return The EC parameter specification, {@code null} if it cannot be 220 * determined. 221 */ 222 public ECParameterSpec toECParameterSpec() { 223 224 return ECParameterTable.get(this); 225 } 226 227 228 /** 229 * @see #getName 230 */ 231 @Override 232 public String toString() { 233 234 return getName(); 235 } 236 237 238 @Override 239 public boolean equals(final Object object) { 240 241 return object instanceof Curve && 242 this.toString().equals(object.toString()); 243 } 244 245 246 /** 247 * Parses a cryptographic curve from the specified string. 248 * 249 * @param s The string to parse. Must not be {@code null} or empty. 250 * 251 * @return The cryptographic curve. 252 */ 253 public static Curve parse(final String s) { 254 255 if (s == null || s.trim().isEmpty()) { 256 throw new IllegalArgumentException("The cryptographic curve string must not be null or empty"); 257 } 258 259 if (s.equals(P_256.getName())) { 260 return P_256; 261 } else if (s.equals(P_256K.getName())) { 262 return P_256K; 263 } else if (s.equals(SECP256K1.getName())) { 264 return SECP256K1; 265 } else if (s.equals(P_384.getName())) { 266 return P_384; 267 } else if (s.equals(P_521.getName())) { 268 return P_521; 269 } else if (s.equals(Ed25519.getName())) { 270 return Ed25519; 271 } else if (s.equals(Ed448.getName())) { 272 return Ed448; 273 } else if (s.equals(X25519.getName())) { 274 return X25519; 275 } else if (s.equals(X448.getName())) { 276 return X448; 277 } else { 278 return new Curve(s); 279 } 280 } 281 282 283 /** 284 * Gets the cryptographic curve for the specified standard 285 * name. 286 * 287 * @param stdName The standard curve name. May be {@code null}. 288 * 289 * @return The curve, {@code null} if it cannot be determined. 290 */ 291 public static Curve forStdName(final String stdName) { 292 if( "secp256r1".equals(stdName) || "prime256v1".equals(stdName)) { 293 return P_256; 294 } else if("secp256k1".equals(stdName)) { 295 return SECP256K1; 296 } else if("secp384r1".equals(stdName)) { 297 return P_384; 298 } else if("secp521r1".equals(stdName)) { 299 return P_521; 300 } else if (Ed25519.getStdName().equals(stdName)) { 301 return Ed25519; 302 } else if (Ed448.getStdName().equals(stdName)) { 303 return Ed448; 304 } else if (X25519.getStdName().equals(stdName)) { 305 return X25519; 306 } else if (X448.getStdName().equals(stdName)) { 307 return X448; 308 } else { 309 return null; 310 } 311 } 312 313 314 /** 315 * Gets the cryptographic curve for the specified object identifier 316 * (OID). 317 * 318 * @param oid The object OID. May be {@code null}. 319 * 320 * @return The curve, {@code null} if it cannot be determined. 321 */ 322 public static Curve forOID(final String oid) { 323 324 if (P_256.getOID().equals(oid)) { 325 return P_256; 326 } else if (SECP256K1.getOID().equals(oid)) { 327 return SECP256K1; 328 } else if (P_384.getOID().equals(oid)) { 329 return P_384; 330 } else if (P_521.getOID().equals(oid)) { 331 return P_521; 332 } else { 333 return null; 334 } 335 } 336 337 338 /** 339 * Gets the cryptographic curve(s) for the specified JWS algorithm. 340 * 341 * @param alg The JWS algorithm. May be {@code null}. 342 * 343 * @return The curve(s), {@code null} if the JWS algorithm is not curve 344 * based, or the JWS algorithm is not supported. 345 */ 346 public static Set<Curve> forJWSAlgorithm(final JWSAlgorithm alg) { 347 348 if (JWSAlgorithm.ES256.equals(alg)) { 349 return Collections.singleton(P_256); 350 } else if (JWSAlgorithm.ES256K.equals(alg)) { 351 return Collections.singleton(SECP256K1); 352 } else if (JWSAlgorithm.ES384.equals(alg)) { 353 return Collections.singleton(P_384); 354 } else if (JWSAlgorithm.ES512.equals(alg)) { 355 return Collections.singleton(P_521); 356 } else if (JWSAlgorithm.EdDSA.equals(alg)) { 357 return Collections.unmodifiableSet( 358 new HashSet<>(Arrays.asList( 359 Ed25519, 360 Ed448 361 )) 362 ); 363 } else { 364 return null; 365 } 366 } 367 368 369 /** 370 * Gets the cryptographic curve for the specified parameter 371 * specification. 372 * 373 * @param spec The EC parameter spec. May be {@code null}. 374 * 375 * @return The curve, {@code null} if it cannot be determined. 376 */ 377 public static Curve forECParameterSpec(final ECParameterSpec spec) { 378 379 return ECParameterTable.get(spec); 380 } 381}