org.opensaml.security.x509.X509SupportTest.java Source code

Java tutorial

Introduction

Here is the source code for org.opensaml.security.x509.X509SupportTest.java

Source

/*
 * Licensed to the University Corporation for Advanced Internet Development, 
 * Inc. (UCAID) under one or more contributor license agreements.  See the 
 * NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The UCAID licenses this file to You under the Apache 
 * License, Version 2.0 (the "License"); you may not use this file except in 
 * compliance with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.opensaml.security.x509;

import java.io.InputStream;
import java.security.PrivateKey;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.security.auth.x500.X500Principal;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.opensaml.security.SecurityException;
import org.opensaml.security.crypto.KeySupport;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

/**
 * Tests the X509Support utility methods.
 */
public class X509SupportTest {

    private PrivateKey entityPrivateKey;

    private String entityPrivKeyBase64 = "MIICXQIBAAKBgQCewxYtt+tEFlhy7+5V3kdCGDATiiXP/A0r2Q+amujuDz0aauvf"
            + "j8fcEsIm1JJf7KDeIeYncybi71Fd/2iPFVUKJIUuXmPxfwXnn7eqzspQRNnS1zf+"
            + "y8oe4V7Y6/DBD0vt+tMCjMCiaAfsyQshaje78hZbh0m3fWrdJMClpcTXAQIDAQAB"
            + "AoGAENG8JMXKT+FKJ4sRpdkxlWf4l+lXziv2vUF2rLtil+3XXFgdewbBdqgqF3EH"
            + "vM/VzxKqTl2drgcKiLnJOvdYldq721OglkBfCEwI1yKjf/xWo/B2IuHsbkKrodBW"
            + "LpzWhoYb8WLSePFPaYvIyRUxAiDSTUcySn1piHKh2L6dFj0CQQDTC5/3GZaFL1lK"
            + "Tp2/WOzp1a+W5pinNVYugQz6ZUWurIdkePiJswCeERa7IHnAfa8iHYWZhn2Y9jub"
            + "l1W+aLgXAkEAwJRu+JFpW4AtiwRGRHpTLMGJh40eUI668RwXiBePLUFdWJMPsuZC"
            + "//fWRLIZQ/Ukv5XLcFdQeAPh8crVQGlApwJAXSy2tRtg7vAWlc3bq00RW7Nx0EeC"
            + "gd/0apejKTFo8FNPezZFVFXpIeAdjwQpfKiAl6k9AKj17oBXlLvdqTEGhQJBALgs"
            + "PIST7EKJrwSILftHUUw4OyLbnuZD2hzEVOzeOxt4q6EN47Gf7OuHRe+ks+z+AQsI"
            + "YuspVdexPuBSrudOwXkCQQDEdI7texImU7o6tXAt9mmVyVik9ibRaTnpbJJh+ox+"
            + "EwYAMfQ7HqW8el3XH+q5tNNDNuR+voIuWJPRD30nOgb5";

    private X509Certificate entityCert;

    private String entityCertBase64 = "MIICvzCCAiigAwIBAgIJALQ1JXkgPO25MA0GCSqGSIb3DQEBBQUAMEoxCzAJBgNV"
            + "BAYTAkNIMQ8wDQYDVQQIEwZadXJpY2gxFDASBgNVBAoTC2V4YW1wbGUub3JnMRQw"
            + "EgYDVQQDEwtleGFtcGxlLm9yZzAeFw0wODEyMDQwNzUzNDBaFw0wOTEyMDQwNzUz"
            + "NDBaMEoxCzAJBgNVBAYTAkNIMQ8wDQYDVQQIEwZadXJpY2gxFDASBgNVBAoTC2V4"
            + "YW1wbGUub3JnMRQwEgYDVQQDEwtleGFtcGxlLm9yZzCBnzANBgkqhkiG9w0BAQEF"
            + "AAOBjQAwgYkCgYEAnsMWLbfrRBZYcu/uVd5HQhgwE4olz/wNK9kPmpro7g89Gmrr"
            + "34/H3BLCJtSSX+yg3iHmJ3Mm4u9RXf9ojxVVCiSFLl5j8X8F55+3qs7KUETZ0tc3"
            + "/svKHuFe2OvwwQ9L7frTAozAomgH7MkLIWo3u/IWW4dJt31q3STApaXE1wECAwEA"
            + "AaOBrDCBqTAdBgNVHQ4EFgQU0lf1wYwRJhvGZYL2WpMOykDNdeUwegYDVR0jBHMw"
            + "cYAU0lf1wYwRJhvGZYL2WpMOykDNdeWhTqRMMEoxCzAJBgNVBAYTAkNIMQ8wDQYD"
            + "VQQIEwZadXJpY2gxFDASBgNVBAoTC2V4YW1wbGUub3JnMRQwEgYDVQQDEwtleGFt"
            + "cGxlLm9yZ4IJALQ1JXkgPO25MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD"
            + "gYEAlhsuXNm5WMq7mILnbS+Xr+oi/LVezr4Yju+Qdh9AhYwbDaXnsZITHiAmfYhO"
            + "5nTjstWMAHc6JZs7h8wDvqY92RvLY+Vx78MoJXIwqqLFH4oHm2UKpvsNivrNfD/q"
            + "WPiKEYrXVVkDXUVA2yKupX1VtCru8kaJ42kAlCN9Bg4wezU=";

