Java tutorial
/* * 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.xml.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.Arrays; 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.xml.XMLObjectBaseTestCase; import org.opensaml.xml.security.DefaultSecurityConfigurationBootstrap; import org.opensaml.xml.security.SecurityException; import org.opensaml.xml.security.SecurityHelper; /** * Tests the X509Util utility methods. */ public class X509UtilTest extends XMLObjectBaseTestCase { 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 entityCertSKIBase64 = "OBGBOSNoqgroOhl9RniD0sMlRa4="; private String caCertBase64 = "MIIDXTCCAkWgAwIBAgIBATANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQKEwlJbnRl" + "cm5ldDIxFzAVBgNVBAMTDmNhLmV4YW1wbGUub3JnMB4XDTA3MDQwOTA1NDcxMloX" + "DTE3MDQwNjA1NDcxMlowLTESMBAGA1UEChMJSW50ZXJuZXQyMRcwFQYDVQQDEw5j" + "YS5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxM" + "5/6mBCcX+S7HApcKtfqdFRZzi6Ra91nkEzXOUcO+BPUdYqSxKGnCCso25ZOZP3gn" + "JVkY8Pi7VWrCM6wRgIMyQDvNYqCpNjkZGFkrMoa6fm8BSaDHJ1fz6l/eEl0CVU3U" + "uUAf0mXQLGm6Jannq8aMolRujlhE5iRaOJ2qp6wqsvyatK+vTgDngnwYVa4Cqu0j" + "UeNF28quST5D3gIuZ0OeFHSM2Z1WUKkwwsHqVkxBBcH1QE1JOGIoSnrxxl/o4VlL" + "WGEI8zq5qixE8VYtBBmijBwIL5ETy2fwiqcsvimQaQAtAfbtpO3kBSs8n7nnzMUH" + "fRlcebGkwwcNfYcD5hcCAwEAAaOBhzCBhDAdBgNVHQ4EFgQU1e5lU95R2oetQupB" + "bvKv1u5GlAswVQYDVR0jBE4wTIAU1e5lU95R2oetQupBbvKv1u5GlAuhMaQvMC0x" + "EjAQBgNVBAoTCUludGVybmV0MjEXMBUGA1UEAxMOY2EuZXhhbXBsZS5vcmeCAQEw" + "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAbqrozetM/iBVIUir9k14" + "HbLEP0lZ6jOPWFIUFXMOn0t8+Ul7PMp9Rdn+7OGQIoJw97/mam3kpQ/HmjJMFYv6" + "MGsDQ4vAOiQiaTKzgMhrnCdVpVH9uz4ARHiysCujnjH9sehTWgybY8pXzzSG5BAj" + "EGowHq01nXxq2K4yAJSdAUBYLfuSKW1uRU6cmEa9uzl9EvoZfAF3BLnGlPqu4Zaj" + "H2NC9ZY0y19LX4yeJLHL1sY4fyxb3x8QhcCXiI16awBTr/VnUpJjSe9vh+OudWGe" + "yCL/KhjlrDkjJ3hIxBF5mP/Y27cFpRnC2gECkieURvh52OyuqkzpbOrTN5rD9fNi" + "nA=="; private String altNameDNS, altNameURN, altNameURL, altNameIP; private Integer altNameTypeDNS, altNameTypeURI, altNameTypeIP; private String caCRLBase64 = "MIIBmjCBgwIBATANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQKEwlJbnRlcm5ldDIx" + "FzAVBgNVBAMTDmNhLmV4YW1wbGUub3JnFw0wNzA1MjEwNTAwMzNaFw0wNzA2MjAw" + "NTAwMzNaMCIwIAIBKxcNMDcwNTIxMDQ1ODI5WjAMMAoGA1UdFQQDCgEBMA0GCSqG" + "SIb3DQEBBQUAA4IBAQAghL5eW9NsMRCk84mAZ+QMjoCuy7zZJr5vPHk7WrOffL7B" + "GWZ6u6D1cSCzZNvrBolip1yb8KSdB9PJqEV1kInXnZegeqjENq+9j8nGdyoYuofh" + "A5AU8L9n9fjwYTUkfNfAMWeVVuplJN4yAp03JSJULVqmC63EEP7u7kFS94Mze9sa" + "+VqBu7tGyZ55XX8AO39d1c3DoHIPfS1wHHLyuWxnys8GjANJxQiZmFtUfPztp3qH" + "/XlfFLgY5EBTanyOk5yycU/l+6P1RBhJZDPicp3iWVsjYHYWS+ovdyWuL7RrLRMb" + "zecnCa5eIhSevoMYUkg4h9ckAZUQeHsK08gB/dFh"; 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"; /** {@inheritDoc} */ protected void setUp() throws Exception { super.setUp(); entityPrivateKey = SecurityHelper.buildJavaRSAPrivateKey(entityPrivKeyBase64); entityCert = SecurityHelper.buildJavaX509Cert(entityCertBase64); entityCert3AltNamesDNS_URL_IP = SecurityHelper.buildJavaX509Cert(entityCert3AltNamesDNS_URL_IPBase64); entityCert3AltNamesDNS_URN_IP = SecurityHelper.buildJavaX509Cert(entityCert3AltNamesDNS_URN_IPBase64); entityCert1AltNameDNS = SecurityHelper.buildJavaX509Cert(entityCert1AltNameDNSBase64); entityCert1AltNameURN = SecurityHelper.buildJavaX509Cert(entityCert1AltNameURNBase64); entityCert1AltNameURL = SecurityHelper.buildJavaX509Cert(entityCert1AltNameURLBase64); entityCert1AltNameIP = SecurityHelper.buildJavaX509Cert(entityCert1AltNameIPBase64); altNameDNS = "asimov.example.org"; altNameURN = "urn:foo:example.org:idp"; altNameURL = "http://heinlein.example.org"; altNameIP = "10.1.2.3"; altNameTypeIP = X509Util.IP_ADDRESS_ALT_NAME; altNameTypeURI = X509Util.URI_ALT_NAME; altNameTypeDNS = X509Util.DNS_ALT_NAME; } /** * Test common name (CN) extraction from X500Principal. */ public void testGetCommonNames() { List<String> commonNames; // 1 component commonNames = X509Util.getCommonNames(new X500Principal("cn=foo.example.org")); assertNotNull(commonNames); assertEquals(1, commonNames.size()); assertEquals("foo.example.org", commonNames.get(0)); // 2 components, 1 cn commonNames = X509Util.getCommonNames(new X500Principal("cn=foo.example.org, o=MyOrg")); assertNotNull(commonNames); assertEquals(1, commonNames.size()); assertEquals("foo.example.org", commonNames.get(0)); // 2 components each with cn commonNames = X509Util.getCommonNames(new X500Principal("cn=foo.example.org, cn=MyOrg")); assertNotNull(commonNames); assertEquals(2, commonNames.size()); assertEquals("foo.example.org", commonNames.get(0)); assertEquals("MyOrg", commonNames.get(1)); // 4 components, 3 cn commonNames = X509Util .getCommonNames(new X500Principal("cn=foo.example.org, cn=WebServers, cn=Hosts, o=MyOrg")); assertNotNull(commonNames); assertEquals(3, commonNames.size()); assertEquals("foo.example.org", commonNames.get(0)); assertEquals("WebServers", commonNames.get(1)); assertEquals("Hosts", commonNames.get(2)); // 4 components, 2 cn, a cn is not first nor last commonNames = X509Util.getCommonNames(new X500Principal("uid=foo, cn=Admins, cn=People, o=MyOrg")); assertNotNull(commonNames); assertEquals(2, commonNames.size()); assertEquals("Admins", commonNames.get(0)); assertEquals("People", commonNames.get(1)); // 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 = X509Util.getCommonNames( new X500Principal("cn=foo.example.org+cn=bar.example.org+cn=baz.example.org, o=MyOrg")); assertNotNull(commonNames); assertEquals(3, commonNames.size()); assertTrue(commonNames.contains("foo.example.org")); assertTrue(commonNames.contains("bar.example.org")); 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 = X509Util.getCommonNames( new X500Principal("cn=foo.example.org+cn=bar.example.org+cn=baz.example.org, cn=Org1+cn=Org2")); assertNotNull(commonNames); assertEquals(5, commonNames.size()); assertTrue(commonNames.subList(0, 3).contains("foo.example.org")); assertTrue(commonNames.subList(0, 3).contains("bar.example.org")); assertTrue(commonNames.subList(0, 3).contains("baz.example.org")); assertTrue(commonNames.subList(3, 5).contains("Org1")); assertTrue(commonNames.subList(3, 5).contains("Org2")); // No cn at all commonNames = X509Util.getCommonNames(new X500Principal("uid=foo, o=MyOrg")); assertNotNull(commonNames); assertEquals(0, commonNames.size()); // Test input of raw OID commonNames = X509Util.getCommonNames(new X500Principal("2.5.4.3=foo.example.org")); assertNotNull(commonNames); assertEquals(1, commonNames.size()); assertEquals("foo.example.org", commonNames.get(0)); // Test attack DNs per CVE-2014-3577 commonNames = X509Util.getCommonNames(new X500Principal("cn=foo.example.org, o=foo \\,cn=www.apache.org")); assertNotNull(commonNames); assertEquals(1, commonNames.size()); assertFalse(commonNames.contains("www.apache.org")); assertEquals("foo.example.org", commonNames.get(0)); commonNames = X509Util.getCommonNames(new X500Principal("cn=foo.example.org, o=cn=www.apache.org\\, foo")); assertNotNull(commonNames); assertEquals(1, commonNames.size()); assertFalse(commonNames.contains("www.apache.org")); assertEquals("foo.example.org", commonNames.get(0)); } /** * Test Subject Key Identifier (SKI) extraction from certificate. * @throws DecoderException */ 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 = X509Util.getSubjectKeyIdentifier(entityCert); assertTrue(Arrays.equals(controlSKI, certSKI)); } /** * Tests that the entity cert is correctly identified in the collection. * * @throws Exception */ public void testDetermineEntityCertificate() throws Exception { org.opensaml.xml.Configuration .setGlobalSecurityConfiguration(DefaultSecurityConfigurationBootstrap.buildDefaultConfig()); ArrayList<X509Certificate> certs = new ArrayList<X509Certificate>(); certs.add(entityCert3AltNamesDNS_URL_IP); certs.add(entityCert1AltNameDNS); certs.add(entityCert); assertTrue(X509Util.determineEntityCertificate(certs, entityPrivateKey).equals(entityCert)); } /** * Test 1 alt name: DNS. * @throws SecurityException * @throws CertificateParsingException */ public void testGetSubjectAltNames1NameDNS() throws SecurityException, CertificateParsingException { X509Certificate cert = entityCert1AltNameDNS; // Sanity checks byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID); assertNotNull("Entity cert's Java native getExtensionValue() was null", extensionValue); assertTrue("Entity cert's extension value was empty", extensionValue.length > 0); Set<Integer> nameTypes = new HashSet<Integer>(); nameTypes.add(altNameTypeDNS); List altNames = getAltNames(cert, nameTypes); assertNotNull("X509Util.getAltNames() returned null", altNames); assertTrue("Failed to find expected KeyName value", altNames.contains(altNameDNS)); } /** * Test 1 alt name: URI (URN). * @throws SecurityException * @throws CertificateParsingException */ public void testGetSubjectAltNames1NameURN() throws SecurityException, CertificateParsingException { X509Certificate cert = entityCert1AltNameURN; // Sanity checks byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID); assertNotNull("Entity cert's Java native getExtensionValue() was null", extensionValue); assertTrue("Entity cert's extension value was empty", extensionValue.length > 0); Set<Integer> nameTypes = new HashSet<Integer>(); nameTypes.add(altNameTypeURI); List altNames = getAltNames(cert, nameTypes); assertNotNull("X509Util.getAltNames() returned null", altNames); assertTrue("Failed to find expected KeyName value", altNames.contains(altNameURN)); } /** * Test 1 alt name: URI (URL). * @throws SecurityException * @throws CertificateParsingException */ public void testGetSubjectAltNames1NameURL() throws SecurityException, CertificateParsingException { X509Certificate cert = entityCert1AltNameURL; // Sanity checks byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID); assertNotNull("Entity cert's Java native getExtensionValue() was null", extensionValue); assertTrue("Entity cert's extension value was empty", extensionValue.length > 0); Set<Integer> nameTypes = new HashSet<Integer>(); nameTypes.add(altNameTypeURI); List altNames = getAltNames(cert, nameTypes); assertNotNull("X509Util.getAltNames() returned null", altNames); assertTrue("Failed to find expected KeyName value", altNames.contains(altNameURL)); } /** * Test 1 alt name: IP. * @throws SecurityException * @throws CertificateParsingException */ public void testGetSubjectAltNames1NameIP() throws SecurityException, CertificateParsingException { X509Certificate cert = entityCert1AltNameIP; // Sanity checks byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID); assertNotNull("Entity cert's Java native getExtensionValue() was null", extensionValue); assertTrue("Entity cert's extension value was empty", extensionValue.length > 0); Set<Integer> nameTypes = new HashSet<Integer>(); nameTypes.add(altNameTypeIP); List altNames = getAltNames(cert, nameTypes); assertNotNull("X509Util.getAltNames() returned null", altNames); assertTrue("Failed to find expected KeyName value", altNames.contains(altNameIP)); } /** * Test 3 alt names: DNS, URI (URL), IP. * @throws SecurityException * @throws CertificateParsingException */ public void testGetSubjectAltNames3NamesDNS_URL_IP() throws SecurityException, CertificateParsingException { X509Certificate cert = entityCert3AltNamesDNS_URL_IP; // Sanity checks byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID); assertNotNull("Entity cert's Java native getExtensionValue() was null", extensionValue); assertTrue("Entity cert's extension value was empty", extensionValue.length > 0); Set<Integer> nameTypes = new HashSet<Integer>(); nameTypes.add(altNameTypeDNS); nameTypes.add(altNameTypeURI); nameTypes.add(altNameTypeIP); List altNames = getAltNames(cert, nameTypes); assertNotNull("X509Util.getAltNames() returned null", altNames); assertTrue("Failed to find expected KeyName value", altNames.contains(altNameDNS)); assertTrue("Failed to find expected KeyName value", altNames.contains(altNameURL)); assertTrue("Failed to find expected KeyName value", altNames.contains(altNameIP)); } /** * Test 3 alt names: DNS, URI (URN), IP. * @throws SecurityException * @throws CertificateParsingException */ public void testGetSubjectAltNames3NamesDNS_URN_IP() throws SecurityException, CertificateParsingException { X509Certificate cert = entityCert3AltNamesDNS_URN_IP; // Sanity checks byte[] extensionValue = cert.getExtensionValue(subjectAltNameExtensionOID); assertNotNull("Entity cert's Java native getExtensionValue() was null", extensionValue); assertTrue("Entity cert's extension value was empty", extensionValue.length > 0); Set<Integer> nameTypes = new HashSet<Integer>(); nameTypes.add(altNameTypeDNS); nameTypes.add(altNameTypeURI); nameTypes.add(altNameTypeIP); List altNames = getAltNames(cert, nameTypes); assertNotNull("X509Util.getAltNames() returned null", altNames); assertTrue("Failed to find expected KeyName value", altNames.contains(altNameDNS)); assertTrue("Failed to find expected KeyName value", altNames.contains(altNameURN)); assertTrue("Failed to find expected KeyName value", altNames.contains(altNameIP)); } /** Test decoding a PEM encoded cert. */ public void testDecodeCertPEM() throws Exception { InputStream certInS = X509UtilTest.class.getResourceAsStream(certPEM); byte[] certBytes = new byte[certInS.available()]; certInS.read(certBytes); Collection<X509Certificate> certs = X509Util.decodeCertificate(certBytes); assertNotNull(certs); assertEquals(2, certs.size()); } /** Test decoding a DER encoded cert. */ public void testDecodeCertPDER() throws Exception { InputStream certInS = X509UtilTest.class.getResourceAsStream(certDER); byte[] certBytes = new byte[certInS.available()]; certInS.read(certBytes); Collection<X509Certificate> certs = X509Util.decodeCertificate(certBytes); assertNotNull(certs); assertEquals(1, certs.size()); } /** Test decoding a PEM encoded CRL. */ public void testDecodeCRLPEM() throws Exception { InputStream crlInS = X509UtilTest.class.getResourceAsStream(crlPEM); byte[] crlBytes = new byte[crlInS.available()]; crlInS.read(crlBytes); Collection<X509CRL> crls = X509Util.decodeCRLs(crlBytes); assertNotNull(crls); assertEquals(1, crls.size()); } /** Test decoding a DER encoded CRL. */ public void testDecodeCRLDER() throws Exception { InputStream crlInS = X509UtilTest.class.getResourceAsStream(crlDER); byte[] crlBytes = new byte[crlInS.available()]; crlInS.read(crlBytes); Collection<X509CRL> crls = X509Util.decodeCRLs(crlBytes); assertNotNull(crls); assertEquals(1, crls.size()); } /** * 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 X509Util.getAltNames(cert, array); } }