View Javadoc
1   /*
2    * Copyright 2016 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.handler.ssl;
17  
18  import io.netty.internal.tcnative.CertificateVerifier;
19  
20  import java.security.cert.CertificateException;
21  
22  /**
23   * A special {@link CertificateException} which allows to specify which error code is included in the
24   * SSL Record. This only work when {@link SslProvider#OPENSSL} or {@link SslProvider#OPENSSL_REFCNT} is used.
25   */
26  public final class OpenSslCertificateException extends CertificateException {
27      private static final long serialVersionUID = 5542675253797129798L;
28  
29      private final int errorCode;
30  
31      /**
32       * Construct a new exception with the
33       * <a href="https://www.openssl.org/docs/manmaster/apps/verify.html">error code</a>.
34       */
35      public OpenSslCertificateException(int errorCode) {
36          this((String) null, errorCode);
37      }
38  
39      /**
40       * Construct a new exception with the msg and
41       * <a href="https://www.openssl.org/docs/manmaster/apps/verify.html">error code</a> .
42       */
43      public OpenSslCertificateException(String msg, int errorCode) {
44          super(msg);
45          this.errorCode = checkErrorCode(errorCode);
46      }
47  
48      /**
49       * Construct a new exception with the msg, cause and
50       * <a href="https://www.openssl.org/docs/manmaster/apps/verify.html">error code</a> .
51       */
52      public OpenSslCertificateException(String message, Throwable cause, int errorCode) {
53          super(message, cause);
54          this.errorCode = checkErrorCode(errorCode);
55      }
56  
57      /**
58       * Construct a new exception with the cause and
59       * <a href="https://www.openssl.org/docs/manmaster/apps/verify.html">error code</a> .
60       */
61      public OpenSslCertificateException(Throwable cause, int errorCode) {
62          this(null, cause, errorCode);
63      }
64  
65      /**
66       * Return the <a href="https://www.openssl.org/docs/man1.0.2/apps/verify.html">error code</a> to use.
67       */
68      public int errorCode() {
69          return errorCode;
70      }
71  
72      private static int checkErrorCode(int errorCode) {
73          // Call OpenSsl.isAvailable() to ensure we try to load the native lib as CertificateVerifier.isValid(...)
74          // will depend on it. If loading fails we will just skip the validation.
75          if (OpenSsl.isAvailable() && !CertificateVerifier.isValid(errorCode)) {
76              throw new IllegalArgumentException("errorCode '" + errorCode +
77                      "' invalid, see https://www.openssl.org/docs/man1.0.2/apps/verify.html.");
78          }
79          return errorCode;
80      }
81  }