    private X509Certificate entityCert3AltNamesDNS_URL_IP;

    private String entityCert3AltNamesDNS_URL_IPBase64 = "MIIDzjCCAragAwIBAgIBMTANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQKEwlJbnRl"
            + "cm5ldDIxFzAVBgNVBAMTDmNhLmV4YW1wbGUub3JnMB4XDTA3MDUyMTE4MjM0MFoX"
            + "DTE3MDUxODE4MjM0MFowMTESMBAGA1UEChMJSW50ZXJuZXQyMRswGQYDVQQDExJm"
            + "b29iYXIuZXhhbXBsZS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
            + "AQDNWnkFmhy1vYa6gN/xBRKkZxFy3sUq2V0LsYb6Q3pe9Qlb6+BzaM5DrN8uIqqr"
            + "oBE3Wp0LtrgKuQTpDpNFBdS2p5afiUtOYLWBDtizTOzs3Z36MGMjIPUYQ4s03IP3"
            + "yPh2ud6EKpDPiYqzNbkRaiIwmYSit5r+RMYvd6fuKvTOn6h7PZI5AD7Rda7VWh5O"
            + "VSoZXlRx3qxFho+mZhW0q4fUfTi5lWwf4EhkfBlzgw/k5gf4cOi6rrGpRS1zxmbt"
            + "X1RAg+I20z6d04g0N2WsK5stszgYKoIROJCiXwjraa8/SoFcILolWQpttVHBIUYl"
            + "yDlm8mIFleZf4ReFpfm+nUYxAgMBAAGjgfQwgfEwCQYDVR0TBAIwADAsBglghkgB"
            + "hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE"
            + "FDgRgTkjaKoK6DoZfUZ4g9LDJUWuMFUGA1UdIwROMEyAFNXuZVPeUdqHrULqQW7y"
            + "r9buRpQLoTGkLzAtMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDmNhLmV4"
            + "YW1wbGUub3JnggEBMEAGA1UdEQQ5MDeCEmFzaW1vdi5leGFtcGxlLm9yZ4YbaHR0"
            + "cDovL2hlaW5sZWluLmV4YW1wbGUub3JnhwQKAQIDMA0GCSqGSIb3DQEBBQUAA4IB"
            + "AQBLiDMyQ60ldIytVO1GCpp1S1sKJyTF56GVxHh/82hiRFbyPu+2eSl7UcJfH4ZN"
            + "bAfHL1vDKTRJ9zoD8WRzpOCUtT0IPIA/Ex+8lFzZmujO10j3TMpp8Ii6+auYwi/T"
            + "osrfw1YCxF+GI5KO49CfDRr6yxUbMhbTN+ssK4UzFf36UbkeJ3EfDwB0WU70jnlk"
            + "yO8f97X6mLd5QvRcwlkDMftP4+MB+inTlxDZ/w8NLXQoDW6p/8r91bupXe0xwuyE"
            + "vow2xjxlzVcux2BZsUZYjBa07ZmNNBtF7WaQqH7l2OBCAdnBhvme5i/e0LK3Ivys" + "+hcVyvCXs5XtFTFWDAVYvzQ6";

    private X509Certificate entityCert3AltNamesDNS_URN_IP;

