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