/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF 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.
 */

/**
 * @author Alexander Y. Kleymenov
 * @version $Revision$
 */

package tests.api.javax.security.cert;

import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import tests.targets.security.cert.CertificateFactoryTestX509;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Security;
import java.security.SignatureException;
import java.security.Provider.Service;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Set;
import java.util.logging.Logger;

import javax.security.cert.Certificate;
import javax.security.cert.CertificateEncodingException;
import javax.security.cert.CertificateException;
import javax.security.cert.CertificateExpiredException;
import javax.security.cert.CertificateNotYetValidException;
import javax.security.cert.X509Certificate;

/**
 */
@TestTargetClass(X509Certificate.class)
public class X509CertificateTest extends TestCase {

    // Testing data was generated by using of classes
    // from org.apache.harmony.security.asn1 package encoded
    // by org.apache.harmony.misc.Base64 class.

    private static String base64cert = "-----BEGIN CERTIFICATE-----\n"
            + "MIIC+jCCAragAwIBAgICAiswDAYHKoZIzjgEAwEBADAdMRswGQYDVQQKExJDZXJ0a"
            + "WZpY2F0ZSBJc3N1ZXIwIhgPMTk3MDAxMTIxMzQ2NDBaGA8xOTcwMDEyNDAzMzMyMF"
            + "owHzEdMBsGA1UEChMUU3ViamVjdCBPcmdhbml6YXRpb24wGTAMBgcqhkjOOAQDAQE"
            + "AAwkAAQIDBAUGBwiBAgCqggIAVaOCAhQwggIQMA8GA1UdDwEB/wQFAwMBqoAwEgYD"
            + "VR0TAQH/BAgwBgEB/wIBBTAUBgNVHSABAf8ECjAIMAYGBFUdIAAwZwYDVR0RAQH/B"
            + "F0wW4EMcmZjQDgyMi5OYW1lggdkTlNOYW1lpBcxFTATBgNVBAoTDE9yZ2FuaXphdG"
            + "lvboYaaHR0cDovL3VuaWZvcm0uUmVzb3VyY2UuSWSHBP///wCIByoDolyDsgMwDAY"
            + "DVR0eAQH/BAIwADAMBgNVHSQBAf8EAjAAMIGZBgNVHSUBAf8EgY4wgYsGBFUdJQAG"
            + "CCsGAQUFBwMBBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDB"
            + "AYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUFBw"
            + "MJBggrBgEFBQgCAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GA1UdNgEB/wQDAgE"
            + "BMA4GBCpNhgkBAf8EAwEBATBkBgNVHRIEXTBbgQxyZmNAODIyLk5hbWWCB2ROU05h"
            + "bWWkFzEVMBMGA1UEChMMT3JnYW5pemF0aW9uhhpodHRwOi8vdW5pZm9ybS5SZXNvd"
            + "XJjZS5JZIcE////AIgHKgOiXIOyAzAJBgNVHR8EAjAAMAoGA1UdIwQDAQEBMAoGA1"
            + "UdDgQDAQEBMAoGA1UdIQQDAQEBMAwGByqGSM44BAMBAQADMAAwLQIUAL4QvoazNWP"
            + "7jrj84/GZlhm09DsCFQCBKGKCGbrP64VtUt4JPmLjW1VxQA==\n"
            + "-----END CERTIFICATE-----";
   
