1 /*
2  * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */

15 package com.amazonaws.http.conn.ssl;
16
17 import java.net.Socket;
18
19 import com.amazonaws.http.conn.ssl.privileged.PrivilegedMasterSecretValidator;
20 import com.amazonaws.util.JavaVersionParser;
21 import com.amazonaws.util.JavaVersionParser.JavaVersion;
22
23 public class MasterSecretValidators {
24
25     // Versions that the SKIP-TLS bug has been fixed in for each affected major version
26     private static final JavaVersion FIXED_JAVA_6 = new JavaVersion(1, 6, 0, 91);
27     private static final JavaVersion FIXED_JAVA_7 = new JavaVersion(1, 7, 0, 51);
28     private static final JavaVersion FIXED_JAVA_8 = new JavaVersion(1, 8, 0, 31);
29
30     /**
31      * Interface to validate the master secret of a SSL session
32      */

33     public interface MasterSecretValidator {
34         /**
35          * @param socket
36          *            SSLSocket containing master secret
37          * @return True if master secret is considered valid, false otherwise
38          */

39         public boolean isMasterSecretValid(final Socket socket);
40     }
41
42     /**
43      * The implementation of {@link MasterSecretValidator} depends on the JVM version. Certain JVMs
44      * are affected by a serious bug that could allow a malicious MITM to negotiate a null master
45      * secret. Non-affected JVMs return a dummy implementation that always returns true
46      * 
47      * @see http://www.oracle.com/technetwork/topics/security/cpujan2015-1972971.html
48      * @see https://access.redhat.com/security/cve/CVE-2014-6593
49      * @return The correct implementation of {@link MasterSecretValidator}
50      */

51     public static MasterSecretValidator getMasterSecretValidator() {
52         return getMasterSecretValidator(JavaVersionParser.getCurrentJavaVersion());
53     }
54
55     /**
56      * @param javaVersion
57      *            Current Java version
58      * @return An appropriate {@link MasterSecretValidator} per the Java version in use
59      */

60     public static MasterSecretValidator getMasterSecretValidator(JavaVersion javaVersion) {
61         switch (javaVersion.getKnownVersion()) {
62         case JAVA_6:
63             if (javaVersion.compareTo(FIXED_JAVA_6) < 0) {
64                 return new PrivilegedMasterSecretValidator();
65             }
66             break;
67         case JAVA_7:
68             if (javaVersion.compareTo(FIXED_JAVA_7) < 0) {
69                 return new PrivilegedMasterSecretValidator();
70             }
71             break;
72         case JAVA_8:
73             if (javaVersion.compareTo(FIXED_JAVA_8) < 0) {
74                 return new PrivilegedMasterSecretValidator();
75             }
76             break;
77         default:
78             break;
79
80         }
81         return new NoOpMasterSecretValidator();
82
83     }
84
85     /**
86      * Dummy implementation of {@link MasterSecretValidator} that always returns true. For JVMs that
87      * aren't affected by the SKIP-TLS bug
88      */

89     public static class NoOpMasterSecretValidator implements MasterSecretValidator {
90
91         @Override
92         public boolean isMasterSecretValid(Socket socket) {
93             return true;
94         }
95
96     }
97
98 }
99