test/jdk/sun/security/ssl/StatusStapling/java.base/sun/security/ssl/CertStatusReqListV2ExtensionTests.java
branchJDK-8145252-TLS13-branch
changeset 56542 56aaa6cb3693
parent 56541 92cbbfc996f3
child 56543 2352538d2f6e
equal deleted inserted replaced
56541:92cbbfc996f3 56542:56aaa6cb3693
     1 /*
       
     2  * Copyright (c) 2015, 2016, 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.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 package sun.security.ssl;
       
    25 
       
    26 import java.io.IOException;
       
    27 import java.util.*;
       
    28 import java.nio.ByteBuffer;
       
    29 import javax.net.ssl.*;
       
    30 
       
    31 /*
       
    32  * Checks that the hash value for a certificate's issuer name is generated
       
    33  * correctly. Requires any certificate that is not self-signed.
       
    34  *
       
    35  * NOTE: this test uses Sun private classes which are subject to change.
       
    36  */
       
    37 public class CertStatusReqListV2ExtensionTests {
       
    38 
       
    39     private static final boolean debug = false;
       
    40 
       
    41     // Default status_request_v2 extension with two items
       
    42     // 1. Type = ocsp_multi, OCSPStatusRequest is default
       
    43     // 2. Type = ocsp, OCSPStatusRequest is default
       
    44     private static final byte[] CSRLV2_DEF = {
       
    45            0,   14,    2,    0,    4,    0,    0,    0,
       
    46            0,    1,    0,    4,    0,    0,    0,    0
       
    47     };
       
    48 
       
    49     // A status_request_v2 where the item list length is
       
    50     // longer than the provided data
       
    51     private static final byte[] CSRLV2_LEN_TOO_LONG = {
       
    52            0,   18,    2,    0,    4,    0,    0,    0,
       
    53            0,    1,    0,    4,    0,    0,    0,    0
       
    54     };
       
    55 
       
    56     // A status_request_v2 where the item list length is
       
    57     // shorter than the provided data
       
    58     private static final byte[] CSRLV2_LEN_TOO_SHORT = {
       
    59            0,   11,    2,    0,    4,    0,    0,    0,
       
    60            0,    1,    0,    4,    0,    0,    0,    0
       
    61     };
       
    62 
       
    63     // A status_request_v2 extension with a zero-length
       
    64     // certificate_status_req_list (not allowed by the spec)
       
    65     private static final byte[] CSRLV2_INVALID_ZEROLEN = {0, 0};
       
    66 
       
    67     // A status_request_v2 extension with two items (ocsp_multi and ocsp)
       
    68     // using OCSPStatusRequests with 5 ResponderIds and 1 Extension each.
       
    69     private static final byte[] CSRLV2_TWO_NON_DEF_ITEMS = {
       
    70             2,   90,    2,    1,   42,    0,  -13,    0,
       
    71            59,  -95,   57,   48,   55,   49,   16,   48,
       
    72            14,    6,    3,   85,    4,   10,   19,    7,
       
    73            83,  111,  109,  101,   73,  110,   99,   49,
       
    74            16,   48,   14,    6,    3,   85,    4,   11,
       
    75            19,    7,   83,  111,  109,  101,   80,   75,
       
    76            73,   49,   17,   48,   15,    6,    3,   85,
       
    77             4,    3,   19,    8,   83,  111,  109,  101,
       
    78            79,   67,   83,   80,    0,   68,  -95,   66,
       
    79            48,   64,   49,   13,   48,   11,    6,    3,
       
    80            85,    4,   10,   19,    4,   79,  104,   77,
       
    81           121,   49,   14,   48,   12,    6,    3,   85,
       
    82             4,   11,   19,    5,   66,  101,   97,  114,
       
    83           115,   49,   15,   48,   13,    6,    3,   85,
       
    84             4,   11,   19,    6,   84,  105,  103,  101,
       
    85           114,  115,   49,   14,   48,   12,    6,    3,
       
    86            85,    4,    3,   19,    5,   76,  105,  111,
       
    87           110,  115,    0,   58,  -95,   56,   48,   54,
       
    88            49,   16,   48,   14,    6,    3,   85,    4,
       
    89            10,   19,    7,   67,  111,  109,  112,   97,
       
    90           110,  121,   49,   13,   48,   11,    6,    3,
       
    91            85,    4,   11,   19,    4,   87,  101,  115,
       
    92           116,   49,   19,   48,   17,    6,    3,   85,
       
    93             4,    3,   19,   10,   82,  101,  115,  112,
       
    94           111,  110,  100,  101,  114,   49,    0,   24,
       
    95           -94,   22,    4,   20,  -67,  -36,  114,  121,
       
    96            92,  -79,  116,   -1,  102, -107,    7,  -21,
       
    97            18, -113,   64,   76,   96,   -7,  -66,  -63,
       
    98             0,   24,  -94,   22,    4,   20,  -51,  -69,
       
    99           107,  -82,  -39,  -87,   45,   25,   41,   28,
       
   100           -76,  -68,  -11, -110,  -94,  -97,   62,   47,
       
   101            58, -125,    0,   51,   48,   49,   48,   47,
       
   102             6,    9,   43,    6,    1,    5,    5,    7,
       
   103            48,    1,    2,    4,   34,    4,   32,  -26,
       
   104           -81, -120,  -61, -127,  -79,    0,  -39,  -54,
       
   105            49,    3,  -51,  -57,  -85,   19, -126,   94,
       
   106            -2,   21,   26,   98,    6,  105,  -35,  -37,
       
   107           -29,  -73,  101,   53,   44,   15,  -19,    1,
       
   108             1,   42,    0,  -13,    0,   59,  -95,   57,
       
   109            48,   55,   49,   16,   48,   14,    6,    3,
       
   110            85,    4,   10,   19,    7,   83,  111,  109,
       
   111           101,   73,  110,   99,   49,   16,   48,   14,
       
   112             6,    3,   85,    4,   11,   19,    7,   83,
       
   113           111,  109,  101,   80,   75,   73,   49,   17,
       
   114            48,   15,    6,    3,   85,    4,    3,   19,
       
   115             8,   83,  111,  109,  101,   79,   67,   83,
       
   116            80,    0,   68,  -95,   66,   48,   64,   49,
       
   117            13,   48,   11,    6,    3,   85,    4,   10,
       
   118            19,    4,   79,  104,   77,  121,   49,   14,
       
   119            48,   12,    6,    3,   85,    4,   11,   19,
       
   120             5,   66,  101,   97,  114,  115,   49,   15,
       
   121            48,   13,    6,    3,   85,    4,   11,   19,
       
   122             6,   84,  105,  103,  101,  114,  115,   49,
       
   123            14,   48,   12,    6,    3,   85,    4,    3,
       
   124            19,    5,   76,  105,  111,  110,  115,    0,
       
   125            58,  -95,   56,   48,   54,   49,   16,   48,
       
   126            14,    6,    3,   85,    4,   10,   19,    7,
       
   127            67,  111,  109,  112,   97,  110,  121,   49,
       
   128            13,   48,   11,    6,    3,   85,    4,   11,
       
   129            19,    4,   87,  101,  115,  116,   49,   19,
       
   130            48,   17,    6,    3,   85,    4,    3,   19,
       
   131            10,   82,  101,  115,  112,  111,  110,  100,
       
   132           101,  114,   49,    0,   24,  -94,   22,    4,
       
   133            20,  -67,  -36,  114,  121,   92,  -79,  116,
       
   134            -1,  102, -107,    7,  -21,   18, -113,   64,
       
   135            76,   96,   -7,  -66,  -63,    0,   24,  -94,
       
   136            22,    4,   20,  -51,  -69,  107,  -82,  -39,
       
   137           -87,   45,   25,   41,   28,  -76,  -68,  -11,
       
   138          -110,  -94,  -97,   62,   47,   58, -125,    0,
       
   139            51,   48,   49,   48,   47,    6,    9,   43,
       
   140             6,    1,    5,    5,    7,   48,    1,    2,
       
   141             4,   34,    4,   32,  -26,  -81, -120,  -61,
       
   142          -127,  -79,    0,  -39,  -54,   49,    3,  -51,
       
   143           -57,  -85,   19, -126,   94,   -2,   21,   26,
       
   144            98,    6,  105,  -35,  -37,  -29,  -73,  101,
       
   145            53,   44,   15,  -19
       
   146     };
       
   147 
       
   148     public static void main(String[] args) throws Exception {
       
   149         Map<String, TestCase> testList =
       
   150                 new LinkedHashMap<String, TestCase>() {{
       
   151             put("CTOR (default)", testCtorDefault);
       
   152             put("CTOR (List<CertStatusReqItemV2)", testCtorItemList);
       
   153             put("CTOR (HandshakeInStream, getRequestList",
       
   154                     testCtorInStream);
       
   155         }};
       
   156 
       
   157         TestUtils.runTests(testList);
       
   158     }
       
   159 
       
   160     public static final TestCase testCtorDefault = new TestCase() {
       
   161         @Override
       
   162         public Map.Entry<Boolean, String> runTest() {
       
   163             Boolean pass = Boolean.FALSE;
       
   164             String message = null;
       
   165             try {
       
   166                 CertStatusReqListV2Extension csrlV2 =
       
   167                         new CertStatusReqListV2Extension();
       
   168                 HandshakeOutStream hsout = new HandshakeOutStream(null);
       
   169                 csrlV2.send(hsout);
       
   170                 TestUtils.valueCheck(wrapExtData(new byte[0]),
       
   171                         hsout.toByteArray());
       
   172 
       
   173                 // The length should be 4 (2 bytes for the type, 2 for the
       
   174                 // encoding of zero-length
       
   175                 if (csrlV2.length() != 4) {
       
   176                     throw new RuntimeException("Incorrect length from " +
       
   177                             "default object.  Expected 4, got " +
       
   178                             csrlV2.length());
       
   179                 }
       
   180 
       
   181                 // Since there's no data, there are no status_type or request
       
   182                 // data fields defined.  An empty, unmodifiable list should be
       
   183                 // returned when obtained from the extension.
       
   184                 List<CertStatusReqItemV2> itemList = csrlV2.getRequestItems();
       
   185                 if (!itemList.isEmpty()) {
       
   186                     throw new RuntimeException("Default CSRLV2 returned " +
       
   187                             "non-empty request list");
       
   188                 } else {
       
   189                     try {
       
   190                         itemList.add(new CertStatusReqItemV2(
       
   191                                 StatusRequestType.OCSP_MULTI,
       
   192                                 new OCSPStatusRequest()));
       
   193                         throw new RuntimeException("Returned itemList is " +
       
   194                                 "modifiable!");
       
   195                     } catch (UnsupportedOperationException uoe) { }
       
   196                 }
       
   197 
       
   198                 pass = Boolean.TRUE;
       
   199             } catch (Exception e) {
       
   200                 e.printStackTrace(System.out);
       
   201                 message = e.getClass().getName();
       
   202             }
       
   203 
       
   204             return new AbstractMap.SimpleEntry<>(pass, message);
       
   205         }
       
   206     };
       
   207 
       
   208     public static final TestCase testCtorItemList = new TestCase() {
       
   209         @Override
       
   210         public Map.Entry<Boolean, String> runTest() {
       
   211             Boolean pass = Boolean.FALSE;
       
   212             String message = null;
       
   213             OCSPStatusRequest osr = new OCSPStatusRequest();
       
   214             List<CertStatusReqItemV2> noItems = Collections.emptyList();
       
   215             List<CertStatusReqItemV2> defList =
       
   216                     new ArrayList<CertStatusReqItemV2>() {{
       
   217                 add(new CertStatusReqItemV2(StatusRequestType.OCSP_MULTI, osr));
       
   218                 add(new CertStatusReqItemV2(StatusRequestType.OCSP, osr));
       
   219             }};
       
   220             List<CertStatusReqItemV2> unknownTypesList =
       
   221                     new ArrayList<CertStatusReqItemV2>() {{
       
   222                 add(new CertStatusReqItemV2(StatusRequestType.get(8),
       
   223                         new UnknownStatusRequest(new byte[0])));
       
   224                 add(new CertStatusReqItemV2(StatusRequestType.get(12),
       
   225                         new UnknownStatusRequest(new byte[5])));
       
   226             }};
       
   227 
       
   228             try {
       
   229                 HandshakeOutStream hsout = new HandshakeOutStream(null);
       
   230                 StatusRequest basicStatReq = new OCSPStatusRequest();
       
   231 
       
   232                 // Create an extension using a default-style OCSPStatusRequest
       
   233                 // (no responder IDs, no extensions).
       
   234                 CertStatusReqListV2Extension csrlv2 =
       
   235                         new CertStatusReqListV2Extension(defList);
       
   236                 csrlv2.send(hsout);
       
   237                 TestUtils.valueCheck(wrapExtData(CSRLV2_DEF),
       
   238                         hsout.toByteArray());
       
   239                 hsout.reset();
       
   240 
       
   241                 // Create the extension using a StatusRequestType not already
       
   242                 // instantiated as a static StatusRequestType
       
   243                 // (e.g. OCSP/OCSP_MULTI)
       
   244                 csrlv2 = new CertStatusReqListV2Extension(unknownTypesList);
       
   245                 List<CertStatusReqItemV2> itemList = csrlv2.getRequestItems();
       
   246                 if (itemList.size() != unknownTypesList.size()) {
       
   247                     throw new RuntimeException("Custom CSRLV2 returned " +
       
   248                             "an incorrect number of items: expected " +
       
   249                             unknownTypesList.size() + ", got " +
       
   250                             itemList.size());
       
   251                 } else {
       
   252                     // Verify that the list is unmodifiable
       
   253                     try {
       
   254                         itemList.add(new CertStatusReqItemV2(
       
   255                                 StatusRequestType.OCSP_MULTI,
       
   256                                 new OCSPStatusRequest()));
       
   257                         throw new RuntimeException("Returned itemList is " +
       
   258                                 "modifiable!");
       
   259                     } catch (UnsupportedOperationException uoe) { }
       
   260                 }
       
   261 
       
   262                 // Pass a null value for the item list.  This should throw
       
   263                 // an exception
       
   264                 try {
       
   265                     CertStatusReqListV2Extension csrlv2Null =
       
   266                             new CertStatusReqListV2Extension(null);
       
   267                     throw new RuntimeException("Constructor accepted a " +
       
   268                             "null request list");
       
   269                 } catch (NullPointerException npe) { }
       
   270 
       
   271                 pass = Boolean.TRUE;
       
   272             } catch (Exception e) {
       
   273                 e.printStackTrace(System.out);
       
   274                 message = e.getClass().getName();
       
   275             }
       
   276 
       
   277             return new AbstractMap.SimpleEntry<>(pass, message);
       
   278         }
       
   279     };
       
   280 
       
   281     // Test the constructor that builds the ob ject using data from
       
   282     // a HandshakeInStream
       
   283     // This also tests the length, getReqType and getRequest methods
       
   284     public static final TestCase testCtorInStream = new TestCase() {
       
   285         @Override
       
   286         public Map.Entry<Boolean, String> runTest() {
       
   287             Boolean pass = Boolean.FALSE;
       
   288             String message = null;
       
   289             OCSPStatusRequest osr;
       
   290             CertStatusReqListV2Extension csrlv2;
       
   291 
       
   292             try {
       
   293                 // To simulate the extension coming in a ServerHello, the
       
   294                 // type and length would already be read by HelloExtensions
       
   295                 // and there is no extension data
       
   296                 HandshakeInStream hsis = new HandshakeInStream();
       
   297                 hsis.incomingRecord(ByteBuffer.wrap(new byte[0]));
       
   298                 csrlv2 = new CertStatusReqListV2Extension(hsis,
       
   299                         hsis.available());
       
   300 
       
   301                 // Verify length/request list
       
   302                 if (csrlv2.length() != 4) {
       
   303                      throw new RuntimeException("Invalid length: received " +
       
   304                             csrlv2.length() + ", expected 4");
       
   305                 } else {
       
   306                     List<CertStatusReqItemV2> itemList =
       
   307                             csrlv2.getRequestItems();
       
   308                     if (!itemList.isEmpty()) {
       
   309                         throw new RuntimeException("Default CSRLV2 returned " +
       
   310                                 "non-empty request list");
       
   311                     } else {
       
   312                         try {
       
   313                             itemList.add(new CertStatusReqItemV2(
       
   314                                     StatusRequestType.OCSP_MULTI,
       
   315                                     new OCSPStatusRequest()));
       
   316                             throw new RuntimeException("Returned itemList is " +
       
   317                                     "modifiable!");
       
   318                         } catch (UnsupportedOperationException uoe) { }
       
   319                     }
       
   320                 }
       
   321 
       
   322                 // Try the an extension with our basic client-generated
       
   323                 // status_request_v2 (2 items, ocsp_multi and ocsp, each with
       
   324                 // a default OCSPStatusRequest
       
   325                 hsis = new HandshakeInStream();
       
   326                 hsis.incomingRecord(ByteBuffer.wrap(CSRLV2_DEF));
       
   327                 csrlv2 = new CertStatusReqListV2Extension(hsis,
       
   328                         hsis.available());
       
   329                 if (csrlv2.length() != (CSRLV2_DEF.length + 4)) {
       
   330                     throw new RuntimeException("Invalid length: received " +
       
   331                             csrlv2.length() + ", expected " +
       
   332                             CSRLV2_DEF.length + 4);
       
   333                 } else {
       
   334                     List<CertStatusReqItemV2> itemList =
       
   335                             csrlv2.getRequestItems();
       
   336                     if (itemList.size() != 2) {
       
   337                         throw new RuntimeException("Unexpected number of " +
       
   338                                 "items request list, expected 2, got " +
       
   339                                 itemList.size());
       
   340                     } else {
       
   341                         try {
       
   342                             itemList.add(new CertStatusReqItemV2(
       
   343                                     StatusRequestType.OCSP_MULTI,
       
   344                                     new OCSPStatusRequest()));
       
   345                             throw new RuntimeException("Returned itemList is " +
       
   346                                     "modifiable!");
       
   347                         } catch (UnsupportedOperationException uoe) { }
       
   348                     }
       
   349                 }
       
   350 
       
   351                 // Try incoming data with an illegal zero-length
       
   352                 // certificate_status_req_list
       
   353                 try {
       
   354                     hsis = new HandshakeInStream();
       
   355                     hsis.incomingRecord(
       
   356                             ByteBuffer.wrap(CSRLV2_INVALID_ZEROLEN));
       
   357                     csrlv2 = new CertStatusReqListV2Extension(hsis,
       
   358                             hsis.available());
       
   359                     throw new RuntimeException("Unxpected successful " +
       
   360                             "object construction");
       
   361                 } catch (SSLException ssle) { }
       
   362 
       
   363                 // Try extensions where the certificate_status_req_list length
       
   364                 // is either too long or too short
       
   365                 try {
       
   366                     hsis = new HandshakeInStream();
       
   367                     hsis.incomingRecord(ByteBuffer.wrap(CSRLV2_LEN_TOO_LONG));
       
   368                     csrlv2 = new CertStatusReqListV2Extension(hsis,
       
   369                             hsis.available());
       
   370                     throw new RuntimeException("Unxpected successful " +
       
   371                             "object construction");
       
   372                 } catch (SSLException ssle) { }
       
   373 
       
   374                 try {
       
   375                     hsis = new HandshakeInStream();
       
   376                     hsis.incomingRecord(ByteBuffer.wrap(CSRLV2_LEN_TOO_SHORT));
       
   377                     csrlv2 = new CertStatusReqListV2Extension(hsis,
       
   378                             hsis.available());
       
   379                     throw new RuntimeException("Unxpected successful " +
       
   380                             "object construction");
       
   381                 } catch (SSLException ssle) { }
       
   382 
       
   383                 pass = Boolean.TRUE;
       
   384             } catch (Exception e) {
       
   385                 e.printStackTrace(System.out);
       
   386                 message = e.getClass().getName();
       
   387             }
       
   388 
       
   389             return new AbstractMap.SimpleEntry<>(pass, message);
       
   390         }
       
   391     };
       
   392 
       
   393     // Take CSRE extension data and add extension type and length decorations
       
   394     private static byte[] wrapExtData(byte[] extData) {
       
   395         int bufferLen = extData.length + 4;
       
   396         ByteBuffer bb = ByteBuffer.allocate(bufferLen);
       
   397 
       
   398         bb.putShort((short)ExtensionType.EXT_STATUS_REQUEST_V2.id);
       
   399         bb.putShort((short)extData.length);
       
   400         if (extData.length != 0) {
       
   401             bb.put(extData);
       
   402         }
       
   403         return bb.array();
       
   404     }
       
   405 }