package com.philisense.www.xml;

import org.apache.commons.codec.binary.*;
import java.io.*;
import java.security.*;
import java.beans.*;

public final class GenericCertificate implements Serializable, XMLConstants
{
    private static final long serialVersionUID = 6247620498526484734L;
    private static final String BASE64_CHARSET = "US-ASCII";
    private static final String SIGNATURE_ENCODING = "US-ASCII/Base64";
    private transient volatile boolean locked;
    private String encoded;
    private String signature;
    private String signatureAlgorithm;
    private String signatureEncoding;
    private transient PropertyChangeSupport propertyChangeSupport;
    private transient VetoableChangeSupport vetoableChangeSupport;
    
    public GenericCertificate() {
    }
    
    public GenericCertificate(final GenericCertificate genericCertificate) {
        try {
            this.setEncoded(genericCertificate.getEncoded());
            this.setSignature(genericCertificate.getSignature());
            this.setSignatureAlgorithm(genericCertificate.getSignatureAlgorithm());
            this.setSignatureEncoding(genericCertificate.getSignatureEncoding());
        }
        catch (PropertyVetoException ex) {
            throw new AssertionError((Object)ex);
        }
    }
    
    public synchronized void sign(final Object o, final PrivateKey privateKey, final Signature signature) throws NullPointerException, GenericCertificateIsLockedException, PropertyVetoException, PersistenceServiceException, InvalidKeyException {
        final PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this, "locked", this.locked, Boolean.TRUE);
        if (this.locked) {
            throw new GenericCertificateIsLockedException(propertyChangeEvent);
        }
        if (null == privateKey || null == signature) {
            throw new NullPointerException();
        }
        this.fireVetoableChange(propertyChangeEvent);
        try {
            final byte[] store2ByteArray = PersistenceService.store2ByteArray(o);
            final String encoded = new String(store2ByteArray, "UTF-8");
            signature.initSign(privateKey);
            signature.update(store2ByteArray);
            final String signature2 = new String(Base64.encodeBase64(signature.sign()), "US-ASCII");
            final String algorithm = signature.getAlgorithm();
            this.setEncoded(encoded);
            this.setSignature(signature2);
            this.setSignatureAlgorithm(algorithm);
            this.setSignatureEncoding("US-ASCII/Base64");
        }
        catch (UnsupportedEncodingException ex) {
            throw new AssertionError((Object)ex);
        }
        catch (SignatureException ex2) {
            throw new AssertionError((Object)ex2);
        }
        this.locked = true;
        this.firePropertyChange(propertyChangeEvent);
    }
    
    public synchronized void verify(final PublicKey publicKey, final Signature signature) throws NullPointerException, GenericCertificateIsLockedException, PropertyVetoException, InvalidKeyException, SignatureException, GenericCertificateIntegrityException {
        final PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this, "locked", this.locked, Boolean.TRUE);
        if (this.locked) {
            throw new GenericCertificateIsLockedException(propertyChangeEvent);
        }
        if (null == publicKey || null == signature) {
            throw new NullPointerException();
        }
        this.fireVetoableChange(propertyChangeEvent);
        try {
            final byte[] bytes = this.encoded.getBytes("UTF-8");
            signature.initVerify(publicKey);
            signature.update(bytes);
            if (!signature.verify(Base64.decodeBase64(this.signature.getBytes("US-ASCII")))) {
                throw new GenericCertificateIntegrityException();
            }
            this.setSignatureAlgorithm(signature.getAlgorithm());
            this.setSignatureEncoding("US-ASCII/Base64");
        }
        catch (UnsupportedEncodingException ex) {
            throw new AssertionError((Object)ex);
        }
        this.locked = true;
        this.firePropertyChange(propertyChangeEvent);
    }
    
    public boolean isLocked() {
        return this.locked;
    }
    
    public synchronized Object getContent() throws GenericCertificateNotLockedException, PersistenceServiceException {
        if (!this.locked) {
            throw new GenericCertificateNotLockedException();
        }
        return PersistenceService.load(this.encoded);
    }
    
    public synchronized String getEncoded() {
        return this.encoded;
    }
    
    public synchronized void setEncoded(final String encoded) throws GenericCertificateIsLockedException {
        final PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this, "encoded", this.encoded, encoded);
        if (this.locked) {
            throw new GenericCertificateIsLockedException(propertyChangeEvent);
        }
        if (equals(this.encoded, encoded)) {
            return;
        }
        this.encoded = encoded;
        this.firePropertyChange(propertyChangeEvent);
    }
    
    public synchronized String getSignature() {
        return this.signature;
    }
    
    public synchronized void setSignature(final String signature) throws GenericCertificateIsLockedException {
        final PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this, "signature", this.signature, signature);
        if (this.locked) {
            throw new GenericCertificateIsLockedException(propertyChangeEvent);
        }
        if (equals(this.signature, signature)) {
            return;
        }
        this.signature = signature;
        this.firePropertyChange(propertyChangeEvent);
    }
    
    public synchronized String getSignatureAlgorithm() {
        return this.signatureAlgorithm;
    }
    
    public synchronized void setSignatureAlgorithm(final String signatureAlgorithm) throws GenericCertificateIsLockedException {
        final PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this, "signatureAlgorithm", this.signatureAlgorithm, signatureAlgorithm);
        if (this.locked) {
            throw new GenericCertificateIsLockedException(propertyChangeEvent);
        }
        if (equals(this.signatureAlgorithm, signatureAlgorithm)) {
            return;
        }
        this.signatureAlgorithm = signatureAlgorithm;
        this.firePropertyChange(propertyChangeEvent);
    }
    
    public synchronized String getSignatureEncoding() {
        return this.signatureEncoding;
    }
    
    public synchronized void setSignatureEncoding(final String signatureEncoding) throws GenericCertificateIsLockedException {
        final PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this, "signatureEncoding", this.signatureEncoding, signatureEncoding);
        if (this.locked) {
            throw new GenericCertificateIsLockedException(propertyChangeEvent);
        }
        if (equals(this.signatureEncoding, signatureEncoding)) {
            return;
        }
        this.signatureEncoding = signatureEncoding;
        this.firePropertyChange(propertyChangeEvent);
    }
    
    private static boolean equals(final Object o, final Object o2) {
        return o == o2 || (null != o && o.equals(o2));
    }
    
    public synchronized void addVetoableChangeListener(final VetoableChangeListener vetoableChangeListener) {
        if (null == this.vetoableChangeSupport) {
            this.vetoableChangeSupport = new VetoableChangeSupport(this);
        }
        this.vetoableChangeSupport.addVetoableChangeListener(vetoableChangeListener);
    }
    
    public synchronized void removeVetoableChangeListener(final VetoableChangeListener vetoableChangeListener) {
        if (null == this.vetoableChangeSupport) {
            return;
        }
        this.vetoableChangeSupport.removeVetoableChangeListener(vetoableChangeListener);
    }
    
    private void fireVetoableChange(final PropertyChangeEvent propertyChangeEvent) throws PropertyVetoException {
        if (null == this.vetoableChangeSupport) {
            return;
        }
        this.vetoableChangeSupport.fireVetoableChange(propertyChangeEvent);
    }
    
    public synchronized void addPropertyChangeListener(final PropertyChangeListener propertyChangeListener) {
        if (null == this.propertyChangeSupport) {
            this.propertyChangeSupport = new PropertyChangeSupport(this);
        }
        this.propertyChangeSupport.addPropertyChangeListener(propertyChangeListener);
    }
    
    public synchronized void removePropertyChangeListener(final PropertyChangeListener propertyChangeListener) {
        if (null == this.propertyChangeSupport) {
            return;
        }
        this.propertyChangeSupport.removePropertyChangeListener(propertyChangeListener);
    }
    
    private void firePropertyChange(final PropertyChangeEvent propertyChangeEvent) {
        if (null == this.propertyChangeSupport) {
            return;
        }
        this.propertyChangeSupport.firePropertyChange(propertyChangeEvent);
    }
}