   /**
    * Copy of CertPathValidatorTestPKIX.selfSignedCert
    */
   private static final String selfSignedCert = "-----BEGIN CERTIFICATE-----\n"
        + "MIICSDCCAbECBEk2ZvswDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCQU4xEDAOBgNVBAgTB0Fu\n"
        + "ZHJvaWQxEDAOBgNVBAcTB0FuZHJvaWQxEDAOBgNVBAoTB0FuZHJvaWQxEDAOBgNVBAsTB0FuZHJv\n"
        + "aWQxFDASBgNVBAMTC0FuZHJvaWQgQ1RTMB4XDTA4MTIwMzExMDExNVoXDTM2MDQyMDExMDExNVow\n"
        + "azELMAkGA1UEBhMCQU4xEDAOBgNVBAgTB0FuZHJvaWQxEDAOBgNVBAcTB0FuZHJvaWQxEDAOBgNV\n"
        + "BAoTB0FuZHJvaWQxEDAOBgNVBAsTB0FuZHJvaWQxFDASBgNVBAMTC0FuZHJvaWQgQ1RTMIGfMA0G\n"
        + "CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAMd+N1Bu2eiI4kukOLvFlpTSEHTGplN2vvw76T7jSZinx\n"
        + "WcrtLe6qH1uPffbVNW4/BRn6OywbcynazEdqEUa09hWtHYmUsXpRPyGUBScNnyF751SGA2JIQUfg\n"
        + "3gi3gT3h32Z64AIHnn5gsGDJkeWOHx6/uVOV7iqr7cwPdLp03QIDAQABMA0GCSqGSIb3DQEBBAUA\n"
        + "A4GBAGG46Udsh6U7bSkJsyPPmSCCEkGr14L8F431UuaWbLvQVDtyPv8vtdJilyUTVnlWM6JNGV/q\n"
        + "bgHuLbohkVXn9l68GtgQ7QDexHJE5hEDG/S7cYNi9GhrCfzAjEed13VMntZHZ0XQ4E7jBOmhcMAY\n"
        + "DC9BBx1sVKoji17RP4R8CTf1\n" + "-----END CERTIFICATE-----";

    private java.security.cert.X509Certificate cert;

    private javax.security.cert.X509Certificate tbt_cert;
    
    private java.security.cert.X509Certificate javaCert;
    
    private Provider myProvider;

    private javax.security.cert.X509Certificate javaxCert;

    private java.security.cert.Certificate javaSSCert;

    private Provider mySSProvider;

    private Certificate javaxSSCert;

    protected void setUp() throws Exception {
        try {
            ByteArrayInputStream bais = new ByteArrayInputStream(base64cert
                    .getBytes());
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            this.cert = (java.security.cert.X509Certificate) cf
                    .generateCertificate(bais);
            this.tbt_cert = X509Certificate.getInstance(cert.getEncoded());

            // non self signed cert
            this.javaCert = (java.security.cert.X509Certificate) cf
                    .generateCertificate(new ByteArrayInputStream(
                            CertificateFactoryTestX509.encodedCertificate
                                    .getBytes()));
            this.javaxCert = X509Certificate.getInstance(javaCert.getEncoded());
            myProvider = cf.getProvider();
            Security.addProvider(myProvider);

            // self signed cert
            this.javaSSCert = cf.generateCertificate(new ByteArrayInputStream(
                    selfSignedCert.getBytes()));
            this.javaxSSCert = X509Certificate.getInstance(javaCert
                    .getEncoded());
            mySSProvider = cf.getProvider();
            Security.addProvider(mySSProvider);

        } catch (java.security.cert.CertificateException e) {
            // The requested certificate type is not available.
            // Test pass..
            this.cert = null;
            Logger.global.warning("Error in test setup: Certificate type not supported");
        } catch (javax.security.cert.CertificateException e) {
            // The requested certificate type is not available.
            // Test pass..
            this.cert = null;
            Logger.global.warning("Error in test setup: Certificate type not supported");
        }
    }

