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