1 /* 2 * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.ssl; 27 28 import java.security.*; 29 import java.security.interfaces.ECPrivateKey; 30 import java.security.spec.AlgorithmParameterSpec; 31 import java.security.spec.ECParameterSpec; 32 import java.security.spec.MGF1ParameterSpec; 33 import java.security.spec.PSSParameterSpec; 34 import java.util.ArrayList; 35 import java.util.Arrays; 36 import java.util.Collection; 37 import java.util.Collections; 38 import java.util.EnumSet; 39 import java.util.LinkedList; 40 import java.util.List; 41 import java.util.Set; 42 import sun.security.ssl.SupportedGroupsExtension.NamedGroup; 43 import sun.security.ssl.SupportedGroupsExtension.NamedGroupType; 44 import sun.security.ssl.X509Authentication.X509Possession; 45 import sun.security.util.KeyUtil; 46 47 enum SignatureScheme { 48 // EdDSA algorithms 49 ED25519 (0x0807, "ed25519", "ed25519", 50 "ed25519", 51 ProtocolVersion.PROTOCOLS_OF_13), 52 ED448 (0x0808, "ed448", "ed448", 53 "ed448", 54 ProtocolVersion.PROTOCOLS_OF_13), 55 56 // ECDSA algorithms 57 ECDSA_SECP256R1_SHA256 (0x0403, "ecdsa_secp256r1_sha256", 58 "SHA256withECDSA", 59 "EC", 60 NamedGroup.SECP256_R1, 61 ProtocolVersion.PROTOCOLS_TO_13), 62 ECDSA_SECP384R1_SHA384 (0x0503, "ecdsa_secp384r1_sha384", 63 "SHA384withECDSA", 64 "EC", 65 NamedGroup.SECP384_R1, 66 ProtocolVersion.PROTOCOLS_TO_13), 67 ECDSA_SECP521R1_SHA512 (0x0603, "ecdsa_secp521r1_sha512", 68 "SHA512withECDSA", 69 "EC", 70 NamedGroup.SECP521_R1, 71 ProtocolVersion.PROTOCOLS_TO_13), 72 73 // RSASSA-PSS algorithms with public key OID rsaEncryption 74 // 75 // The minimalKeySize is calculated as (See RFC 8017 for details): 76 // hash length + salt length + 16 77 RSA_PSS_RSAE_SHA256 (0x0804, "rsa_pss_rsae_sha256", 78 "RSASSA-PSS", "RSA", 79 SigAlgParamSpec.RSA_PSS_SHA256, 528, 80 ProtocolVersion.PROTOCOLS_12_13), 81 RSA_PSS_RSAE_SHA384 (0x0805, "rsa_pss_rsae_sha384", 82 "RSASSA-PSS", "RSA", 83 SigAlgParamSpec.RSA_PSS_SHA384, 784, 84 ProtocolVersion.PROTOCOLS_12_13), 85 RSA_PSS_RSAE_SHA512 (0x0806, "rsa_pss_rsae_sha512", 86 "RSASSA-PSS", "RSA", 87 SigAlgParamSpec.RSA_PSS_SHA512, 1040, 88 ProtocolVersion.PROTOCOLS_12_13), 89 90 // RSASSA-PSS algorithms with public key OID RSASSA-PSS 91 // 92 // The minimalKeySize is calculated as (See RFC 8017 for details): 93 // hash length + salt length + 16 94 RSA_PSS_PSS_SHA256 (0x0809, "rsa_pss_pss_sha256", 95 "RSASSA-PSS", "RSASSA-PSS", 96 SigAlgParamSpec.RSA_PSS_SHA256, 528, 97 ProtocolVersion.PROTOCOLS_12_13), 98 RSA_PSS_PSS_SHA384 (0x080A, "rsa_pss_pss_sha384", 99 "RSASSA-PSS", "RSASSA-PSS", 100 SigAlgParamSpec.RSA_PSS_SHA384, 784, 101 ProtocolVersion.PROTOCOLS_12_13), 102 RSA_PSS_PSS_SHA512 (0x080B, "rsa_pss_pss_sha512", 103 "RSASSA-PSS", "RSASSA-PSS", 104 SigAlgParamSpec.RSA_PSS_SHA512, 1040, 105 ProtocolVersion.PROTOCOLS_12_13), 106 107 // RSASSA-PKCS1-v1_5 algorithms 108 RSA_PKCS1_SHA256 (0x0401, "rsa_pkcs1_sha256", "SHA256withRSA", 109 "RSA", null, null, 511, 110 ProtocolVersion.PROTOCOLS_TO_13, 111 ProtocolVersion.PROTOCOLS_TO_12), 112 RSA_PKCS1_SHA384 (0x0501, "rsa_pkcs1_sha384", "SHA384withRSA", 113 "RSA", null, null, 768, 114 ProtocolVersion.PROTOCOLS_TO_13, 115 ProtocolVersion.PROTOCOLS_TO_12), 116 RSA_PKCS1_SHA512 (0x0601, "rsa_pkcs1_sha512", "SHA512withRSA", 117 "RSA", null, null, 768, 118 ProtocolVersion.PROTOCOLS_TO_13, 119 ProtocolVersion.PROTOCOLS_TO_12), 120 121 // Legacy algorithms 122 DSA_SHA256 (0x0402, "dsa_sha256", "SHA256withDSA", 123 "DSA", 124 ProtocolVersion.PROTOCOLS_TO_12), 125 ECDSA_SHA224 (0x0303, "ecdsa_sha224", "SHA224withECDSA", 126 "EC", 127 ProtocolVersion.PROTOCOLS_TO_12), 128 RSA_SHA224 (0x0301, "rsa_sha224", "SHA224withRSA", 129 "RSA", 511, 130 ProtocolVersion.PROTOCOLS_TO_12), 131 DSA_SHA224 (0x0302, "dsa_sha224", "SHA224withDSA", 132 "DSA", 133 ProtocolVersion.PROTOCOLS_TO_12), 134 ECDSA_SHA1 (0x0203, "ecdsa_sha1", "SHA1withECDSA", 135 "EC", 136 ProtocolVersion.PROTOCOLS_TO_13), 137 RSA_PKCS1_SHA1 (0x0201, "rsa_pkcs1_sha1", "SHA1withRSA", 138 "RSA", null, null, 511, 139 ProtocolVersion.PROTOCOLS_TO_13, 140 ProtocolVersion.PROTOCOLS_TO_12), 141 DSA_SHA1 (0x0202, "dsa_sha1", "SHA1withDSA", 142 "DSA", 143 ProtocolVersion.PROTOCOLS_TO_12), 144 RSA_MD5 (0x0101, "rsa_md5", "MD5withRSA", 145 "RSA", 511, 146 ProtocolVersion.PROTOCOLS_TO_12); 147 148 final int id; // hash + signature 149 final String name; // literal name 150 private final String algorithm; // signature algorithm 151 final String keyAlgorithm; // signature key algorithm 152 private final AlgorithmParameterSpec signAlgParameter; 153 private final NamedGroup namedGroup; // associated named group 154 155 // The minimal required key size in bits. 156 // 157 // Only need to check RSA algorithm at present. RSA keys of 512 bits 158 // have been shown to be practically breakable, it does not make much 159 // sense to use the strong hash algorithm for keys whose key size less 160 // than 512 bits. So it is not necessary to calculate the minimal 161 // required key size exactly for a hash algorithm. 162 // 163 // Note that some provider may use 511 bits for 512-bit strength RSA keys. 164 final int minimalKeySize; 165 final List<ProtocolVersion> supportedProtocols; 166 167 // Some signature schemes are supported in different versions for handshake 168 // messages and certificates. This field holds the supported protocols 169 // for handshake messages. 170 final List<ProtocolVersion> handshakeSupportedProtocols; 171 final boolean isAvailable; 172 173 private static final String[] hashAlgorithms = new String[] { 174 "none", "md5", "sha1", "sha224", 175 "sha256", "sha384", "sha512" 176 }; 177 178 private static final String[] signatureAlgorithms = new String[] { 179 "anonymous", "rsa", "dsa", "ecdsa", 180 }; 181 182 static enum SigAlgParamSpec { // support RSASSA-PSS only now 183 RSA_PSS_SHA256 ("SHA-256", 32), 184 RSA_PSS_SHA384 ("SHA-384", 48), 185 RSA_PSS_SHA512 ("SHA-512", 64); 186 187 final private AlgorithmParameterSpec parameterSpec; 188 final boolean isAvailable; 189 190 SigAlgParamSpec(String hash, int saltLength) { 191 // See RFC 8017 192 PSSParameterSpec pssParamSpec = 193 new PSSParameterSpec(hash, "MGF1", 194 new MGF1ParameterSpec(hash), saltLength, 1); 195 196 boolean mediator = true; 197 try { 198 Signature signer = Signature.getInstance("RSASSA-PSS"); 199 signer.setParameter(pssParamSpec); 200 } catch (InvalidAlgorithmParameterException | 201 NoSuchAlgorithmException exp) { 202 mediator = false; 203 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 204 SSLLogger.warning( 205 "RSASSA-PSS signature with " + hash + 206 " is not supported by the underlying providers", exp); 207 } 208 } 209 210 this.isAvailable = mediator; 211 this.parameterSpec = mediator ? pssParamSpec : null; 212 } 213 214 AlgorithmParameterSpec getParameterSpec() { 215 return parameterSpec; 216 } 217 } 218 219 // performance optimization 220 private static final Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET = 221 Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE)); 222 223 224 private SignatureScheme(int id, String name, 225 String algorithm, String keyAlgorithm, 226 ProtocolVersion[] supportedProtocols) { 227 this(id, name, algorithm, keyAlgorithm, -1, supportedProtocols); 228 } 229 230 private SignatureScheme(int id, String name, 231 String algorithm, String keyAlgorithm, 232 int minimalKeySize, 233 ProtocolVersion[] supportedProtocols) { 234 this(id, name, algorithm, keyAlgorithm, 235 null, minimalKeySize, supportedProtocols); 236 } 237 238 private SignatureScheme(int id, String name, 239 String algorithm, String keyAlgorithm, 240 SigAlgParamSpec signAlgParamSpec, int minimalKeySize, 241 ProtocolVersion[] supportedProtocols) { 242 this(id, name, algorithm, keyAlgorithm, 243 signAlgParamSpec, null, minimalKeySize, 244 supportedProtocols, supportedProtocols); 245 } 246 247 private SignatureScheme(int id, String name, 248 String algorithm, String keyAlgorithm, 249 NamedGroup namedGroup, 250 ProtocolVersion[] supportedProtocols) { 251 this(id, name, algorithm, keyAlgorithm, 252 null, namedGroup, -1, 253 supportedProtocols, supportedProtocols); 254 } 255 256 private SignatureScheme(int id, String name, 257 String algorithm, String keyAlgorithm, 258 SigAlgParamSpec signAlgParamSpec, 259 NamedGroup namedGroup, int minimalKeySize, 260 ProtocolVersion[] supportedProtocols, 261 ProtocolVersion[] handshakeSupportedProtocols) { 262 this.id = id; 263 this.name = name; 264 this.algorithm = algorithm; 265 this.keyAlgorithm = keyAlgorithm; 266 this.signAlgParameter = 267 signAlgParamSpec != null ? signAlgParamSpec.parameterSpec : null; 268 this.namedGroup = namedGroup; 269 this.minimalKeySize = minimalKeySize; 270 this.supportedProtocols = Arrays.asList(supportedProtocols); 271 this.handshakeSupportedProtocols = 272 Arrays.asList(handshakeSupportedProtocols); 273 274 boolean mediator = true; 275 if (signAlgParamSpec != null) { 276 mediator = signAlgParamSpec.isAvailable; 277 } else { 278 try { 279 Signature.getInstance(algorithm); 280 } catch (Exception e) { 281 mediator = false; 282 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 283 SSLLogger.warning( 284 "Signature algorithm, " + algorithm + 285 ", is not supported by the underlying providers"); 286 } 287 } 288 } 289 290 if (mediator && ((id >> 8) & 0xFF) == 0x03) { // SHA224 291 // There are some problems to use SHA224 on Windows. 292 if (Security.getProvider("SunMSCAPI") != null) { 293 mediator = false; 294 } 295 } 296 297 this.isAvailable = mediator; 298 } 299 300 static SignatureScheme valueOf(int id) { 301 for (SignatureScheme ss: SignatureScheme.values()) { 302 if (ss.id == id) { 303 return ss; 304 } 305 } 306 307 return null; 308 } 309 310 static String nameOf(int id) { 311 for (SignatureScheme ss: SignatureScheme.values()) { 312 if (ss.id == id) { 313 return ss.name; 314 } 315 } 316 317 // Use TLS 1.2 style name for unknown signature scheme. 318 int hashId = ((id >> 8) & 0xFF); 319 int signId = (id & 0xFF); 320 String hashName = (hashId >= hashAlgorithms.length) ? 321 "UNDEFINED-HASH(" + hashId + ")" : hashAlgorithms[hashId]; 322 String signName = (signId >= signatureAlgorithms.length) ? 323 "UNDEFINED-SIGNATURE(" + signId + ")" : 324 signatureAlgorithms[signId]; 325 326 return signName + "_" + hashName; 327 } 328 329 // Return the size of a SignatureScheme structure in TLS record 330 static int sizeInRecord() { 331 return 2; 332 } 333 334 // Get local supported algorithm collection complying to algorithm 335 // constraints. 336 static List<SignatureScheme> getSupportedAlgorithms( 337 AlgorithmConstraints constraints, 338 List<ProtocolVersion> activeProtocols) { 339 List<SignatureScheme> supported = new LinkedList<>(); 340 for (SignatureScheme ss: SignatureScheme.values()) { 341 if (!ss.isAvailable) { 342 continue; 343 } 344 345 boolean isMatch = false; 346 for (ProtocolVersion pv : activeProtocols) { 347 if (ss.supportedProtocols.contains(pv)) { 348 isMatch = true; 349 break; 350 } 351 } 352 353 if (isMatch) { 354 if (constraints.permits( 355 SIGNATURE_PRIMITIVE_SET, ss.algorithm, null)) { 356 supported.add(ss); 357 } else if (SSLLogger.isOn && 358 SSLLogger.isOn("ssl,handshake,verbose")) { 359 SSLLogger.finest( 360 "Ignore disabled signature scheme: " + ss.name); 361 } 362 } else if (SSLLogger.isOn && 363 SSLLogger.isOn("ssl,handshake,verbose")) { 364 SSLLogger.finest( 365 "Ignore inactive signature scheme: " + ss.name); 366 } 367 } 368 369 return supported; 370 } 371 372 static List<SignatureScheme> getSupportedAlgorithms( 373 AlgorithmConstraints constraints, 374 ProtocolVersion protocolVersion, int[] algorithmIds) { 375 List<SignatureScheme> supported = new LinkedList<>(); 376 for (int ssid : algorithmIds) { 377 SignatureScheme ss = SignatureScheme.valueOf(ssid); 378 if (ss == null) { 379 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 380 SSLLogger.warning( 381 "Unsupported signature scheme: " + 382 SignatureScheme.nameOf(ssid)); 383 } 384 } else if (ss.isAvailable && 385 ss.supportedProtocols.contains(protocolVersion) && 386 constraints.permits(SIGNATURE_PRIMITIVE_SET, 387 ss.algorithm, null)) { 388 supported.add(ss); 389 } else { 390 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 391 SSLLogger.warning( 392 "Unsupported signature scheme: " + ss.name); 393 } 394 } 395 } 396 397 return supported; 398 } 399 400 static SignatureScheme getPreferableAlgorithm( 401 List<SignatureScheme> schemes, 402 SignatureScheme certScheme, 403 ProtocolVersion version) { 404 405 for (SignatureScheme ss : schemes) { 406 if (ss.isAvailable && 407 ss.handshakeSupportedProtocols.contains(version) && 408 certScheme.keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm)) { 409 410 return ss; 411 } 412 } 413 414 return null; 415 } 416 417 static SignatureScheme getPreferableAlgorithm( 418 List<SignatureScheme> schemes, 419 X509Possession x509Possession, 420 ProtocolVersion version) { 421 422 PrivateKey signingKey = x509Possession.popPrivateKey; 423 String keyAlgorithm = signingKey.getAlgorithm(); 424 int keySize; 425 // Only need to check RSA algorithm at present. 426 if (keyAlgorithm.equalsIgnoreCase("RSA") || 427 keyAlgorithm.equalsIgnoreCase("RSASSA-PSS")) { 428 keySize = KeyUtil.getKeySize(signingKey); 429 } else { 430 keySize = Integer.MAX_VALUE; 431 } 432 for (SignatureScheme ss : schemes) { 433 if (ss.isAvailable && (keySize >= ss.minimalKeySize) && 434 ss.handshakeSupportedProtocols.contains(version) && 435 keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm)) { 436 if (ss.namedGroup != null && 437 ss.namedGroup.type == NamedGroupType.NAMED_GROUP_ECDHE) { 438 ECParameterSpec params = 439 x509Possession.getECParameterSpec(); 440 if (params != null && 441 ss.namedGroup == NamedGroup.valueOf(params)) { 442 return ss; 443 } 444 } else { 445 return ss; 446 } 447 } 448 } 449 450 return null; 451 } 452 453 static String[] getAlgorithmNames(Collection<SignatureScheme> schemes) { 454 if (schemes != null) { 455 ArrayList<String> names = new ArrayList<>(schemes.size()); 456 for (SignatureScheme scheme : schemes) { 457 names.add(scheme.algorithm); 458 } 459 460 return names.toArray(new String[0]); 461 } 462 463 return new String[0]; 464 } 465 466 Signature getSignature(Key key) throws NoSuchAlgorithmException, 467 InvalidAlgorithmParameterException, InvalidKeyException { 468 if (!isAvailable) { 469 return null; 470 } 471 472 Signature signer = Signature.getInstance(algorithm); 473 if (key instanceof PublicKey) { 474 signer.initVerify((PublicKey)(key)); 475 } else { 476 signer.initSign((PrivateKey)key); 477 } 478 479 // Important note: Please don't set the parameters before signature 480 // or verification initialization, so that the crypto provider can 481 // be selected properly. 482 if (signAlgParameter != null) { 483 signer.setParameter(signAlgParameter); 484 } 485 486 return signer; 487 } 488 }