View Javadoc
1   /*
2    * Copyright 2014 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.internal.tcnative;
17  
18  import java.util.Collections;
19  import java.util.HashSet;
20  import java.util.Set;
21  
22  import static io.netty.internal.tcnative.NativeStaticallyReferencedJniMethods.*;
23  
24  /**
25   * Is called during handshake and hooked into openssl via {@code SSL_CTX_set_cert_verify_callback}.
26   *
27   * IMPORTANT: Implementations of this interface should be static as it is stored as a global reference via JNI. This
28   *            means if you use an inner / anonymous class to implement this and also depend on the finalizer of the
29   *            class to free up the SSLContext the finalizer will never run as the object is never GC, due the hard
30   *            reference to the enclosing class. This will most likely result in a memory leak.
31   */
32  public abstract class CertificateVerifier {
33  
34      // WARNING: If you add any new field here you also need to add it to the ERRORS set!
35      public static final int X509_V_OK = x509vOK();
36      public static final int X509_V_ERR_UNSPECIFIED = x509vErrUnspecified();
37      public static final int X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = x509vErrUnableToGetIssuerCert();
38      public static final int X509_V_ERR_UNABLE_TO_GET_CRL = x509vErrUnableToGetCrl();
39      public static final int X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE = x509vErrUnableToDecryptCertSignature();
40      public static final int X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE = x509vErrUnableToDecryptCrlSignature();
41      public static final int X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY = x509vErrUnableToDecodeIssuerPublicKey();
42      public static final int X509_V_ERR_CERT_SIGNATURE_FAILURE = x509vErrCertSignatureFailure();
43      public static final int X509_V_ERR_CRL_SIGNATURE_FAILURE = x509vErrCrlSignatureFailure();
44      public static final int X509_V_ERR_CERT_NOT_YET_VALID = x509vErrCertNotYetValid();
45      public static final int X509_V_ERR_CERT_HAS_EXPIRED = x509vErrCertHasExpired();
46      public static final int X509_V_ERR_CRL_NOT_YET_VALID = x509vErrCrlNotYetValid();
47      public static final int X509_V_ERR_CRL_HAS_EXPIRED = x509vErrCrlHasExpired();
48      public static final int X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = x509vErrErrorInCertNotBeforeField();
49      public static final int X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = x509vErrErrorInCertNotAfterField();
50      public static final int X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD = x509vErrErrorInCrlLastUpdateField();
51      public static final int X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = x509vErrErrorInCrlNextUpdateField();
52      public static final int X509_V_ERR_OUT_OF_MEM = x509vErrOutOfMem();
53      public static final int X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = x509vErrDepthZeroSelfSignedCert();
54      public static final int X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN = x509vErrSelfSignedCertInChain();
55      public static final int X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = x509vErrUnableToGetIssuerCertLocally();
56      public static final int X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE  = x509vErrUnableToVerifyLeafSignature();
57      public static final int X509_V_ERR_CERT_CHAIN_TOO_LONG = x509vErrCertChainTooLong();
58      public static final int X509_V_ERR_CERT_REVOKED = x509vErrCertRevoked();
59      public static final int X509_V_ERR_INVALID_CA = x509vErrInvalidCa();
60      public static final int X509_V_ERR_PATH_LENGTH_EXCEEDED = x509vErrPathLengthExceeded();
61      public static final int X509_V_ERR_INVALID_PURPOSE = x509vErrInvalidPurpose();
62      public static final int X509_V_ERR_CERT_UNTRUSTED = x509vErrCertUntrusted();
63      public static final int X509_V_ERR_CERT_REJECTED = x509vErrCertRejected();
64      public static final int X509_V_ERR_SUBJECT_ISSUER_MISMATCH = x509vErrSubjectIssuerMismatch();
65      public static final int X509_V_ERR_AKID_SKID_MISMATCH = x509vErrAkidSkidMismatch();
66      public static final int X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH = x509vErrAkidIssuerSerialMismatch();
67      public static final int X509_V_ERR_KEYUSAGE_NO_CERTSIGN = x509vErrKeyUsageNoCertSign();
68      public static final int X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER = x509vErrUnableToGetCrlIssuer();
69      public static final int X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION = x509vErrUnhandledCriticalExtension();
70      public static final int X509_V_ERR_KEYUSAGE_NO_CRL_SIGN = x509vErrKeyUsageNoCrlSign();
71      public static final int X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION = x509vErrUnhandledCriticalCrlExtension();
72      public static final int X509_V_ERR_INVALID_NON_CA = x509vErrInvalidNonCa();
73      public static final int X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED = x509vErrProxyPathLengthExceeded();
74      public static final int X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE = x509vErrKeyUsageNoDigitalSignature();
75      public static final int X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED = x509vErrProxyCertificatesNotAllowed();
76      public static final int X509_V_ERR_INVALID_EXTENSION = x509vErrInvalidExtension();
77      public static final int X509_V_ERR_INVALID_POLICY_EXTENSION = x509vErrInvalidPolicyExtension();
78      public static final int X509_V_ERR_NO_EXPLICIT_POLICY = x509vErrNoExplicitPolicy();
79      public static final int X509_V_ERR_DIFFERENT_CRL_SCOPE = x509vErrDifferntCrlScope();
80      public static final int X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE = x509vErrUnsupportedExtensionFeature();
81      public static final int X509_V_ERR_UNNESTED_RESOURCE = x509vErrUnnestedResource();
82      public static final int X509_V_ERR_PERMITTED_VIOLATION = x509vErrPermittedViolation();
83      public static final int X509_V_ERR_EXCLUDED_VIOLATION  = x509vErrExcludedViolation();
84      public static final int X509_V_ERR_SUBTREE_MINMAX = x509vErrSubtreeMinMax();
85      public static final int X509_V_ERR_APPLICATION_VERIFICATION = x509vErrApplicationVerification();
86      public static final int X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE = x509vErrUnsupportedConstraintType();
87      public static final int X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX = x509vErrUnsupportedConstraintSyntax();
88      public static final int X509_V_ERR_UNSUPPORTED_NAME_SYNTAX = x509vErrUnsupportedNameSyntax();
89      public static final int X509_V_ERR_CRL_PATH_VALIDATION_ERROR = x509vErrCrlPathValidationError();
90      public static final int X509_V_ERR_PATH_LOOP = x509vErrPathLoop();
91      public static final int X509_V_ERR_SUITE_B_INVALID_VERSION = x509vErrSuiteBInvalidVersion();
92      public static final int X509_V_ERR_SUITE_B_INVALID_ALGORITHM = x509vErrSuiteBInvalidAlgorithm();
93      public static final int X509_V_ERR_SUITE_B_INVALID_CURVE = x509vErrSuiteBInvalidCurve();
94      public static final int X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM = x509vErrSuiteBInvalidSignatureAlgorithm();
95      public static final int X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED = x509vErrSuiteBLosNotAllowed();
96      public static final int X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 = x509vErrSuiteBCannotSignP384WithP256();
97      public static final int X509_V_ERR_HOSTNAME_MISMATCH = x509vErrHostnameMismatch();
98      public static final int X509_V_ERR_EMAIL_MISMATCH = x509vErrEmailMismatch();
99      public static final int X509_V_ERR_IP_ADDRESS_MISMATCH = x509vErrIpAddressMismatch();
100     public static final int X509_V_ERR_DANE_NO_MATCH = x509vErrDaneNoMatch();
101 
102     private static final Set<Integer> ERRORS;
103 
104     static {
105         Set<Integer> errors = new HashSet<Integer>();
106         errors.add(X509_V_OK);
107         errors.add(X509_V_ERR_UNSPECIFIED);
108         errors.add(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT);
109         errors.add(X509_V_ERR_UNABLE_TO_GET_CRL);
110         errors.add(X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE);
111         errors.add(X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE);
112         errors.add(X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY);
113         errors.add(X509_V_ERR_CERT_SIGNATURE_FAILURE);
114         errors.add(X509_V_ERR_CRL_SIGNATURE_FAILURE);
115         errors.add(X509_V_ERR_CERT_NOT_YET_VALID);
116         errors.add(X509_V_ERR_CERT_HAS_EXPIRED);
117         errors.add(X509_V_ERR_CRL_NOT_YET_VALID);
118         errors.add(X509_V_ERR_CRL_HAS_EXPIRED);
119         errors.add(X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD);
120         errors.add(X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD);
121         errors.add(X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD);
122         errors.add(X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
123         errors.add(X509_V_ERR_OUT_OF_MEM);
124         errors.add(X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT);
125         errors.add(X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN);
126         errors.add(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY);
127         errors.add(X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
128         errors.add(X509_V_ERR_CERT_CHAIN_TOO_LONG);
129         errors.add(X509_V_ERR_CERT_REVOKED);
130         errors.add(X509_V_ERR_INVALID_CA);
131         errors.add(X509_V_ERR_PATH_LENGTH_EXCEEDED);
132         errors.add(X509_V_ERR_INVALID_PURPOSE);
133         errors.add(X509_V_ERR_CERT_UNTRUSTED);
134         errors.add(X509_V_ERR_CERT_REJECTED);
135         errors.add(X509_V_ERR_SUBJECT_ISSUER_MISMATCH);
136         errors.add(X509_V_ERR_AKID_SKID_MISMATCH);
137         errors.add(X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH);
138         errors.add(X509_V_ERR_KEYUSAGE_NO_CERTSIGN);
139         errors.add(X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER);
140         errors.add(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION);
141         errors.add(X509_V_ERR_KEYUSAGE_NO_CRL_SIGN);
142         errors.add(X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION);
143         errors.add(X509_V_ERR_INVALID_NON_CA);
144         errors.add(X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED);
145         errors.add(X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE);
146         errors.add(X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED);
147         errors.add(X509_V_ERR_INVALID_EXTENSION);
148         errors.add(X509_V_ERR_INVALID_POLICY_EXTENSION);
149         errors.add(X509_V_ERR_NO_EXPLICIT_POLICY);
150         errors.add(X509_V_ERR_DIFFERENT_CRL_SCOPE);
151         errors.add(X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE);
152         errors.add(X509_V_ERR_UNNESTED_RESOURCE);
153         errors.add(X509_V_ERR_PERMITTED_VIOLATION);
154         errors.add(X509_V_ERR_EXCLUDED_VIOLATION);
155         errors.add(X509_V_ERR_SUBTREE_MINMAX);
156         errors.add(X509_V_ERR_APPLICATION_VERIFICATION);
157         errors.add(X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE);
158         errors.add(X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX);
159         errors.add(X509_V_ERR_UNSUPPORTED_NAME_SYNTAX);
160         errors.add(X509_V_ERR_CRL_PATH_VALIDATION_ERROR);
161         errors.add(X509_V_ERR_PATH_LOOP);
162         errors.add(X509_V_ERR_SUITE_B_INVALID_VERSION);
163         errors.add(X509_V_ERR_SUITE_B_INVALID_ALGORITHM);
164         errors.add(X509_V_ERR_SUITE_B_INVALID_CURVE);
165         errors.add(X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM);
166         errors.add(X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED);
167         errors.add(X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256);
168         errors.add(X509_V_ERR_HOSTNAME_MISMATCH);
169         errors.add(X509_V_ERR_EMAIL_MISMATCH);
170         errors.add(X509_V_ERR_IP_ADDRESS_MISMATCH);
171         errors.add(X509_V_ERR_DANE_NO_MATCH);
172         ERRORS = Collections.unmodifiableSet(errors);
173     }
174 
175     /**
176      * Returns {@code} true if the given {@code errorCode} is valid, {@code false} otherwise.
177      */
178     public static boolean isValid(int errorCode) {
179         return ERRORS.contains(errorCode);
180     }
181 
182     /**
183      * Returns {@code true} if the passed in certificate chain could be verified and so the handshake
184      * should be successful, {@code false} otherwise.
185      *
186      * @param ssl               the SSL instance
187      * @param x509              the {@code X509} certificate chain
188      * @param authAlgorithm     the auth algorithm
189      * @return verified         {@code true} if verified successful, {@code false} otherwise
190      */
191     public abstract int verify(long ssl, byte[][] x509, String authAlgorithm);
192 }