    private String entityCert3AltNamesDNS_URN_IPBase64 = "MIIDyjCCArKgAwIBAgIBLDANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQKEwlJbnRl"
            + "cm5ldDIxFzAVBgNVBAMTDmNhLmV4YW1wbGUub3JnMB4XDTA3MDUyMTA0NDQzOVoX"
            + "DTE3MDUxODA0NDQzOVowMTESMBAGA1UEChMJSW50ZXJuZXQyMRswGQYDVQQDExJm"
            + "b29iYXIuZXhhbXBsZS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
            + "AQDNWnkFmhy1vYa6gN/xBRKkZxFy3sUq2V0LsYb6Q3pe9Qlb6+BzaM5DrN8uIqqr"
            + "oBE3Wp0LtrgKuQTpDpNFBdS2p5afiUtOYLWBDtizTOzs3Z36MGMjIPUYQ4s03IP3"
            + "yPh2ud6EKpDPiYqzNbkRaiIwmYSit5r+RMYvd6fuKvTOn6h7PZI5AD7Rda7VWh5O"
            + "VSoZXlRx3qxFho+mZhW0q4fUfTi5lWwf4EhkfBlzgw/k5gf4cOi6rrGpRS1zxmbt"
            + "X1RAg+I20z6d04g0N2WsK5stszgYKoIROJCiXwjraa8/SoFcILolWQpttVHBIUYl"
            + "yDlm8mIFleZf4ReFpfm+nUYxAgMBAAGjgfAwge0wCQYDVR0TBAIwADAsBglghkgB"
            + "hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE"
            + "FDgRgTkjaKoK6DoZfUZ4g9LDJUWuMFUGA1UdIwROMEyAFNXuZVPeUdqHrULqQW7y"
            + "r9buRpQLoTGkLzAtMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDmNhLmV4"
            + "YW1wbGUub3JnggEBMDwGA1UdEQQ1MDOCEmFzaW1vdi5leGFtcGxlLm9yZ4YXdXJu"
            + "OmZvbzpleGFtcGxlLm9yZzppZHCHBAoBAgMwDQYJKoZIhvcNAQEFBQADggEBAH7L"
            + "RnOWJbP5p50lLvBaW6G0593OMChQIXVim9kf6Um4HQjC8/3BZPltyNMxn+xtUnRY"
            + "AaKPDjbpr0CkM5lggJd8Q69XJiPTch9UQlcX+Ry7CXV+GsTnn6kgE5IW0ULqrp/i"
            + "vVQVu6Af/dBS1+K+TddYOatNnABLr0lco5ppZ4v9HFIsoLljTrkdW4XrlYmW1Hx0"
            + "SUVrYsbv2uRP3n1jEEYldvZOdhEGoEADSt46zE+HCG/ytfTYSDyola6OErB09e/o"
            + "FDzzWGsOve69UV11bdeFgaMQJYloFHXq9MRKOCaKQLWxjwMd1MRJLJX6WpwZS600" + "t2pJYMLFu19LDRfgX4M=";

    private X509Certificate entityCert1AltNameDNS;

    private String entityCert1AltNameDNSBase64 = "MIIDqzCCApOgAwIBAgIBLTANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQKEwlJbnRl"
            + "cm5ldDIxFzAVBgNVBAMTDmNhLmV4YW1wbGUub3JnMB4XDTA3MDUyMTE3MzM0M1oX"
            + "DTE3MDUxODE3MzM0M1owMTESMBAGA1UEChMJSW50ZXJuZXQyMRswGQYDVQQDExJm"
            + "b29iYXIuZXhhbXBsZS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
            + "AQDNWnkFmhy1vYa6gN/xBRKkZxFy3sUq2V0LsYb6Q3pe9Qlb6+BzaM5DrN8uIqqr"
            + "oBE3Wp0LtrgKuQTpDpNFBdS2p5afiUtOYLWBDtizTOzs3Z36MGMjIPUYQ4s03IP3"
            + "yPh2ud6EKpDPiYqzNbkRaiIwmYSit5r+RMYvd6fuKvTOn6h7PZI5AD7Rda7VWh5O"
            + "VSoZXlRx3qxFho+mZhW0q4fUfTi5lWwf4EhkfBlzgw/k5gf4cOi6rrGpRS1zxmbt"
            + "X1RAg+I20z6d04g0N2WsK5stszgYKoIROJCiXwjraa8/SoFcILolWQpttVHBIUYl"
            + "yDlm8mIFleZf4ReFpfm+nUYxAgMBAAGjgdEwgc4wCQYDVR0TBAIwADAsBglghkgB"
            + "hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE"
            + "FDgRgTkjaKoK6DoZfUZ4g9LDJUWuMFUGA1UdIwROMEyAFNXuZVPeUdqHrULqQW7y"
            + "r9buRpQLoTGkLzAtMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDmNhLmV4"
            + "YW1wbGUub3JnggEBMB0GA1UdEQQWMBSCEmFzaW1vdi5leGFtcGxlLm9yZzANBgkq"
            + "hkiG9w0BAQUFAAOCAQEAjSRiOpLAbrxkqQ0Yh+mUWCVA2ChSDBnFFDe4a3Z/87Tw"
            + "7QEzU6U1xejCH6kGGZSmHLBMPLg31+QNiWwXDnQTqa8w/16oncUuw3olIK+C/r+F"
            + "5uhakJcPq6LK8ZhSDi85YGMn1vPHP8FsC9/HMZS0Y/ouzDeZYwXc9ZwF8uMxh+vn"
            + "KWUbyVDGuoTI4x0SIMgyrA917xpSG/1m9lJVVvF9S6/+n+ZpkIhpmvmOHGNicBoX"
            + "sNk3tgHPzGTkn/DDx9SGmBUfyBEOTwlDHX36zqGRozWRVqGVYMb58L7dxLjnWkO5"
            + "0eVKajcKvJ1zBowSoiDQ50drULm5FSVzix3gUO1p6g==";

    private X509Certificate entityCert1AltNameURN;

