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