    /**
     * X509Certificate() constructor testing.
     * @tests {@link X509Certificate#X509Certificate() }
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "X509Certificate",
        args = {}
    )
    public void testConstructor() {
        //Direct constructor, check if it throws an exception
        X509Certificate cert = new MyCertificate();
    }

    /**
     * getInstance(InputStream inStream) method testing.
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getInstance",
        args = {java.io.InputStream.class}
    )
    public void testGetInstance1() {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        try {
            ByteArrayInputStream bais = new ByteArrayInputStream(cert
                    .getEncoded());

            X509Certificate.getInstance(bais);
        } catch (java.security.cert.CertificateEncodingException e) {
            fail("Unexpected CertificateEncodingException was thrown.");
        } catch (CertificateEncodingException e) {
            fail("Unexpected CertificateEncodingException was thrown.");
        } catch (CertificateException e) {
            // The requested certificate type is not available.
            // Test pass..
        }

        // Regression for HARMONY-756
        try {
            X509Certificate.getInstance((InputStream) null);
            fail("No expected CertificateException");
        } catch (CertificateException e) {
            // expected;
        }
    }

    /**
     * getInstance(byte[] certData) method testing.
     * @throws CertificateEncodingException 
     * @throws java.security.cert.CertificateEncodingException 
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Verifies CertificateException.",
        method = "getInstance",
        args = {byte[].class}
    )
    public void testGetInstance2() throws java.security.cert.CertificateEncodingException, CertificateEncodingException {
        boolean certificateException = false;
        X509Certificate c = null;
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        try {
            c = X509Certificate.getInstance(cert.getEncoded());
        } catch (java.security.cert.CertificateEncodingException e) {
            fail("Unexpected CertificateEncodingException was thrown.");
        } catch (CertificateException e) {
            // The requested certificate type is not available.
            // Test pass..
            certificateException = true;
            
        }
        
        if (! certificateException) {
            assertNotNull(c);
            assertTrue(Arrays.equals(c.getEncoded(),cert.getEncoded() ));
        }
        
        try {
            X509Certificate.getInstance(new byte[]{(byte) 1 });
        } catch (CertificateException e) {
            //ok
        }

        // Regression for HARMONY-756
        try {
            X509Certificate.getInstance((byte[]) null);
            fail("No expected CertificateException");
        } catch (CertificateException e) {
            // expected;
        }
        
    }

    /**
     * checkValidity() method testing.
     * @throws CertificateNotYetValidException 
     * @throws CertificateExpiredException 
     * @throws java.security.cert.CertificateExpiredException 
     * @throws java.security.cert.CertificateNotYetValidException 
     */
    @TestTargetNew(
        level = TestLevel.SUFFICIENT,
        notes = "Doesn't verify exceptions.",
        method = "checkValidity",
        args = {}
    )
    public void testCheckValidity1() throws CertificateExpiredException, CertificateNotYetValidException, java.security.cert.CertificateExpiredException, java.security.cert.CertificateNotYetValidException {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        Date date = new Date();
        Date nb_date = tbt_cert.getNotBefore();
        Date na_date = tbt_cert.getNotAfter();
        try {
            tbt_cert.checkValidity();
            assertFalse("CertificateExpiredException expected", date
                    .compareTo(na_date) > 0);
            assertFalse("CertificateNotYetValidException expected", date
                    .compareTo(nb_date) < 0);
        } catch (CertificateExpiredException e) {
            assertTrue("Unexpected CertificateExpiredException was thrown",
                    date.compareTo(na_date) > 0);
        } catch (CertificateNotYetValidException e) {
            assertTrue("Unexpected CertificateNotYetValidException was thrown",
                    date.compareTo(nb_date) < 0);
        }
       
       try {
       tbt_cert.checkValidity();
       } catch (CertificateExpiredException e) {
        // ok
       }
       
       try {
            cert.checkValidity();
        } catch (java.security.cert.CertificateExpiredException e) {
            // ok
        } 
       
    }