    private String entityCert1AltNameURNBase64 = "MIIDsDCCApigAwIBAgIBLjANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQKEwlJbnRl"
            + "cm5ldDIxFzAVBgNVBAMTDmNhLmV4YW1wbGUub3JnMB4XDTA3MDUyMTE3NDYyNVoX"
            + "DTE3MDUxODE3NDYyNVowMTESMBAGA1UEChMJSW50ZXJuZXQyMRswGQYDVQQDExJm"
            + "b29iYXIuZXhhbXBsZS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
            + "AQDNWnkFmhy1vYa6gN/xBRKkZxFy3sUq2V0LsYb6Q3pe9Qlb6+BzaM5DrN8uIqqr"
            + "oBE3Wp0LtrgKuQTpDpNFBdS2p5afiUtOYLWBDtizTOzs3Z36MGMjIPUYQ4s03IP3"
            + "yPh2ud6EKpDPiYqzNbkRaiIwmYSit5r+RMYvd6fuKvTOn6h7PZI5AD7Rda7VWh5O"
            + "VSoZXlRx3qxFho+mZhW0q4fUfTi5lWwf4EhkfBlzgw/k5gf4cOi6rrGpRS1zxmbt"
            + "X1RAg+I20z6d04g0N2WsK5stszgYKoIROJCiXwjraa8/SoFcILolWQpttVHBIUYl"
            + "yDlm8mIFleZf4ReFpfm+nUYxAgMBAAGjgdYwgdMwCQYDVR0TBAIwADAsBglghkgB"
            + "hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE"
            + "FDgRgTkjaKoK6DoZfUZ4g9LDJUWuMFUGA1UdIwROMEyAFNXuZVPeUdqHrULqQW7y"
            + "r9buRpQLoTGkLzAtMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDmNhLmV4"
            + "YW1wbGUub3JnggEBMCIGA1UdEQQbMBmGF3Vybjpmb286ZXhhbXBsZS5vcmc6aWRw"
            + "MA0GCSqGSIb3DQEBBQUAA4IBAQA6REOOby69uy/zvgidjEuZRK/oacIKvjVm+1K0"
            + "HSKbGdroCHRRMQS6s5IGRE2ef+wiwus1367/crxYEqa+Tu9iewyVNFkZjWm9ra+T"
            + "kgoghA5DteoC0tYzUhWooWhA6FW7Ktn8yAdmGPV+bhMTwnrm9DiM9mAZr0Ew8qP7"
            + "8HWziw2qWM48LhdfuO2kiWzvinRx1wqKJjur9nY9piUOO32aTlzXZy2yLiOYVKUw"
            + "2dKdxMmvwYxNYCEzNx2ERmDSbHoNZLn75WidNTnHpkn0rBh2J9ZS8j2swyoVoVp3"
            + "rQRHDSQ9CJCNKVXWh/WnjgqnLpBzXKCLv/zrQ3t47OL2Jyso";

    private X509Certificate entityCert1AltNameURL;

    private String entityCert1AltNameURLBase64 = "MIIDtDCCApygAwIBAgIBMDANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQKEwlJbnRl"
            + "cm5ldDIxFzAVBgNVBAMTDmNhLmV4YW1wbGUub3JnMB4XDTA3MDUyMTE4MTMwOFoX"
            + "DTE3MDUxODE4MTMwOFowMTESMBAGA1UEChMJSW50ZXJuZXQyMRswGQYDVQQDExJm"
            + "b29iYXIuZXhhbXBsZS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
            + "AQDNWnkFmhy1vYa6gN/xBRKkZxFy3sUq2V0LsYb6Q3pe9Qlb6+BzaM5DrN8uIqqr"
            + "oBE3Wp0LtrgKuQTpDpNFBdS2p5afiUtOYLWBDtizTOzs3Z36MGMjIPUYQ4s03IP3"
            + "yPh2ud6EKpDPiYqzNbkRaiIwmYSit5r+RMYvd6fuKvTOn6h7PZI5AD7Rda7VWh5O"
            + "VSoZXlRx3qxFho+mZhW0q4fUfTi5lWwf4EhkfBlzgw/k5gf4cOi6rrGpRS1zxmbt"
            + "X1RAg+I20z6d04g0N2WsK5stszgYKoIROJCiXwjraa8/SoFcILolWQpttVHBIUYl"
            + "yDlm8mIFleZf4ReFpfm+nUYxAgMBAAGjgdowgdcwCQYDVR0TBAIwADAsBglghkgB"
            + "hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE"
            + "FDgRgTkjaKoK6DoZfUZ4g9LDJUWuMFUGA1UdIwROMEyAFNXuZVPeUdqHrULqQW7y"
            + "r9buRpQLoTGkLzAtMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDmNhLmV4"
            + "YW1wbGUub3JnggEBMCYGA1UdEQQfMB2GG2h0dHA6Ly9oZWlubGVpbi5leGFtcGxl"
            + "Lm9yZzANBgkqhkiG9w0BAQUFAAOCAQEAQRJHMwtHvzdaTKg/GdSdt1u6H+tkspYE"
            + "SeDOFS0Ni9bm2nPrKLPHzWwVFriMwqtWT0ik7Sx8TK1jA2q3Wxgj+xS9kAvFtGyy"
            + "pq1HEMdVXwcQlyopSZEd3Oi7Bfam6eSy1ehVKkEwG9pry+0v6I1Z3gShPHBm/Tcj"
            + "EV3FIv6CTYgW9jZIBPKfI54xyQ7Ef07V608S6lpPGEOmjZPccQmiqu2fXTvmSxmD"
            + "eXUY9lfn7SR3afmHOeDuovoa+sPZnyBmtsWcllmI328ZkSukaOXhLDLFLt2UA55L"
            + "uy4/1cWTxEqyuizzTvjbHvvw7HF4/yBkNggcumQqr9gWqxNvvXFsNw==";

