1 /*
   2  * Copyright (c) 2012, 2015, 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 //
  25 // SunJSSE does not support dynamic system properties, no way to re-use
  26 // system properties in samevm/agentvm mode.
  27 //
  28 
  29 /*
  30  * @test
  31  * @bug 7166570
  32  * @summary JSSE certificate validation has started to fail for
  33  *     certificate chains
  34  * @run main/othervm BasicConstraints PKIX
  35  * @run main/othervm BasicConstraints SunX509
  36  */
  37 
  38 import java.net.*;
  39 import java.util.*;
  40 import java.io.*;
  41 import javax.net.ssl.*;
  42 import java.security.Security;
  43 import java.security.KeyStore;
  44 import java.security.KeyFactory;
  45 import java.security.cert.*;
  46 import java.security.spec.*;
  47 import java.security.interfaces.*;
  48 import java.math.BigInteger;
  49 
  50 import java.util.Base64;
  51 
  52 public class BasicConstraints {
  53 
  54     /*
  55      * =============================================================
  56      * Set the various variables needed for the tests, then
  57      * specify what tests to run on each side.
  58      */
  59 
  60     /*
  61      * Should we run the client or server in a separate thread?
  62      * Both sides can throw exceptions, but do you have a preference
  63      * as to which side should be the main thread.
  64      */
  65     static boolean separateServerThread = true;
  66 
  67     /*
  68      * Where do we find the keystores?
  69      */
  70     // Certificate information:
  71     // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce
  72     // Validity
  73     //     Not Before: May  5 02:40:50 2012 GMT
  74     //     Not After : Apr 15 02:40:50 2033 GMT
  75     // Subject: C=US, O=Java, OU=SunJSSE Test Serivce
  76     // X509v3 Subject Key Identifier:
  77     //     DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B
  78     // X509v3 Authority Key Identifier:
  79     //     keyid:DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B
  80     //     DirName:/C=US/O=Java/OU=SunJSSE Test Serivce
  81     //     serial:00
  82     static String trusedCertStr =
  83         "-----BEGIN CERTIFICATE-----\n" +
  84         "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJVUzEN\n" +
  85         "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
  86         "MTIwNTA1MDI0MDUwWhcNMzMwNDE1MDI0MDUwWjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
  87         "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
  88         "KoZIhvcNAQEBBQADgY0AMIGJAoGBANtiq0AIJK+iVRwFrqcD7fYXTCbMYC5Qz/k6\n" +
  89         "AXBy7/1rI8wDhEJLE3m/+NSqiJwZcmdq2dNh/1fJFrwvzuURbc9+paOBWeHbN+Sc\n" +
  90         "x3huw91oPZme385VpoK3G13rSE114S/rF4DM9mz4EStFhSHXATjtdbskNOAYGLTV\n" +
  91         "x8uEy9GbAgMBAAGjgaUwgaIwHQYDVR0OBBYEFN1OjSoRwIMD8Kzror/58n3IaR+b\n" +
  92         "MGMGA1UdIwRcMFqAFN1OjSoRwIMD8Kzror/58n3IaR+boT+kPTA7MQswCQYDVQQG\n" +
  93         "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
  94         "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEC\n" +
  95         "BQADgYEAjjkJesQrkbr36N40egybaIxw7RcqT6iy5fkAGS1JYlBDk8uSCK1o6bCH\n" +
  96         "ls5EpYcGeEoabSS73WRdkO1lgeyWDduO4ef8cCCSpmpT6/YdZG0QS1PtcREeVig+\n" +
  97         "Zr25jNemS4ADHX0aaXP4kiV/G80cR7nX5t5XCUm4bYdbwM07NgI=\n" +
  98         "-----END CERTIFICATE-----";
  99     static String trustedPrivateKey = // Private key in the format of PKCS#8
 100         "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANtiq0AIJK+iVRwF\n" +
 101         "rqcD7fYXTCbMYC5Qz/k6AXBy7/1rI8wDhEJLE3m/+NSqiJwZcmdq2dNh/1fJFrwv\n" +
 102         "zuURbc9+paOBWeHbN+Scx3huw91oPZme385VpoK3G13rSE114S/rF4DM9mz4EStF\n" +
 103         "hSHXATjtdbskNOAYGLTVx8uEy9GbAgMBAAECgYEA2VjHkIiA0ABjkX+PqKeb+VLb\n" +
 104         "fxS7tSca5C8zfdRhLxAWRui0/3ihst0eCJNrBDuxvAOACovsDWyLuaUjtI2v2ysz\n" +
 105         "vz6SPyGy82PhQOFzyKQuQ814N6EpothpiZzF0yFchfKIGhUsdY89UrGs9nM7m6NT\n" +
 106         "rztYvgIu4avg2VPR2AECQQD+pFAqipR2BplQRIuuRSZfHRxvoEyDjT1xnHJsC6WP\n" +
 107         "I5hCLghL91MhQGWbP4EJMKYQOTRVukWlcp2Kycpf+P5hAkEA3I43gmVUAPEdyZdY\n" +
 108         "fatW7OaLlbbYJb6qEtpCZ1Rwe/BIvm6H6E3qSi/lpz7Ia7WDulpbF6BawHH3pRFq\n" +
 109         "CUY5ewJBAP3pUDqrRpBN0jB0uSeDslhjSciQ+dqvSpZv3rSYBHUvlBJhnkpJiy37\n" +
 110         "7ZUZhIxqYxyIPgRBolLwb+FFh7OdL+ECQCtldDic9WVmC+VheRDpCKZ+SlK/8lGi\n" +
 111         "7VXeShiIvcU1JysJFoa35fSI7hf1O3wt7+hX5PqGG7Un94EsJwACKEcCQQC1TWt6\n" +
 112         "ArKH6tRxKjOxFtqfs8fgEVYUaOr3j1jF4KBUuX2mtQtddZe3VfJ2wPsuKMMxmhkB\n" +
 113         "e7xWWZnJsErt2e+E";
 114 
 115     // Certificate information:
 116     // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce
 117     // Validity
 118     //     Not Before: May  5 02:40:53 2012 GMT
 119     //     Not After : Jan 21 02:40:53 2032 GMT
 120     // Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=casigner
 121     // X509v3 Subject Key Identifier:
 122     //     13:07:E0:11:07:DB:EB:33:23:87:31:D0:DB:7E:16:56:BE:11:90:0A
 123     // X509v3 Authority Key Identifier:
 124     //     keyid:DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B
 125     //     DirName:/C=US/O=Java/OU=SunJSSE Test Serivce
 126     //     serial:00
 127     static String caSignerStr =
 128         "-----BEGIN CERTIFICATE-----\n" +
 129         "MIICqDCCAhGgAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
 130         "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
 131         "MTIwNTA1MDI0MDUzWhcNMzIwMTIxMDI0MDUzWjBOMQswCQYDVQQGEwJVUzENMAsG\n" +
 132         "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxETAPBgNV\n" +
 133         "BAMTCGNhc2lnbmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+x8+o7oM0\n" +
 134         "ct/LZmZLXBL4CQ8jrULD5P7NtEW0hg/zxBFZfBHf+44Oo2eMPYZj+7xaREOH5BmV\n" +
 135         "KRYlzRtONAaC5Ng4Mrm5UKNPcMIIUjUOvm7vWM4oSTMSfoEcSX+vp99uUAkw3w7Z\n" +
 136         "+frYDm1M4At/j0b+lLij71GFN2L8drpgPQIDAQABo4GoMIGlMB0GA1UdDgQWBBQT\n" +
 137         "B+ARB9vrMyOHMdDbfhZWvhGQCjBjBgNVHSMEXDBagBTdTo0qEcCDA/Cs66K/+fJ9\n" +
 138         "yGkfm6E/pD0wOzELMAkGA1UEBhMCVVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsT\n" +
 139         "FFN1bkpTU0UgVGVzdCBTZXJpdmNlggEAMBIGA1UdEwEB/wQIMAYBAf8CAQEwCwYD\n" +
 140         "VR0PBAQDAgEGMA0GCSqGSIb3DQEBBAUAA4GBAI+LXA/UCPkTANablUkt80JNPWsl\n" +
 141         "pS4XLNgPxWaN0bkRDs5oI4ooWAz1rwpeJ/nfetOvWlpmrVjSeovBFja5Hl+dUHTf\n" +
 142         "VfuyzkxXbhuNiJIpo1mVBpNsjwu9YRxuwX6UA2LTUQpgvtVJEE012x3zRvxBCbu2\n" +
 143         "Y/v1R5fZ4c+hXDfC\n" +
 144         "-----END CERTIFICATE-----";
 145     static String caSignerPrivateKey = // Private key in the format of PKCS#8
 146         "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAL7Hz6jugzRy38tm\n" +
 147         "ZktcEvgJDyOtQsPk/s20RbSGD/PEEVl8Ed/7jg6jZ4w9hmP7vFpEQ4fkGZUpFiXN\n" +
 148         "G040BoLk2DgyublQo09wwghSNQ6+bu9YzihJMxJ+gRxJf6+n325QCTDfDtn5+tgO\n" +
 149         "bUzgC3+PRv6UuKPvUYU3Yvx2umA9AgMBAAECgYBYvu30cW8LONyt62Zua9hPFTe7\n" +
 150         "qt9B7QYyfkdmoG5PQMepTrOp84SzfoOukvgvDm0huFuJnSvhXQl2cCDhkgXskvFj\n" +
 151         "Hh7KBCFViVXokGdq5YoS0/KYMyQV0TZfJUvILBl51uc4/siQ2tClC/N4sa+1JhgW\n" +
 152         "a6dFGfRjiUKSSlmMwQJBAPWpIz3Q/c+DYMvoQr5OD8EaYwYIevlTdXb97RnJJh2b\n" +
 153         "UnhB9jrqesJiHYVzPmP0ukyPOXOwlp2T5Am4Kw0LFOkCQQDGz150NoHOp28Mvyc4\n" +
 154         "CTqz/zYzUhy2eCJESl196uyP4N65Y01VYQ3JDww4DlsXiU17tVSbgA9TCcfTYOzy\n" +
 155         "vyw1AkARUky+1hafZCcWGZljK8PmnMKwsTZikCTvL/Zg5BMA8Wu+OQBwpQnk3OAy\n" +
 156         "Aa87gw0DyvGFG8Vy9POWT9sRP1/JAkBqP0hrMvYMSs6+MSn0eHo2151PsAJIQcuO\n" +
 157         "U2/Da1khSzu8N6WMi2GiobgV/RYRbf9KrY2ZzMZjykZQYOxAjopBAkEAghCu38cN\n" +
 158         "aOsW6ueo24uzsWI1FTdE+qWNVEi3RSP120xXBCyhaBjIq4WVSlJK9K2aBaJpit3j\n" +
 159         "iQ5tl6zrLlxQhg==";
 160 
 161     // Certificate information:
 162     // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce, CN=casigner
 163     // Validity
 164     //     Not Before: May  5 02:40:57 2012 GMT
 165     //     Not After : Jan 21 02:40:57 2032 GMT
 166     // Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=certissuer
 167     // X509v3 Subject Key Identifier:
 168     //     39:0E:C6:33:B1:50:BC:73:07:31:E5:D8:04:F7:BB:97:55:CF:9B:C8
 169     // X509v3 Authority Key Identifier:
 170     //     keyid:13:07:E0:11:07:DB:EB:33:23:87:31:D0:DB:7E:16:56:BE:11:90:0A
 171     //     DirName:/C=US/O=Java/OU=SunJSSE Test Serivce
 172     //     serial:02
 173     static String certIssuerStr =
 174         "-----BEGIN CERTIFICATE-----\n" +
 175         "MIICvjCCAiegAwIBAgIBAzANBgkqhkiG9w0BAQQFADBOMQswCQYDVQQGEwJVUzEN\n" +
 176         "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxETAP\n" +
 177         "BgNVBAMTCGNhc2lnbmVyMB4XDTEyMDUwNTAyNDA1N1oXDTMyMDEyMTAyNDA1N1ow\n" +
 178         "UDELMAkGA1UEBhMCVVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0Ug\n" +
 179         "VGVzdCBTZXJpdmNlMRMwEQYDVQQDEwpjZXJ0aXNzdWVyMIGfMA0GCSqGSIb3DQEB\n" +
 180         "AQUAA4GNADCBiQKBgQCyz55zinU6kNL/LeiTNiBI0QWYmDG0YTotuC4D75liBNqs\n" +
 181         "7Mmladsh2mTtQUAwmuGaGzaZV25a+cUax0DXZoyBwdbTI09u1bUYsZcaUUKbPoCC\n" +
 182         "HH26e4jLFL4olW13Sv4ZAd57tIYevMw+Fp5f4fLPFGegCJTFlv2Qjpmic/cuvQID\n" +
 183         "AQABo4GpMIGmMB0GA1UdDgQWBBQ5DsYzsVC8cwcx5dgE97uXVc+byDBjBgNVHSME\n" +
 184         "XDBagBQTB+ARB9vrMyOHMdDbfhZWvhGQCqE/pD0wOzELMAkGA1UEBhMCVVMxDTAL\n" +
 185         "BgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNlggECMBMG\n" +
 186         "A1UdEwEB/wQJMAcBAf8CAgQAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQQFAAOB\n" +
 187         "gQCQTagenCdClT98C+oTJGJrw/dUBD9K3tE6ZJKPMc/2bUia8G5ei1C0eXj4mWG2\n" +
 188         "lu9umR6C90/A6qB050QB2h50qtqxSrkpu+ym1yypauZpg7U3nUY9wZWJNI1vqrQZ\n" +
 189         "pqUMRcXY3iQIVKx+Qj+4/Za1wwFQzpEoGmqRW31V1SdMEw==\n" +
 190         "-----END CERTIFICATE-----";
 191     static String certIssuerPrivateKey = // Private key in the format of PKCS#8
 192         "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBALLPnnOKdTqQ0v8t\n" +
 193         "6JM2IEjRBZiYMbRhOi24LgPvmWIE2qzsyaVp2yHaZO1BQDCa4ZobNplXblr5xRrH\n" +
 194         "QNdmjIHB1tMjT27VtRixlxpRQps+gIIcfbp7iMsUviiVbXdK/hkB3nu0hh68zD4W\n" +
 195         "nl/h8s8UZ6AIlMWW/ZCOmaJz9y69AgMBAAECgYEAjtew2tgm4gxDojqIauF4VPM1\n" +
 196         "pzsdqd1p3pAdomNLgrQiBLZ8N7oiph6TNb1EjA+OXc+ThFgF/oM9ZDD8qZZwcvjN\n" +
 197         "qDZlpTkFs2TaGcyEZfUaMB45NHVs6Nn+pSkagSNwwy3xeyAct7sQEzGNTDlEwVv5\n" +
 198         "7V9LQutQtBd6xT48KzkCQQDpNRfv2OFNG/6GtzJoO68oJhpnpl2MsYNi4ntRkre/\n" +
 199         "6uXpiCYaDskcrPMRwOOs0m7mxG+Ev+uKnLnSoEMm1GCbAkEAxEmDtiD0Psb8Z9BL\n" +
 200         "ZRb83Jqho3xe2MCAh3xUfz9b/Mhae9dZ44o4OCgQZuwvW1mczF0NtpgZl93BmYa2\n" +
 201         "hTwHhwJBAKHrEj6ep/fA6x0gD2idoATRR94VfbiU+7NpqtO9ecVP0+gsdr/66hn1\n" +
 202         "3yLBeZLh3MxvMTrLgkAQh1i9m0JXjOcCQQClLXAHHegrw+u3uNMZeKTFR+Lp3sk6\n" +
 203         "AZSnbvr0Me9I45kxSeG81x3ENALJecvIRbrrRws5MvmmkNhQR8rkh8WVAkEAk6b+\n" +
 204         "aVtmBgUaTS5+FFlHGHJY9HFrfT1a1C/dwyMuqlmbC3YsBmZaMOlKli5TXNybLff8\n" +
 205         "5KMeGEpXMzgC7AscGA==";
 206 
 207     // Certificate information:
 208     // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce, CN=certissuer
 209     // Validity
 210     //     Not Before: May  5 02:41:01 2012 GMT
 211     //     Not After : Jan 21 02:41:01 2032 GMT
 212     // Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=localhost
 213     // X509v3 Subject Key Identifier:
 214     //     AD:C0:2C:4C:E4:C2:2E:A1:BB:5D:92:BE:66:E0:4E:E0:0D:2F:11:EF
 215     // X509v3 Authority Key Identifier:
 216     //     keyid:39:0E:C6:33:B1:50:BC:73:07:31:E5:D8:04:F7:BB:97:55:CF:9B:C8
 217     static String serverCertStr =
 218         "-----BEGIN CERTIFICATE-----\n" +
 219         "MIICjTCCAfagAwIBAgIBBDANBgkqhkiG9w0BAQQFADBQMQswCQYDVQQGEwJVUzEN\n" +
 220         "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEzAR\n" +
 221         "BgNVBAMTCmNlcnRpc3N1ZXIwHhcNMTIwNTA1MDI0MTAxWhcNMzIwMTIxMDI0MTAx\n" +
 222         "WjBPMQswCQYDVQQGEwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNT\n" +
 223         "RSBUZXN0IFNlcml2Y2UxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0B\n" +
 224         "AQEFAAOBjQAwgYkCgYEAvwaUd7wmBSKqycEstYLWD26vkU08DM39EtaT8wL9HnQ0\n" +
 225         "fgPblwBFI4zdLa2cuYXRZcFUb04N8nrkcpR0D6kkE+AlFAoRWrrZF80B7JTbtEK4\n" +
 226         "1PIeurihXvUT+4MpzGLOojIihMfvM4ufelblD56SInso4WFHm7t4qCln88J1gjkC\n" +
 227         "AwEAAaN4MHYwCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBStwCxM5MIuobtdkr5m4E7g\n" +
 228         "DS8R7zAfBgNVHSMEGDAWgBQ5DsYzsVC8cwcx5dgE97uXVc+byDAnBgNVHSUEIDAe\n" +
 229         "BggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBAUAA4GB\n" +
 230         "AGfwcfdvEG/nSCiAn2MGbYHp34mgF3OA1SJLWUW0LvWJhwm2cn4AXlSoyvbwrkaB\n" +
 231         "IDDCwhJvvc0vUyL2kTx7sqVaFTq3mDs+ktlB/FfH0Pb+i8FE+g+7T42Iw/j0qxHL\n" +
 232         "YmgbrjBQf5WYN1AvBE/rrPt9aOtS3UsqtVGW574b0shW\n" +
 233         "-----END CERTIFICATE-----";
 234     static String serverPrivateKey = // Private key in the format of PKCS#8
 235         "MIICdAIBADANBgkqhkiG9w0BAQEFAASCAl4wggJaAgEAAoGBAL8GlHe8JgUiqsnB\n" +
 236         "LLWC1g9ur5FNPAzN/RLWk/MC/R50NH4D25cARSOM3S2tnLmF0WXBVG9ODfJ65HKU\n" +
 237         "dA+pJBPgJRQKEVq62RfNAeyU27RCuNTyHrq4oV71E/uDKcxizqIyIoTH7zOLn3pW\n" +
 238         "5Q+ekiJ7KOFhR5u7eKgpZ/PCdYI5AgMBAAECf3CscOYvFD3zNMnMJ5LomVqA7w3F\n" +
 239         "gKYM2jlCWAH+wU41PMEXhW6Lujw92jgXL1o+lERwxFzirVdZJWZwKgUSvzP1G0h3\n" +
 240         "fkucq1/UWnToK+8NSXNM/yS8hXbBgSEoJo5f7LKcIi1Ev6doBVofMxs+njzyWKbM\n" +
 241         "Nb7rOLHadghoon0CQQDgQzbzzSN8Dc1YmmylhI5v+0sQRHH0DL7D24k4Weh4vInG\n" +
 242         "EAbt4x8M7ZKEo8/dv0s4hbmNmAnJl93/RRxIyEqLAkEA2g87DiswSQam2pZ8GlrO\n" +
 243         "+w4Qg9mH8uxx8ou2rl0XlHzH1XiTNbkjfY0EZoL7L31BHFk9n11Fb2P85g6ws+Hy\n" +
 244         "ywJAM/xgyLNM/nzUlS128geAXUULaYH0SHaL4isJ7B4rXZGW/mrIsGxtzjlkNYsj\n" +
 245         "rGujrD6TfNc5rZmexIXowJZtcQJBAIww+pCzZ4mrgx5JXWQ8OZHiiu+ZrPOa2+9J\n" +
 246         "r5sOMpi+WGN/73S8oHqZbNjTINZ5OqEVJq8MchWZPQBTNXuQql0CQHEjUzzkCQa3\n" +
 247         "j6JTa2KAdqyvLOx0XF9zcc1gA069uNQI2gPUHS8V215z57f/gMGnDNhVfLs/vMKz\n" +
 248         "sFkVZ3zg7As=";
 249 
 250     // Certificate information:
 251     // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce, CN=certissuer
 252     // Validity
 253     //     Not Before: May  5 02:41:02 2012 GMT
 254     //     Not After : Jan 21 02:41:02 2032 GMT
 255     // Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=InterOp Tester
 256     // X509v3 Subject Key Identifier:
 257     //     57:7D:E2:33:33:60:DF:DD:5E:ED:81:3F:EB:F2:1B:59:7F:50:9C:99
 258     // X509v3 Authority Key Identifier:
 259     //     keyid:39:0E:C6:33:B1:50:BC:73:07:31:E5:D8:04:F7:BB:97:55:CF:9B:C8
 260     static String clientCertStr =
 261         "-----BEGIN CERTIFICATE-----\n" +
 262         "MIICaTCCAdKgAwIBAgIBBTANBgkqhkiG9w0BAQQFADBQMQswCQYDVQQGEwJVUzEN\n" +
 263         "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEzAR\n" +
 264         "BgNVBAMTCmNlcnRpc3N1ZXIwHhcNMTIwNTA1MDI0MTAyWhcNMzIwMTIxMDI0MTAy\n" +
 265         "WjBUMQswCQYDVQQGEwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNT\n" +
 266         "RSBUZXN0IFNlcml2Y2UxFzAVBgNVBAMTDkludGVyT3AgVGVzdGVyMIGfMA0GCSqG\n" +
 267         "SIb3DQEBAQUAA4GNADCBiQKBgQC1pA71nDg1KhhnHjRdi/eVDUa7uFZAtN8R9huu\n" +
 268         "pTwFoyqSX8lDMz8jDawOMmaI9dVZLjTh3hnf4KBEqQOearFVz45yBOjlgPLBuI4F\n" +
 269         "D/ORhgmDaIu2NK+c1yj6YQlyiO0DPwh55GtPLVG3iuEpejU7gQyaMuTaddoXrO7s\n" +
 270         "xwzanQIDAQABo08wTTALBgNVHQ8EBAMCA+gwHQYDVR0OBBYEFFd94jMzYN/dXu2B\n" +
 271         "P+vyG1l/UJyZMB8GA1UdIwQYMBaAFDkOxjOxULxzBzHl2AT3u5dVz5vIMA0GCSqG\n" +
 272         "SIb3DQEBBAUAA4GBAHTgB5W7wnl7Jnb4wNQcb6JdR8FRHIdslcRfnReFfZBHZZux\n" +
 273         "ChpA1lf62KIzYohKoxQXXMul86vnVSHnXq5xctHEmxCBnALEnoAcCOv6wfWqEA7g\n" +
 274         "2rX+ydmu+0ArbqKhSOypZ7K3ame0UOJJ6HDxdsgBYJuotmSou4KKq9e8GF+d\n" +
 275         "-----END CERTIFICATE-----";
 276     static String clientPrivateKey = // Private key in the format of PKCS#8
 277         "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALWkDvWcODUqGGce\n" +
 278         "NF2L95UNRru4VkC03xH2G66lPAWjKpJfyUMzPyMNrA4yZoj11VkuNOHeGd/goESp\n" +
 279         "A55qsVXPjnIE6OWA8sG4jgUP85GGCYNoi7Y0r5zXKPphCXKI7QM/CHnka08tUbeK\n" +
 280         "4Sl6NTuBDJoy5Np12hes7uzHDNqdAgMBAAECgYEAjLwygwapXjfhdHQoqpp6F9iT\n" +
 281         "h3sKCVSaybXgOO75lHyZzZO9wv1/288KEm3mmBOxXEm6245UievnAYvaq/GKt93O\n" +
 282         "pj2zRefBzZjGbz0v84fmna/MN6zUUYX1PcVRMKWLx9HKKmQihzwoXdBX0o9PPXdi\n" +
 283         "LfzujNa/q8/mpI5PmEECQQDZwLSaL7OReWZTY4NoQuNzwhx5IKJUOtCFQfmHKZSW\n" +
 284         "wtXntZf+E5W9tGaDY5wjpq5cilKDAHdEAlFWxDe1PoE1AkEA1YuTBpctOLBfquFn\n" +
 285         "Y/S3lzGVlnIHDk3dj4bFglkoJ2bCdlwRNUyBSjAjBDcbYhper8S7GlEN5SiEdz9I\n" +
 286         "3OjIyQJBAKEPMgYhZjYhjxf6sQV7A/VpC9pj0u1uGzGVXNUmYisorUKXRHa/UbBh\n" +
 287         "MLnaAXE1Jh54iRMwUwbQmA0PUQ0T0EkCQQCcr6/umwhkWw2nHYK2Vf5LoudGn15M\n" +
 288         "AZg7UsEjVnXfC0hOfllmCT+ohs96rVCbWAv33lsHAUg3x9YChV3aMbf5AkAj1kuV\n" +
 289         "jUTgFKjediyQC6uof7YdLn+gQGiXK1XE0GBN4WMkzcLiS0jC+MFTgKfFnFdh9K0y\n" +
 290         "fswYKdTA/o8RKaa5";
 291 
 292     static char passphrase[] = "passphrase".toCharArray();
 293 
 294     /*
 295      * Is the server ready to serve?
 296      */
 297     volatile static boolean serverReady = false;
 298 
 299     /*
 300      * Turn on SSL debugging?
 301      */
 302     static boolean debug = false;
 303 
 304     /*
 305      * Define the server side of the test.
 306      *
 307      * If the server prematurely exits, serverReady will be set to true
 308      * to avoid infinite hangs.
 309      */
 310     void doServerSide() throws Exception {
 311         SSLContext context = getSSLContext(true);
 312         SSLServerSocketFactory sslssf = context.getServerSocketFactory();
 313 
 314         SSLServerSocket sslServerSocket =
 315             (SSLServerSocket)sslssf.createServerSocket(serverPort);
 316         serverPort = sslServerSocket.getLocalPort();
 317         SSLSocket sslSocket = null;
 318         try {
 319             /*
 320              * Signal Client, we're ready for his connect.
 321              */
 322             serverReady = true;
 323 
 324             sslSocket = (SSLSocket) sslServerSocket.accept();
 325             sslSocket.setNeedClientAuth(true);
 326 
 327             InputStream sslIS = sslSocket.getInputStream();
 328             OutputStream sslOS = sslSocket.getOutputStream();
 329 
 330             sslIS.read();
 331             sslOS.write(85);
 332             sslOS.flush();
 333         } finally {
 334             if (sslSocket != null) {
 335                 sslSocket.close();
 336             }
 337             sslServerSocket.close();
 338         }
 339     }
 340 
 341     /*
 342      * Define the client side of the test.
 343      *
 344      * If the server prematurely exits, serverReady will be set to true
 345      * to avoid infinite hangs.
 346      */
 347     void doClientSide() throws Exception {
 348         /*
 349          * Wait for server to get started.
 350          */
 351         while (!serverReady) {
 352             Thread.sleep(50);
 353         }
 354 
 355         SSLContext context = getSSLContext(false);
 356         SSLSocketFactory sslsf = context.getSocketFactory();
 357 
 358         SSLSocket sslSocket =
 359             (SSLSocket)sslsf.createSocket("localhost", serverPort);
 360         try {
 361             InputStream sslIS = sslSocket.getInputStream();
 362             OutputStream sslOS = sslSocket.getOutputStream();
 363 
 364             sslOS.write(280);
 365             sslOS.flush();
 366             sslIS.read();
 367         } finally {
 368             sslSocket.close();
 369         }
 370     }
 371 
 372     // get the ssl context
 373     private static SSLContext getSSLContext(boolean isServer) throws Exception {
 374 
 375         // generate certificate from cert string
 376         CertificateFactory cf = CertificateFactory.getInstance("X.509");
 377 
 378         // create a key store
 379         KeyStore ks = KeyStore.getInstance("JKS");
 380         ks.load(null, null);
 381 
 382         // import the trused cert
 383         ByteArrayInputStream is =
 384             new ByteArrayInputStream(trusedCertStr.getBytes());
 385         Certificate trusedCert = cf.generateCertificate(is);
 386         is.close();
 387 
 388         ks.setCertificateEntry("SunJSSE Test Serivce", trusedCert);
 389 
 390         // import the certificate chain and key
 391         Certificate[] chain = new Certificate[3];
 392 
 393         is = new ByteArrayInputStream(caSignerStr.getBytes());
 394         Certificate caSignerCert = cf.generateCertificate(is);
 395         is.close();
 396         chain[2] = caSignerCert;
 397 
 398         is = new ByteArrayInputStream(certIssuerStr.getBytes());
 399         Certificate certIssuerCert = cf.generateCertificate(is);
 400         is.close();
 401         chain[1] = certIssuerCert;
 402 
 403         PKCS8EncodedKeySpec priKeySpec = null;
 404         if (isServer) {
 405             priKeySpec = new PKCS8EncodedKeySpec(
 406                             Base64.getMimeDecoder().decode(serverPrivateKey));
 407             is = new ByteArrayInputStream(serverCertStr.getBytes());
 408         } else {
 409             priKeySpec = new PKCS8EncodedKeySpec(
 410                             Base64.getMimeDecoder().decode(clientPrivateKey));
 411             is = new ByteArrayInputStream(clientCertStr.getBytes());
 412         }
 413         KeyFactory kf = KeyFactory.getInstance("RSA");
 414         RSAPrivateKey priKey = (RSAPrivateKey)kf.generatePrivate(priKeySpec);
 415         Certificate keyCert = cf.generateCertificate(is);
 416         is.close();
 417         chain[0] = keyCert;
 418 
 419         ks.setKeyEntry("End Entity", priKey, passphrase, chain);
 420 
 421         // check the certification path
 422         PKIXParameters paras = new PKIXParameters(ks);
 423         paras.setRevocationEnabled(false);
 424         CertPath path = cf.generateCertPath(Arrays.asList(chain));
 425         CertPathValidator cv = CertPathValidator.getInstance("PKIX");
 426         cv.validate(path, paras);
 427 
 428         // create SSL context
 429         TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
 430         tmf.init(ks);
 431 
 432         SSLContext ctx = SSLContext.getInstance("TLS");
 433         KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
 434         kmf.init(ks, passphrase);
 435 
 436         ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
 437         ks = null;
 438 
 439         return ctx;
 440     }
 441 
 442     private static String tmAlgorithm;        // trust manager
 443 
 444     private static void parseArguments(String[] args) {
 445         tmAlgorithm = args[0];
 446     }
 447 
 448     /*
 449      * =============================================================
 450      * The remainder is just support stuff
 451      */
 452 
 453     // use any free port by default
 454     volatile int serverPort = 0;
 455 
 456     volatile Exception serverException = null;
 457     volatile Exception clientException = null;
 458 
 459     public static void main(String args[]) throws Exception {
 460         // MD5 is used in this test case, don't disable MD5 algorithm.
 461         Security.setProperty("jdk.certpath.disabledAlgorithms",
 462                 "MD2, RSA keySize < 1024");
 463         Security.setProperty("jdk.tls.disabledAlgorithms",
 464                 "SSLv3, RC4, DH keySize < 768");
 465 
 466         if (debug)
 467             System.setProperty("javax.net.debug", "all");
 468 
 469 
 470         /*
 471          * Get the customized arguments.
 472          */
 473         parseArguments(args);
 474 
 475         /*
 476          * Start the tests.
 477          */
 478         new BasicConstraints();
 479     }
 480 
 481     Thread clientThread = null;
 482     Thread serverThread = null;
 483     /*
 484      * Primary constructor, used to drive remainder of the test.
 485      *
 486      * Fork off the other side, then do your work.
 487      */
 488     BasicConstraints() throws Exception {
 489         if (separateServerThread) {
 490             startServer(true);
 491             startClient(false);
 492         } else {
 493             startClient(true);
 494             startServer(false);
 495         }
 496 
 497         /*
 498          * Wait for other side to close down.
 499          */
 500         if (separateServerThread) {
 501             serverThread.join();
 502         } else {
 503             clientThread.join();
 504         }
 505 
 506         /*
 507          * When we get here, the test is pretty much over.
 508          *
 509          * If the main thread excepted, that propagates back
 510          * immediately.  If the other thread threw an exception, we
 511          * should report back.
 512          */
 513         if (serverException != null)
 514             throw serverException;
 515         if (clientException != null)
 516             throw clientException;
 517     }
 518 
 519     void startServer(boolean newThread) throws Exception {
 520         if (newThread) {
 521             serverThread = new Thread() {
 522                 public void run() {
 523                     try {
 524                         doServerSide();
 525                     } catch (Exception e) {
 526                         /*
 527                          * Our server thread just died.
 528                          *
 529                          * Release the client, if not active already...
 530                          */
 531                         System.err.println("Server died...");
 532                         serverReady = true;
 533                         serverException = e;
 534                     }
 535                 }
 536             };
 537             serverThread.start();
 538         } else {
 539             doServerSide();
 540         }
 541     }
 542 
 543     void startClient(boolean newThread) throws Exception {
 544         if (newThread) {
 545             clientThread = new Thread() {
 546                 public void run() {
 547                     try {
 548                         doClientSide();
 549                     } catch (Exception e) {
 550                         /*
 551                          * Our client thread just died.
 552                          */
 553                         System.err.println("Client died...");
 554                         clientException = e;
 555                     }
 556                 }
 557             };
 558             clientThread.start();
 559         } else {
 560             doClientSide();
 561         }
 562     }
 563 
 564 }