    /**
     * checkValidity(Date date) method testing.
     * @throws CertificateNotYetValidException 
     * @throws CertificateExpiredException 
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Doesn't verify exceptions.",
        method = "checkValidity",
        args = {java.util.Date.class}
    )
    public void testCheckValidity2() throws CertificateNotYetValidException, CertificateExpiredException {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        Date[] date = new Date[4];
        Calendar calendar = Calendar.getInstance();
        for (int i = 0; i < date.length; i++) {
            calendar.set(i * 50, Calendar.JANUARY, 1);
            date[i] = calendar.getTime();
        }
        Date nb_date = tbt_cert.getNotBefore();
        Date na_date = tbt_cert.getNotAfter();
        for (int i = 0; i < date.length; i++) {
            try {
                tbt_cert.checkValidity(date[i]);
                assertFalse("CertificateExpiredException expected", date[i]
                        .compareTo(na_date) > 0);
                assertFalse("CertificateNotYetValidException expected", date[i]
                        .compareTo(nb_date) < 0);
            } catch (CertificateExpiredException e) {
                assertTrue("Unexpected CertificateExpiredException was thrown",
                        date[i].compareTo(na_date) > 0);
            } catch (CertificateNotYetValidException e) {
                assertTrue("Unexpected CertificateNotYetValidException "
                        + "was thrown", date[i].compareTo(nb_date) < 0);
            }
        }
        
        Calendar calendarNow = Calendar.getInstance();
        
        try {
            tbt_cert.checkValidity(calendarNow.getTime());
        } catch (CertificateExpiredException e) {
            //ok
        }
        
        Calendar calendarPast = GregorianCalendar.getInstance();
        calendarPast.clear();
        
        try {
            tbt_cert.checkValidity(calendarPast.getTime());
        } catch (CertificateNotYetValidException e) {
            //ok
        }
        
    }

    /**
     * getVersion() method testing.
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getVersion",
        args = {}
    )
    public void testGetVersion() {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        assertEquals("The version is not correct.", tbt_cert.getVersion(), 2);
    }

    /**
     * getSerialNumber() method testing.
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getSerialNumber",
        args = {}
    )
    public void testGetSerialNumber() {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        assertEquals("The serial number is not correct.", tbt_cert
                .getSerialNumber(), cert.getSerialNumber());
    }

    /**
     * getIssuerDN() method testing.
     */
    @TestTargetNew(
        level = TestLevel.SUFFICIENT,
        notes = "Denigrated API",
        method = "getIssuerDN",
        args = {}
    )
    public void testGetIssuerDN() {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            Logger.global.warning("testGetIssuerDN: error in test setup.");
        }
        assertEquals("The issuer DN is not correct.", tbt_cert.getIssuerDN(),
                cert.getIssuerDN());
    }

    /**
     * getSubjectDN() method testing.
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getSubjectDN",
        args = {}
    )
    public void testGetSubjectDN() {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        assertEquals("The subject DN is not correct.", tbt_cert.getSubjectDN(),
                cert.getSubjectDN());
    }

    /**
     * getNotBefore() method testing.
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getNotBefore",
        args = {}
    )
    public void testGetNotBefore() {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        assertEquals("The NotBefore date is not correct.", tbt_cert
                .getNotBefore(), cert.getNotBefore());
    }

    /**
     * getNotAfter() method testing.
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getNotAfter",
        args = {}
    )
    public void testGetNotAfter() {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        assertEquals("The NotAfter date is not correct.", tbt_cert
                .getNotAfter(), cert.getNotAfter());
    }

    /**
     * getSigAlgName() method testing.
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getSigAlgName",
        args = {}
    )
    public void testGetSigAlgName() {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        assertEquals("The name of signature algorithm is not correct.",
                tbt_cert.getSigAlgName(), cert.getSigAlgName());
    }

    /**
     * getSigAlgOID() method testing.
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getSigAlgOID",
        args = {}
    )
    public void testGetSigAlgOID() {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        assertEquals("The name of OID of signature algorithm is not correct.",
                tbt_cert.getSigAlgOID(), cert.getSigAlgOID());
    }

    /**
     * getSigAlgParams() method testing.
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getSigAlgParams",
        args = {}
    )
    public void testGetSigAlgParams() {
        if (this.cert == null) {
            // The requested certificate type is not available.
            // Test can not be applied.
            return;
        }
        assertTrue("The byte array with encoded algorithm parameters "
                + "is not correct.", Arrays.equals(tbt_cert.getSigAlgParams(),
                cert.getSigAlgParams()));
    }

    /**
     * The stub class used for testing of non abstract methods.
     */
    private class MyCertificate extends X509Certificate {

        public MyCertificate() {
            super();
        }
        
        @Override
        public void checkValidity() throws CertificateExpiredException,
                CertificateNotYetValidException {
        }

        @Override
        public void checkValidity(Date arg0)
                throws CertificateExpiredException,
                CertificateNotYetValidException {
        }

        @Override
        public Principal getIssuerDN() {
            return null;
        }

        @Override
        public Date getNotAfter() {
            return null;
        }

        @Override
        public Date getNotBefore() {
            return null;
        }

        @Override
        public BigInteger getSerialNumber() {
            return null;
        }

        @Override
        public String getSigAlgName() {
            return null;
        }

        @Override
        public String getSigAlgOID() {
            return null;
        }

        @Override
        public byte[] getSigAlgParams() {
            return null;
        }

        @Override
        public Principal getSubjectDN() {
            return null;
        }

        @Override
        public int getVersion() {
            return 0;
        }

        @Override
        public byte[] getEncoded() throws CertificateEncodingException {
            return null;
        }

        @Override
        public PublicKey getPublicKey() {
            return null;
        }

        @Override
        public String toString() {
            return null;
        }

        @Override
        public void verify(PublicKey key) throws CertificateException,
                NoSuchAlgorithmException, InvalidKeyException,
                NoSuchProviderException, SignatureException {
        }

        @Override
        public void verify(PublicKey key, String sigProvider)
                throws CertificateException, NoSuchAlgorithmException,
                InvalidKeyException, NoSuchProviderException,
                SignatureException {
        }
    }
    
    public class MyModifiablePublicKey implements PublicKey {
       
        private PublicKey key;
        private boolean modifiedAlgo;
        private String algo;
        private String format;
        private boolean modifiedFormat;
        private boolean modifiedEncoding;
        private byte[] encoding;
        
        public MyModifiablePublicKey(PublicKey k) {
            super();
            this.key = k;
        }

        public String getAlgorithm() {
            if (modifiedAlgo) {
                return algo;
            } else {
                return key.getAlgorithm();
            }
        }

        public String getFormat() {
            if (modifiedFormat) {
                return this.format;
            } else {
                return key.getFormat();
            }
            
        }

        public byte[] getEncoded() {
            if (modifiedEncoding) {
                return this.encoding;
            } else {
                return key.getEncoded();
            }
            
        }

        public long getSerVerUID() {
            return key.serialVersionUID;
        }
        
        public void setAlgorithm(String myAlgo) {
            modifiedAlgo = true;
            this.algo = myAlgo;
        }
        
        public void setFormat(String myFormat) {
            modifiedFormat = true;
            format = myFormat;
        }
        
        public void setEncoding(byte[] myEncoded) {
            modifiedEncoding = true;
            encoding = myEncoded;
        }
    }
    
    /**
     * @throws CertificateEncodingException 
     * @tests {@link Certificate#getEncoded()}
     */
    @TestTargetNew(
      level = TestLevel.SUFFICIENT,
      notes = "No ASN1/DER encoder available. Exception is not supported.",
      method = "getEncoded",
      args = {}
    )
    public void testGetEncoded()
            throws CertificateEncodingException, java.security.cert.CertificateException {
        // cert = DER encoding of the ASN1.0 structure
        assertTrue(Arrays.equals(cert.getEncoded(), tbt_cert.getEncoded()));
        assertFalse(Arrays.equals(javaxCert.getEncoded(), tbt_cert.getEncoded()));
    }
    
    /**
     * @tests {@link Certificate#getPublicKey()}
     */
    @TestTargetNew(
      level = TestLevel.COMPLETE,
      notes = "",
      method = "getPublicKey",
      args = {}
    )
    public void testGetPublicKey() {
       PublicKey key = javaxCert.getPublicKey();
       assertNotNull(key);
       assertEquals(javaxCert.getPublicKey(), javaCert.getPublicKey());
       assertEquals(key.getAlgorithm(),"RSA");
       
       key = javaxSSCert.getPublicKey();
       assertNotNull(key);
       assertFalse(javaxSSCert.getPublicKey().equals(javaSSCert.getPublicKey()));
       assertEquals(key.getAlgorithm(),"RSA");
       
       //assertTrue(mySSProvider.containsKey(key));

    }
    
    /**
     * @throws SignatureException 
     * @throws NoSuchProviderException 
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeyException 
     * @throws CertificateException 
     * @tests {@link Certificate#verify(PublicKey)}
     */
    @TestTargetNew(
      level = TestLevel.SUFFICIENT,
      notes = " CertificateException not supported."+
      	      "NoSuchAlgorithmException, NoSuchProviderException can be "+
      	      "implemented only with working Cert. Verification fails (see failing) "+
      	      "precondition assertions",
      method = "verify",
      args = {java.security.PublicKey.class}
    )
    public void testVerifyPublicKey() throws InvalidKeyException,
            NoSuchAlgorithmException, NoSuchProviderException,
            SignatureException, CertificateException {

        // Preconditions
        assertNotNull(javaxCert.getPublicKey());
        assertNotNull(javaxSSCert.getPublicKey());
        //precondition for self signed certificates
        /*assertEquals(((X509Certificate) javaxSSCert).getIssuerDN().getName(),
                ((X509Certificate) javaxSSCert).getSubjectDN());*/
        
        // must always evaluate true for self signed
        // here not self signed:
        try {
            javaxCert.verify(javaxCert.getPublicKey());
        } catch (SignatureException e) {
            // ok
        }

        PublicKey k = javaxCert.getPublicKey();

        MyModifiablePublicKey changedEncoding = new MyModifiablePublicKey(k);
        changedEncoding
                .setEncoding(new byte[javaxCert.getEncoded().length - 1]);

        try {
            javaxCert.verify(tbt_cert.getPublicKey());
        } catch (InvalidKeyException e) {
            // ok
        }


        try {
            javaxCert.verify(null);
        } catch (Exception e) {
            // ok
        }

        try {
            javaxCert.verify(changedEncoding);
            fail("Exception expected");
        } catch (Exception e) {
            // ok
        }
        
        // following test doesn't work because the algorithm is derived from
        // somewhere else.

        // MyModifiablePublicKey changedAlgo = new MyModifiablePublicKey(k);
        // changedAlgo.setAlgorithm("MD5withBla");

        // try {
        //     javaxCert.verify(changedAlgo);
        //     fail("Exception expected");
        // } catch (SignatureException e) {
        //     // ok
        // }
        
        // Security.removeProvider(mySSProvider.getName());

        // try {
        //     javaxSSCert.verify(javaxSSCert.getPublicKey());
        // } catch (NoSuchProviderException e) {
        //     // ok
        // }

        // Security.addProvider(mySSProvider);
        
        // must always evaluate true for self signed
        // javaxSSCert.verify(javaxSSCert.getPublicKey());
    }
    
    /**
     * @throws SignatureException 
     * @throws NoSuchProviderException 
     * @throws NoSuchAlgorithmException 
     * @throws java.security.cert.CertificateException 
     * @throws InvalidKeyException 
     * @throws IOException 
     * @throws CertificateException 
     * @tests {@link Certificate#verify(PublicKey, String)}
     */
    @TestTargetNew(
      level = TestLevel.SUFFICIENT,
      notes = "only exception testing: there is an error with the self signed "+
              "certificate. Should verify.",
      method = "verify",
      args = {java.security.PublicKey.class, java.lang.String.class}
    )
    @BrokenTest("there is an error with the self signed certificate")
    public void testVerifyPublicKeyString() throws InvalidKeyException,
            java.security.cert.CertificateException, NoSuchAlgorithmException,
            NoSuchProviderException, SignatureException, IOException,
            CertificateException {
        
        try {
            javaxCert.verify(javaxCert.getPublicKey(), myProvider.getName());
        } catch (NoSuchAlgorithmException e) {
            // ok
        }

        // myProvider.getService(type, algorithm)

        Security.removeProvider(myProvider.getName());
        try {
            javaxCert.verify(javaxCert.getPublicKey(), myProvider.getName());
        } catch (NoSuchProviderException e) {
            // ok
        }
        Security.addProvider(myProvider);
        
        
        // self signed cert: should verify with provider
        javaxSSCert.verify(javaxSSCert.getPublicKey(), mySSProvider.getName());

    }

    public static Test suite() {
        return new TestSuite(X509CertificateTest.class);
    }

    public static void main(String[] args) {
        junit.textui.TestRunner.run(suite());
    }
}