    private X509Certificate entityCert1AltNameIP;

    private String entityCert1AltNameIPBase64 = "MIIDnTCCAoWgAwIBAgIBLzANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQKEwlJbnRl"
            + "cm5ldDIxFzAVBgNVBAMTDmNhLmV4YW1wbGUub3JnMB4XDTA3MDUyMTE3NDgwMloX"
            + "DTE3MDUxODE3NDgwMlowMTESMBAGA1UEChMJSW50ZXJuZXQyMRswGQYDVQQDExJm"
            + "b29iYXIuZXhhbXBsZS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
            + "AQDNWnkFmhy1vYa6gN/xBRKkZxFy3sUq2V0LsYb6Q3pe9Qlb6+BzaM5DrN8uIqqr"
            + "oBE3Wp0LtrgKuQTpDpNFBdS2p5afiUtOYLWBDtizTOzs3Z36MGMjIPUYQ4s03IP3"
            + "yPh2ud6EKpDPiYqzNbkRaiIwmYSit5r+RMYvd6fuKvTOn6h7PZI5AD7Rda7VWh5O"
            + "VSoZXlRx3qxFho+mZhW0q4fUfTi5lWwf4EhkfBlzgw/k5gf4cOi6rrGpRS1zxmbt"
            + "X1RAg+I20z6d04g0N2WsK5stszgYKoIROJCiXwjraa8/SoFcILolWQpttVHBIUYl"
            + "yDlm8mIFleZf4ReFpfm+nUYxAgMBAAGjgcMwgcAwCQYDVR0TBAIwADAsBglghkgB"
            + "hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE"
            + "FDgRgTkjaKoK6DoZfUZ4g9LDJUWuMFUGA1UdIwROMEyAFNXuZVPeUdqHrULqQW7y"
            + "r9buRpQLoTGkLzAtMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDmNhLmV4"
            + "YW1wbGUub3JnggEBMA8GA1UdEQQIMAaHBAoBAgMwDQYJKoZIhvcNAQEFBQADggEB"
            + "AIgpJnJ9Pid+ldf/jvO/BRQkHdRkuzMP3AwLvzSIJPcJAw4Dvzqm57VQaJDnfqqX"
            + "SN9POAPlpsBzBE8Xdtpp5TemJt7X2wjuCHTlvGY/HaPPvb3QielWsU4As6Xdk1xY"
            + "ovTPtGnbh+gsPT5jdrA+d5PKEsXicZEVqGOIRVINuDUhZsl0Y26SJmskWNKAb7l4"
            + "7jPQj8U2kkWUEWXkOv5FsyiB2KdxYGbJSpGwGLRWZNDbuVUjnuzQ29EWWbNwHxTb"
            + "GMRjrI9Q4WynZ2IOcnG1hMjCU6L4uk4JfryIw4IBHGa8uUtskHqJ7TFJ/4taWyV/" + "UB0djqOPjMACQpMBhEVRSBU=";

    private String altNameDNS, altNameURN, altNameURL, altNameIP;

    private Integer altNameTypeDNS, altNameTypeURI, altNameTypeIP;

    private static String subjectAltNameExtensionOID = "2.5.29.17";

    /** A PEM encoded cert. */
    private String certPEM = "/data/certificate.pem";

    /** A PEM encoded cert. */
    private String certDER = "/data/certificate.der";

    /** A PEM encoded CRL. */
    private String crlPEM = "/data/crl.pem";

    /** A PEM encoded CRL. */
    private String crlDER = "/data/crl.der";

    @BeforeMethod
    protected void setUp() throws Exception {
        entityPrivateKey = KeySupport.buildJavaRSAPrivateKey(entityPrivKeyBase64);
        entityCert = X509Support.decodeCertificate(entityCertBase64);

        entityCert3AltNamesDNS_URL_IP = X509Support.decodeCertificate(entityCert3AltNamesDNS_URL_IPBase64);
        entityCert3AltNamesDNS_URN_IP = X509Support.decodeCertificate(entityCert3AltNamesDNS_URN_IPBase64);
        entityCert1AltNameDNS = X509Support.decodeCertificate(entityCert1AltNameDNSBase64);
        entityCert1AltNameURN = X509Support.decodeCertificate(entityCert1AltNameURNBase64);
        entityCert1AltNameURL = X509Support.decodeCertificate(entityCert1AltNameURLBase64);
        entityCert1AltNameIP = X509Support.decodeCertificate(entityCert1AltNameIPBase64);

        altNameDNS = "asimov.example.org";
        altNameURN = "urn:foo:example.org:idp";
        altNameURL = "http://heinlein.example.org";
        altNameIP = "10.1.2.3";

        altNameTypeIP = X509Support.IP_ADDRESS_ALT_NAME;
        altNameTypeURI = X509Support.URI_ALT_NAME;
        altNameTypeDNS = X509Support.DNS_ALT_NAME;
    }

