1cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom/* 2cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * Copyright (C) 2010 The Android Open Source Project 3cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * 4cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 5cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * you may not use this file except in compliance with the License. 6cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * You may obtain a copy of the License at 7cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * 8cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 9cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * 10cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * Unless required by applicable law or agreed to in writing, software 11cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 12cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * See the License for the specific language governing permissions and 14cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom * limitations under the License. 15cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom */ 16cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom 17cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrompackage libcore.java.security.cert; 18cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom 1934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport com.android.org.bouncycastle.asn1.x509.BasicConstraints; 2034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport com.android.org.bouncycastle.asn1.x509.X509Extensions; 2134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport com.android.org.bouncycastle.x509.X509V3CertificateGenerator; 2234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport com.android.org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; 2334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport com.android.org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; 2434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 25cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstromimport java.io.ByteArrayInputStream; 2634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.io.ByteArrayOutputStream; 27bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Rootimport java.io.IOException; 28bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Rootimport java.io.InputStream; 2934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.io.ObjectInputStream; 3034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.io.ObjectOutputStream; 3134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.io.OptionalDataException; 3234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.io.StreamCorruptedException; 3334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.math.BigInteger; 3434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.security.KeyPair; 3534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.security.KeyPairGenerator; 3634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.security.PrivateKey; 37bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Rootimport java.security.Provider; 38bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Rootimport java.security.Security; 3934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.security.cert.CertPath; 40cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstromimport java.security.cert.Certificate; 4134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.security.cert.CertificateEncodingException; 42cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstromimport java.security.cert.CertificateException; 43cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstromimport java.security.cert.CertificateFactory; 4434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.security.cert.X509Certificate; 4534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.util.ArrayList; 4634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.util.Arrays; 4734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.util.Date; 4834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.util.GregorianCalendar; 4934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.util.Iterator; 5034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.util.List; 5134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport java.util.TimeZone; 5234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 5334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport javax.security.auth.x500.X500Principal; 5434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 55cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstromimport junit.framework.TestCase; 5634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Rootimport libcore.java.security.StandardNames; 57cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom 58cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrompublic class CertificateFactoryTest extends TestCase { 59cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom 60cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom private static final String VALID_CERTIFICATE_PEM = 61cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom "-----BEGIN CERTIFICATE-----\n" 62cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM\n" 63cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg\n" 64cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x\n" 65cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh\n" 66cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw\n" 67cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC\n" 68cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN\n" 69cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L\n" 70cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM\n" 71cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl\n" 72cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF\n" 73cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw\n" 74cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0\n" 75cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF\n" 76cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5\n" 77cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6\n" 78cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==\n" 79cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "-----END CERTIFICATE-----\n"; 80cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom 81e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root private static final String VALID_CERTIFICATE_PEM_CRLF = 82e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root "-----BEGIN CERTIFICATE-----\r\n" 83e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM\r\n" 84e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg\r\n" 85e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x\r\n" 86e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh\r\n" 87e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw\r\n" 88e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC\r\n" 89e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN\r\n" 90e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L\r\n" 91e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM\r\n" 92e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl\r\n" 93e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF\r\n" 94e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw\r\n" 95e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0\r\n" 96e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF\r\n" 97e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5\r\n" 98e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6\r\n" 99e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==\r\n" 100e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "-----END CERTIFICATE-----\r\n"; 101e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root 102e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root private static final byte[] VALID_CERTIFICATE_PEM_HEADER = "-----BEGIN CERTIFICATE-----\n" 103e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root .getBytes(); 104e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root 105e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root private static final byte[] VALID_CERTIFICATE_PEM_DATA = 106e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root ("MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM" 107e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg" 108e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x" 109e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh" 110e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw" 111e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC" 112e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN" 113e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L" 114e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM" 115e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl" 116e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF" 117e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw" 118e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0" 119e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF" 120e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5" 121e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6" 122e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==").getBytes(); 123e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root 124e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root private static final byte[] VALID_CERTIFICATE_PEM_FOOTER = "\n-----END CERTIFICATE-----\n" 125e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root .getBytes(); 126e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root 127cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom private static final String INVALID_CERTIFICATE_PEM = 128cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom "-----BEGIN CERTIFICATE-----\n" 129cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 130cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 131cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 132cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 133cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 134cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 135cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 136cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 137cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 138cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 139cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 140cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 141cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 142cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 143cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 144cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 145cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 146cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 147cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 148cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 149cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 150cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 151cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 152cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 153cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 154cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 155cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 156cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 157cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 158cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 159cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 160cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 161cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" 162cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "AAAAAAAA\n" 163cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom + "-----END CERTIFICATE-----"; 164cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom 165cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom public void test_generateCertificate() throws Exception { 166bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root Provider[] providers = Security.getProviders("CertificateFactory.X509"); 167bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root for (Provider p : providers) { 168bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root CertificateFactory cf = CertificateFactory.getInstance("X509", p); 169bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root try { 170bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root test_generateCertificate(cf); 171fd30c751591675c253613373bcc133ca2c53d74fKenny Root test_generateCertificate_InputStream_Offset_Correct(cf); 172fd30c751591675c253613373bcc133ca2c53d74fKenny Root test_generateCertificate_InputStream_Empty(cf); 173e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root test_generateCertificate_InputStream_InvalidStart_Failure(cf); 174e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root test_generateCertificate_AnyLineLength_Success(cf); 175e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } catch (Throwable e) { 176bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root throw new Exception("Problem testing " + p.getName(), e); 177bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 178bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 179cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom } 180bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 181cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom private void test_generateCertificate(CertificateFactory cf) throws Exception { 182e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root { 183e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root byte[] valid = VALID_CERTIFICATE_PEM.getBytes(); 184e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root Certificate c = cf.generateCertificate(new ByteArrayInputStream(valid)); 185e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root assertNotNull(c); 186e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 187e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root 188e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root { 189e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root byte[] valid = VALID_CERTIFICATE_PEM_CRLF.getBytes(); 190e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root Certificate c = cf.generateCertificate(new ByteArrayInputStream(valid)); 191e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root assertNotNull(c); 192e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 193cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom 194cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom try { 195cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom byte[] invalid = INVALID_CERTIFICATE_PEM.getBytes(); 196cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom cf.generateCertificate(new ByteArrayInputStream(invalid)); 197cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom fail(); 198cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom } catch (CertificateException expected) { 199cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom } 200cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom } 201cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom 202e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root /* 203e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root * Checks all possible line lengths for PEM input data. 204e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root */ 205e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root private void test_generateCertificate_AnyLineLength_Success(CertificateFactory cf) 206e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root throws Exception { 207e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root // RI barfs on this 208e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root if (StandardNames.IS_RI) { 209e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root return; 210e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 211e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root 212e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root int lineLength = 1; 213e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root int maxLineLength = VALID_CERTIFICATE_PEM_DATA.length; 214e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root 215e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root ByteArrayOutputStream baos = new ByteArrayOutputStream(); 216e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root baos.write(VALID_CERTIFICATE_PEM_HEADER); 217e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root int offset = 0; 218e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root while (lineLength < (maxLineLength - 4)) { 219e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root int end = offset + lineLength; 220e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root if (end > VALID_CERTIFICATE_PEM_DATA.length) { 221e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root end = VALID_CERTIFICATE_PEM_DATA.length; 222e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 223e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root baos.write(Arrays.copyOfRange(VALID_CERTIFICATE_PEM_DATA, offset, end)); 224e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root baos.write('\n'); 225e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root offset += lineLength; 226e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root if (offset >= maxLineLength) { 227e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root baos.write(VALID_CERTIFICATE_PEM_FOOTER); 228e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root try { 229e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root Certificate c = 230e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root cf.generateCertificate(new ByteArrayInputStream(baos.toByteArray())); 231e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root assertNotNull(c); 232e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } catch (Exception e) { 233e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root throw new Exception("Fail at line length " + lineLength, e); 234e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 235e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root baos.reset(); 236e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root baos.write(VALID_CERTIFICATE_PEM_HEADER); 237e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root offset = 0; 238e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } else { 239e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root lineLength++; 240e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 241e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 242e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root 243e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 244e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root 245fd30c751591675c253613373bcc133ca2c53d74fKenny Root private void test_generateCertificate_InputStream_Empty(CertificateFactory cf) throws Exception { 246fd30c751591675c253613373bcc133ca2c53d74fKenny Root try { 247fd30c751591675c253613373bcc133ca2c53d74fKenny Root Certificate c = cf.generateCertificate(new ByteArrayInputStream(new byte[0])); 248fd30c751591675c253613373bcc133ca2c53d74fKenny Root if (!"BC".equals(cf.getProvider().getName())) { 249fd30c751591675c253613373bcc133ca2c53d74fKenny Root fail("should throw CertificateException: " + cf.getProvider().getName()); 250fd30c751591675c253613373bcc133ca2c53d74fKenny Root } 251fd30c751591675c253613373bcc133ca2c53d74fKenny Root assertNull(c); 252fd30c751591675c253613373bcc133ca2c53d74fKenny Root } catch (CertificateException e) { 253fd30c751591675c253613373bcc133ca2c53d74fKenny Root if ("BC".equals(cf.getProvider().getName())) { 254fd30c751591675c253613373bcc133ca2c53d74fKenny Root fail("should return null: " + cf.getProvider().getName()); 255fd30c751591675c253613373bcc133ca2c53d74fKenny Root } 256fd30c751591675c253613373bcc133ca2c53d74fKenny Root } 257fd30c751591675c253613373bcc133ca2c53d74fKenny Root } 258fd30c751591675c253613373bcc133ca2c53d74fKenny Root 259e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root private void test_generateCertificate_InputStream_InvalidStart_Failure(CertificateFactory cf) 260e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root throws Exception { 261e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root try { 262e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root Certificate c = cf.generateCertificate(new ByteArrayInputStream( 263e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root "-----BEGIN CERTIFICATE-----".getBytes())); 264e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root if (!"BC".equals(cf.getProvider().getName())) { 265e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root fail("should throw CertificateException: " + cf.getProvider().getName()); 266e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 267e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root assertNull(c); 268e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } catch (CertificateException expected) { 269e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root if ("BC".equals(cf.getProvider().getName())) { 270e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root fail("should return null: " + cf.getProvider().getName()); 271e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 272e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 273e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root } 274e21b3caf3fb4e3e3d9244a000669a547621c16bdKenny Root 275fd30c751591675c253613373bcc133ca2c53d74fKenny Root private void test_generateCertificate_InputStream_Offset_Correct(CertificateFactory cf) 276bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root throws Exception { 277bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root byte[] valid = VALID_CERTIFICATE_PEM.getBytes(); 278bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 279bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root byte[] doubleCertificateData = new byte[valid.length * 2]; 280bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root System.arraycopy(valid, 0, doubleCertificateData, 0, valid.length); 281bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root System.arraycopy(valid, 0, doubleCertificateData, valid.length, valid.length); 282bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root MeasuredInputStream certStream = new MeasuredInputStream(new ByteArrayInputStream( 283bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root doubleCertificateData)); 284bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root Certificate certificate = cf.generateCertificate(certStream); 285bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root assertNotNull(certificate); 286bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root assertEquals(valid.length, certStream.getCount()); 287bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 288bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 289bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root /** 290bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root * Proxy that counts the number of bytes read from an InputStream. 291bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root */ 292bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root private static class MeasuredInputStream extends InputStream { 293bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root private long mCount = 0; 294bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 295bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root private long mMarked = 0; 296bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 297bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root private InputStream mStream; 298bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 299bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root public MeasuredInputStream(InputStream is) { 300bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root mStream = is; 301bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 302bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 303bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root public long getCount() { 304bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root return mCount; 305bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 306bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 307bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root @Override 308bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root public int read() throws IOException { 309bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root int nextByte = mStream.read(); 310bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root mCount++; 311bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root return nextByte; 312bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 313bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 314bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root @Override 315bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root public int read(byte[] buffer) throws IOException { 316bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root int count = mStream.read(buffer); 317bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root mCount += count; 318bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root return count; 319bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 320bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 321bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root @Override 322bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root public int read(byte[] buffer, int offset, int length) throws IOException { 323bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root int count = mStream.read(buffer, offset, length); 324bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root mCount += count; 325bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root return count; 326bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 327bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 328bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root @Override 329bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root public long skip(long byteCount) throws IOException { 330bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root long count = mStream.skip(byteCount); 331bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root mCount += count; 332bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root return count; 333bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 334bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 335bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root @Override 336bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root public int available() throws IOException { 337bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root return mStream.available(); 338bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 339bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 340bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root @Override 341bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root public void close() throws IOException { 342bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root mStream.close(); 343bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 344bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 345bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root @Override 346bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root public void mark(int readlimit) { 347bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root mMarked = mCount; 348bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root mStream.mark(readlimit); 349bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 350bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 351bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root @Override 352bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root public boolean markSupported() { 353bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root return mStream.markSupported(); 354bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 355bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root 356bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root @Override 357bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root public synchronized void reset() throws IOException { 358bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root mCount = mMarked; 359bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root mStream.reset(); 360bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 361bcd731fc88df3806f963b2c6e19b83de5aba8d35Kenny Root } 36234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 36334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root /* CertPath tests */ 36434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root public void testGenerateCertPath() throws Exception { 36534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root KeyHolder ca = generateCertificate(true, null); 36634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root KeyHolder cert1 = generateCertificate(true, ca); 36734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root KeyHolder cert2 = generateCertificate(false, cert1); 36834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root KeyHolder cert3 = generateCertificate(false, cert2); 36934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 37034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root List<X509Certificate> certs = new ArrayList<X509Certificate>(); 37134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certs.add(cert3.certificate); 37234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certs.add(cert2.certificate); 37334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certs.add(cert1.certificate); 37434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 37534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root List<X509Certificate> duplicatedCerts = new ArrayList<X509Certificate>(certs); 37634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root duplicatedCerts.add(cert2.certificate); 37734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 37834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root Provider[] providers = Security.getProviders("CertificateFactory.X509"); 37934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root for (Provider p : providers) { 38034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root final CertificateFactory cf = CertificateFactory.getInstance("X.509", p); 38134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 38234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root // Duplicate certificates can cause an exception. 38334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root { 38434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root final CertPath duplicatedPath = cf.generateCertPath(duplicatedCerts); 38534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root try { 38634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root duplicatedPath.getEncoded(); 38734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root if (StandardNames.IS_RI) { 38834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root fail("duplicate certificates should cause failure: " + p.getName()); 38934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 39034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } catch (CertificateEncodingException expected) { 39134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root if (!StandardNames.IS_RI) { 39234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root fail("duplicate certificates should pass: " + p.getName()); 39334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 39434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 39534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 39634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 39734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root testCertPathEncoding(cf, certs, null); 39834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 39934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root /* Make sure all encoding entries are the same. */ 40034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root final Iterator<String> it1 = cf.getCertPathEncodings(); 40134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root final Iterator<String> it2 = cf.generateCertPath(certs).getEncodings(); 40234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root for (;;) { 40334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertEquals(p.getName(), it1.hasNext(), it2.hasNext()); 40434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root if (!it1.hasNext()) { 40534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root break; 40634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 40734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 40834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root String encoding = it1.next(); 40934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertEquals(p.getName(), encoding, it2.next()); 41034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 41134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root try { 41234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root it1.remove(); 41334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root fail("Should not be able to remove from iterator"); 41434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } catch (UnsupportedOperationException expected) { 41534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 41634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 41734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root try { 41834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root it2.remove(); 41934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root fail("Should not be able to remove from iterator"); 42034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } catch (UnsupportedOperationException expected) { 42134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 42234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 42334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root /* Now test using this encoding. */ 42434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root testCertPathEncoding(cf, certs, encoding); 42534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 42634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 42734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 42834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 42934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root private void testCertPathEncoding(CertificateFactory cf, List<X509Certificate> expectedCerts, 43034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root String encoding) throws Exception { 43134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root final String providerName = cf.getProvider().getName() + "[" + encoding + "]"; 43234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 43334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root final CertPath pathFromList = cf.generateCertPath(expectedCerts); 43434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 43534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root // Create a copy we can modify and discard. 43634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root final byte[] encodedCopy; 43734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root if (encoding == null) { 43834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root encodedCopy = pathFromList.getEncoded(); 43934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertNotNull(providerName, encodedCopy); 44034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 44134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root // check idempotence 44234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertEquals(providerName, Arrays.toString(pathFromList.getEncoded()), 44334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root Arrays.toString(encodedCopy)); 44434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } else { 44534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root encodedCopy = pathFromList.getEncoded(encoding); 44634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertNotNull(providerName, encodedCopy); 44734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 44834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root // check idempotence 44934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertEquals(providerName, Arrays.toString(pathFromList.getEncoded(encoding)), 45034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root Arrays.toString(encodedCopy)); 45134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 45234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 45334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root // Try to modify byte array. 45434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root encodedCopy[0] ^= (byte) 0xFF; 45534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 45634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root // Get a real copy we will use if the test proceeds. 45734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root final byte[] encoded; 45834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root if (encoding == null) { 45934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root encoded = pathFromList.getEncoded(); 46034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertNotNull(providerName, encodedCopy); 46134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 46234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root // check idempotence 46334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertEquals(providerName, Arrays.toString(pathFromList.getEncoded()), 46434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root Arrays.toString(encoded)); 46534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } else { 46634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root encoded = pathFromList.getEncoded(encoding); 46734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertNotNull(providerName, encodedCopy); 46834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 46934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root // check idempotence 47034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertEquals(providerName, Arrays.toString(pathFromList.getEncoded(encoding)), 47134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root Arrays.toString(encoded)); 47234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 47334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertFalse(providerName, Arrays.toString(encoded).equals(Arrays.toString(encodedCopy))); 47434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 47534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root encodedCopy[0] ^= (byte) 0xFF; 47634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertEquals(providerName, Arrays.toString(encoded), Arrays.toString(encodedCopy)); 47734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 47834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root final CertPath actualPath; 47934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root if (encoding == null) { 48034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root actualPath = cf.generateCertPath(new ByteArrayInputStream(encoded)); 48134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } else { 48234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root actualPath = cf.generateCertPath(new ByteArrayInputStream(encoded), encoding); 48334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 48434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 48534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root // PKCS7 certificate bags are not guaranteed to be in order. 48634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root final List<? extends Certificate> actualCerts; 48734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root if (!"PKCS7".equals(encoding)) { 48834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root actualCerts = actualPath.getCertificates(); 48934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertEquals(providerName, expectedCerts, actualCerts); 49034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } else { 49134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root actualCerts = pathFromList.getCertificates(); 49234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 49334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 49434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root try { 49534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root actualCerts.remove(0); 49634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root fail("List of certificate should be immutable"); 49734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } catch (UnsupportedOperationException expected) { 49834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 49934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 50034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root ByteArrayOutputStream baos = new ByteArrayOutputStream(); 50134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root ObjectOutputStream oos = new ObjectOutputStream(baos); 50234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root oos.writeObject(actualPath); 50334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root oos.close(); 50434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 50534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root byte[] serialized = baos.toByteArray(); 50634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root ByteArrayInputStream bais = new ByteArrayInputStream(serialized); 50734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root ObjectInputStream ois = new ObjectInputStream(bais); 50834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root Object output = ois.readObject(); 50934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertTrue(providerName, output instanceof CertPath); 51034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 51134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root assertEquals(providerName, actualPath, (CertPath) output); 51234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 51334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 51434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root public static class KeyHolder { 51534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root public X509Certificate certificate; 51634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 51734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root public PrivateKey privateKey; 51834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 51934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 52034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root @SuppressWarnings("deprecation") 52134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root private static KeyHolder generateCertificate(boolean isCa, KeyHolder issuer) throws Exception { 52234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root Date startDate = new Date(); 52334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 52434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root GregorianCalendar cal = new GregorianCalendar(); 52534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root cal.setTimeZone(TimeZone.getTimeZone("UTC")); 52634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root cal.set(2100, 0, 1, 0, 0, 0); // Jan 1, 2100 UTC 52734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root Date expiryDate = cal.getTime(); 52834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 52934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 53034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root KeyPair keyPair = kpg.generateKeyPair(); 53134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 53234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root BigInteger serial; 53334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root X500Principal issuerPrincipal; 53434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root X500Principal subjectPrincipal; 53534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root PrivateKey caKey; 53634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root if (issuer != null) { 53734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root serial = issuer.certificate.getSerialNumber().add(BigInteger.ONE); 53834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root subjectPrincipal = new X500Principal("CN=Test Certificate Serial #" + serial.toString()); 53934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root issuerPrincipal = issuer.certificate.getSubjectX500Principal(); 54034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root caKey = issuer.privateKey; 54134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } else { 54234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root serial = BigInteger.ONE; 54334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root subjectPrincipal = new X500Principal("CN=Test CA, O=Tests, C=US"); 54434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root issuerPrincipal = subjectPrincipal; 54534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root caKey = keyPair.getPrivate(); 54634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 54734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 54834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root BasicConstraints basicConstraints; 54934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root if (isCa) { 55034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root basicConstraints = new BasicConstraints(10 - serial.intValue()); 55134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } else { 55234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root basicConstraints = new BasicConstraints(false); 55334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 55434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 55534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); 55634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 55734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certGen.setSerialNumber(serial); 55834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certGen.setIssuerDN(issuerPrincipal); 55934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certGen.setNotBefore(startDate); 56034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certGen.setNotAfter(expiryDate); 56134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certGen.setSubjectDN(subjectPrincipal); 56234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certGen.setPublicKey(keyPair.getPublic()); 56334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certGen.setSignatureAlgorithm("SHA1withRSA"); 56434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 56534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root if (issuer != null) { 56634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, 56734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root new AuthorityKeyIdentifierStructure(issuer.certificate)); 56834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } else { 56934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, 57034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root new AuthorityKeyIdentifierStructure(keyPair.getPublic())); 57134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 57234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 57334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, 57434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root new SubjectKeyIdentifierStructure(keyPair.getPublic())); 57534acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root certGen.addExtension(X509Extensions.BasicConstraints, true, basicConstraints); 57634acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 57734acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root X509Certificate cert = certGen.generate(caKey); 57834acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 57934acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root KeyHolder holder = new KeyHolder(); 58034acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root holder.certificate = cert; 58134acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root holder.privateKey = keyPair.getPrivate(); 58234acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root 58334acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root return holder; 58434acecb989e8cecfe10027d3a2c6e6b8a54d970fKenny Root } 585cdeb809350d8c1a14a96924bf01febfa82a8b5b6Brian Carlstrom} 586