    /**
     *  Test common name (CN) extraction from X500Principal.
     */
    @Test
    public void testGetCommonNames() {
        List<String> commonNames;

        // 1 component
        commonNames = X509Support.getCommonNames(new X500Principal("cn=foo.example.org"));
        Assert.assertNotNull(commonNames);
        Assert.assertEquals(commonNames.size(), 1);
        Assert.assertEquals(commonNames.get(0), "foo.example.org");

        // 2 components, 1 cn
        commonNames = X509Support.getCommonNames(new X500Principal("cn=foo.example.org, o=MyOrg"));
        Assert.assertNotNull(commonNames);
        Assert.assertEquals(commonNames.size(), 1);
        Assert.assertEquals(commonNames.get(0), "foo.example.org");

        // 2 components each with cn
        commonNames = X509Support.getCommonNames(new X500Principal("cn=foo.example.org, cn=MyOrg"));
        Assert.assertNotNull(commonNames);
        Assert.assertEquals(commonNames.size(), 2);
        Assert.assertEquals(commonNames.get(0), "foo.example.org");
        Assert.assertEquals(commonNames.get(1), "MyOrg");

        // 4 components, 3 cn
        commonNames = X509Support
                .getCommonNames(new X500Principal("cn=foo.example.org, cn=WebServers, cn=Hosts, o=MyOrg"));
        Assert.assertNotNull(commonNames);
        Assert.assertEquals(commonNames.size(), 3);
        Assert.assertEquals(commonNames.get(0), "foo.example.org");
        Assert.assertEquals(commonNames.get(1), "WebServers");
        Assert.assertEquals(commonNames.get(2), "Hosts");

        // 4 components, 2 cn, a cn is not first nor last
        commonNames = X509Support.getCommonNames(new X500Principal("uid=foo, cn=Admins, cn=People, o=MyOrg"));
        Assert.assertNotNull(commonNames);
        Assert.assertEquals(commonNames.size(), 2);
        Assert.assertEquals(commonNames.get(0), "Admins");
        Assert.assertEquals(commonNames.get(1), "People");

        // 2 components, one of them with multiple cn AVAs
        // Note: The set of AVAs in a DN component is unordered, so can't test returned ordering.
        commonNames = X509Support.getCommonNames(
                new X500Principal("cn=foo.example.org+cn=bar.example.org+cn=baz.example.org, o=MyOrg"));
        Assert.assertNotNull(commonNames);
        Assert.assertEquals(commonNames.size(), 3);
        Assert.assertTrue(commonNames.contains("foo.example.org"));
        Assert.assertTrue(commonNames.contains("bar.example.org"));
        Assert.assertTrue(commonNames.contains("baz.example.org"));

        // 2 components, both with multiple cn AVAs
        // Note: The set of AVAs in a DN component is unordered, so can't test returned ordering.
        commonNames = X509Support.getCommonNames(
                new X500Principal("cn=foo.example.org+cn=bar.example.org+cn=baz.example.org, cn=Org1+cn=Org2"));
        Assert.assertNotNull(commonNames);
        Assert.assertEquals(commonNames.size(), 5);
        Assert.assertTrue(commonNames.contains("foo.example.org"));
        Assert.assertTrue(commonNames.contains("bar.example.org"));
        Assert.assertTrue(commonNames.contains("baz.example.org"));
        Assert.assertTrue(commonNames.contains("Org1"));
        Assert.assertTrue(commonNames.contains("Org2"));

        // No cn at all
        commonNames = X509Support.getCommonNames(new X500Principal("uid=foo, o=MyOrg"));
        Assert.assertNotNull(commonNames);
        Assert.assertEquals(commonNames.size(), 0);

        // Test input of raw OID
        commonNames = X509Support.getCommonNames(new X500Principal("2.5.4.3=foo.example.org"));
        Assert.assertNotNull(commonNames);
        Assert.assertEquals(commonNames.size(), 1);
        Assert.assertEquals(commonNames.get(0), "foo.example.org");

        // Test attack DNs per CVE-2014-3577
        commonNames = X509Support
                .getCommonNames(new X500Principal("cn=foo.example.org, o=foo \\,cn=www.apache.org"));
        Assert.assertNotNull(commonNames);
        Assert.assertEquals(commonNames.size(), 1);
        Assert.assertFalse(commonNames.contains("www.apache.org"));
        Assert.assertEquals(commonNames.get(0), "foo.example.org");

        commonNames = X509Support
                .getCommonNames(new X500Principal("cn=foo.example.org, o=cn=www.apache.org\\, foo"));
        Assert.assertNotNull(commonNames);
        Assert.assertEquals(commonNames.size(), 1);
        Assert.assertFalse(commonNames.contains("www.apache.org"));
        Assert.assertEquals(commonNames.get(0), "foo.example.org");
    }

    /**
     *  Test Subject Key Identifier (SKI) extraction from certificate.
     * @throws DecoderException 
     */
    @Test
    public void testGetSubjectKeyIdentifier() throws DecoderException {
        // This is the cert SKI according to OpenSSL 'openssl x509 -in entity.crt -noout -text'
        String hexSKI = "D2:57:F5:C1:8C:11:26:1B:C6:65:82:F6:5A:93:0E:CA:40:CD:75:E5";
        byte[] controlSKI = Hex.decodeHex(hexSKI.replaceAll(":", "").toCharArray());
        byte[] certSKI = X509Support.getSubjectKeyIdentifier(entityCert);
        Assert.assertEquals(certSKI, controlSKI);
    }

    /**
     * Tests that the entity cert is correctly identified in the collection.
     * 
     * @throws Exception
     */
    @Test
    public void testDetermineEntityCertificate() throws Exception {
        ArrayList<X509Certificate> certs = new ArrayList<>();
        certs.add(entityCert3AltNamesDNS_URL_IP);
        certs.add(entityCert1AltNameDNS);
        certs.add(entityCert);

        Assert.assertTrue(X509Support.determineEntityCertificate(certs, entityPrivateKey).equals(entityCert));
    }

    /**
     * Test 1 alt name: DNS.
     * 
     * @throws SecurityException
     * @throws CertificateParsingException
     */
    @Test
    public void testGetSubjectAltNames1NameDNS() throws SecurityException, CertificateParsingException {
        X509Certificate cert = entityCert1AltNameDNS;
        // Sanity checks
        byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID);
        Assert.assertNotNull(extensionValue, "Entity cert's Java native getExtensionValue() was null");
        Assert.assertTrue(extensionValue.length > 0, "Entity cert's extension value was empty");

        Set<Integer> nameTypes = new HashSet<>();
        nameTypes.add(altNameTypeDNS);

        List altNames = getAltNames(cert, nameTypes);
        Assert.assertNotNull(altNames, "X509Support.getAltNames() returned null");

        Assert.assertTrue(altNames.contains(altNameDNS), "Failed to find expected KeyName value");
    }

    /**
     * Test 1 alt name: URI (URN).
     * 
     * @throws SecurityException
     * @throws CertificateParsingException
     */
    @Test
    public void testGetSubjectAltNames1NameURN() throws SecurityException, CertificateParsingException {
        X509Certificate cert = entityCert1AltNameURN;
        // Sanity checks
        byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID);
        Assert.assertNotNull(extensionValue, "Entity cert's Java native getExtensionValue() was null");
        Assert.assertTrue(extensionValue.length > 0, "Entity cert's extension value was empty");

        Set<Integer> nameTypes = new HashSet<>();
        nameTypes.add(altNameTypeURI);

        List altNames = getAltNames(cert, nameTypes);
        Assert.assertNotNull(altNames, "X509Support.getAltNames() returned null");

        Assert.assertTrue(altNames.contains(altNameURN), "Failed to find expected KeyName value");
    }

    /**
     * Test 1 alt name: URI (URL).
     * 
     * @throws SecurityException
     * @throws CertificateParsingException
     */
    @Test
    public void testGetSubjectAltNames1NameURL() throws SecurityException, CertificateParsingException {
        X509Certificate cert = entityCert1AltNameURL;
        // Sanity checks
        byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID);
        Assert.assertNotNull(extensionValue, "Entity cert's Java native getExtensionValue() was null");
        Assert.assertTrue(extensionValue.length > 0, "Entity cert's extension value was empty");

        Set<Integer> nameTypes = new HashSet<>();
        nameTypes.add(altNameTypeURI);

        List altNames = getAltNames(cert, nameTypes);
        Assert.assertNotNull(altNames, "X509Support.getAltNames() returned null");

        Assert.assertTrue(altNames.contains(altNameURL), "Failed to find expected KeyName value");
    }

    /**
     * Test 1 alt name: IP.
     * 
     * @throws SecurityException
     * @throws CertificateParsingException
     */
    @Test
    public void testGetSubjectAltNames1NameIP() throws SecurityException, CertificateParsingException {
        X509Certificate cert = entityCert1AltNameIP;
        // Sanity checks
        byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID);
        Assert.assertNotNull(extensionValue, "Entity cert's Java native getExtensionValue() was null");
        Assert.assertTrue(extensionValue.length > 0, "Entity cert's extension value was empty");

        Set<Integer> nameTypes = new HashSet<>();
        nameTypes.add(altNameTypeIP);

        List altNames = getAltNames(cert, nameTypes);
        Assert.assertNotNull(altNames, "X509Support.getAltNames() returned null");

        Assert.assertTrue(altNames.contains(altNameIP), "Failed to find expected KeyName value");
    }

    /**
     * Test 3 alt names: DNS, URI (URL), IP.
     * 
     * @throws SecurityException
     * @throws CertificateParsingException
     */
    @Test
    public void testGetSubjectAltNames3NamesDNS_URL_IP() throws SecurityException, CertificateParsingException {
        X509Certificate cert = entityCert3AltNamesDNS_URL_IP;
        // Sanity checks
        byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID);
        Assert.assertNotNull(extensionValue, "Entity cert's Java native getExtensionValue() was null");
        Assert.assertTrue(extensionValue.length > 0, "Entity cert's extension value was empty");

        Set<Integer> nameTypes = new HashSet<>();
        nameTypes.add(altNameTypeDNS);
        nameTypes.add(altNameTypeURI);
        nameTypes.add(altNameTypeIP);

        List altNames = getAltNames(cert, nameTypes);
        Assert.assertNotNull(altNames, "X509Support.getAltNames() returned null");

        Assert.assertTrue(altNames.contains(altNameDNS), "Failed to find expected KeyName value");
        Assert.assertTrue(altNames.contains(altNameURL), "Failed to find expected KeyName value");
        Assert.assertTrue(altNames.contains(altNameIP), "Failed to find expected KeyName value");
    }

    /**
     * Test 3 alt names: DNS, URI (URN), IP.
     * 
     * @throws SecurityException
     * @throws CertificateParsingException
     */
    @Test
    public void testGetSubjectAltNames3NamesDNS_URN_IP() throws SecurityException, CertificateParsingException {
        X509Certificate cert = entityCert3AltNamesDNS_URN_IP;
        // Sanity checks
        byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID);
        Assert.assertNotNull(extensionValue, "Entity cert's Java native getExtensionValue() was null");
        Assert.assertTrue(extensionValue.length > 0, "Entity cert's extension value was empty");

        Set<Integer> nameTypes = new HashSet<>();
        nameTypes.add(altNameTypeDNS);
        nameTypes.add(altNameTypeURI);
        nameTypes.add(altNameTypeIP);

        List altNames = getAltNames(cert, nameTypes);
        Assert.assertNotNull(altNames, "X509Support.getAltNames() returned null");

        Assert.assertTrue(altNames.contains(altNameDNS), "Failed to find expected KeyName value");
        Assert.assertTrue(altNames.contains(altNameURN), "Failed to find expected KeyName value");
        Assert.assertTrue(altNames.contains(altNameIP), "Failed to find expected KeyName value");
    }

    /** Test decoding a PEM encoded cert. */
    @Test
    public void testDecodeCertPEM() throws Exception {
        InputStream certInS = X509SupportTest.class.getResourceAsStream(certPEM);

        byte[] certBytes = new byte[certInS.available()];
        certInS.read(certBytes);

        Collection<X509Certificate> certs = X509Support.decodeCertificates(certBytes);
        Assert.assertNotNull(certs);
        Assert.assertEquals(certs.size(), 2);
    }

    /** Test decoding a DER encoded cert. */
    @Test
    public void testDecodeCertDER() throws Exception {
        InputStream certInS = X509SupportTest.class.getResourceAsStream(certDER);

        byte[] certBytes = new byte[certInS.available()];
        certInS.read(certBytes);

        Collection<X509Certificate> certs = X509Support.decodeCertificates(certBytes);
        Assert.assertNotNull(certs);
        Assert.assertEquals(certs.size(), 1);

        X509Certificate cert = X509Support.decodeCertificate(certBytes);
        Assert.assertNotNull(cert);
    }

    /** Test decoding a PEM encoded CRL. */
    @Test
    public void testDecodeCRLPEM() throws Exception {
        InputStream crlInS = X509SupportTest.class.getResourceAsStream(crlPEM);

        byte[] crlBytes = new byte[crlInS.available()];
        crlInS.read(crlBytes);

        Collection<X509CRL> crls = X509Support.decodeCRLs(crlBytes);
        Assert.assertNotNull(crls);
        Assert.assertEquals(crls.size(), 1);
    }

    /** Test decoding a DER encoded CRL. */
    @Test
    public void testDecodeCRLDER() throws Exception {
        InputStream crlInS = X509SupportTest.class.getResourceAsStream(crlDER);

        byte[] crlBytes = new byte[crlInS.available()];
        crlInS.read(crlBytes);

        Collection<X509CRL> crls = X509Support.decodeCRLs(crlBytes);
        Assert.assertNotNull(crls);
        Assert.assertEquals(crls.size(), 1);
    }

    /**
     * Get the alt names from the certificate.
     * 
     * @param cert the cert to process
     * @param nameTypes set of Integers identifying which alt name types to extract
     * @return list of alt name value Objects
     */
    private List getAltNames(X509Certificate cert, Set<Integer> nameTypes) {
        Integer[] array = new Integer[nameTypes.size()];
        nameTypes.toArray(array);
        return X509Support.getAltNames(cert, array);
    }
}