package com.philisense.www.license;

import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;

import com.philisense.www.utils.*;
import com.philisense.www.xml.*;


import java.io.*;

public class LicenseNotary
{
    private static final int BUFSIZE = 5120;
    static final String PARAM;
    private static final String ALIAS;
    private static final String EXC_NO_KEY_PWD;
    private static final String EXC_NO_KEY_ENTRY;
    private static final String EXC_PRIVATE_KEY_OR_PWD_IS_NOT_ALLOWED;
    private static final String EXC_NO_CERTIFICATE_ENTRY;
    private static final String SHA1_WITH_DSA;
    private static final String JKS;
    private KeyStoreParam param;
    private KeyStore keyStore;
    private PrivateKey privateKey;
    private PublicKey publicKey;
    
    protected LicenseNotary() {
    }
    
    public LicenseNotary(final KeyStoreParam keyStoreParam0) {
        this.setKeyStoreParam0(keyStoreParam0);
    }
    
    public KeyStoreParam getKeyStoreParam() {
        return this.param;
    }
    
    public void setKeyStoreParam(final KeyStoreParam keyStoreParam0) {
        this.setKeyStoreParam0(keyStoreParam0);
    }
    
    private void setKeyStoreParam0(final KeyStoreParam param) {
        if (null == param.getAlias()) {
            throw new NullPointerException(LicenseNotary.ALIAS);
        }
        final Policy current = Policy.getCurrent();
        current.checkPwd(param.getStorePwd());
        final String keyPwd = param.getKeyPwd();
        if (null != keyPwd) {
            current.checkPwd(keyPwd);
        }
        this.param = param;
        this.keyStore = null;
        this.privateKey = null;
        this.publicKey = null;
    }
    
    public GenericCertificate sign(final Object o) throws Exception {
        final GenericCertificate genericCertificate = new GenericCertificate();
        this.sign(genericCertificate, o);
        return genericCertificate;
    }
    
    void sign(final GenericCertificate genericCertificate, final Object o) throws Exception {
        genericCertificate.sign(o, this.getPrivateKey(), this.getSignatureEngine());
    }
    
    public void verify(final GenericCertificate genericCertificate) throws Exception {
        genericCertificate.verify(this.getPublicKey(), this.getSignatureEngine());
    }
    
    protected PrivateKey getPrivateKey() throws LicenseNotaryException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
        if (null == this.privateKey) {
            final KeyStoreParam keyStoreParam = this.getKeyStoreParam();
            final String keyPwd = keyStoreParam.getKeyPwd();
            final String alias = keyStoreParam.getAlias();
            if (null == keyPwd) {
                throw new LicenseNotaryException(LicenseNotary.EXC_NO_KEY_PWD, alias);
            }
            final KeyStore keyStore = this.getKeyStore();
            try {
                this.privateKey = (PrivateKey)keyStore.getKey(alias, keyPwd.toCharArray());
            }
            catch (KeyStoreException ex) {
                throw new AssertionError((Object)ex);
            }
            if (null == this.privateKey) {
                throw new LicenseNotaryException(LicenseNotary.EXC_NO_KEY_ENTRY, alias);
            }
        }
        return this.privateKey;
    }
    
    protected PublicKey getPublicKey() throws LicenseNotaryException, IOException, CertificateException, NoSuchAlgorithmException {
        if (null == this.publicKey) {
            final String alias = this.getKeyStoreParam().getAlias();
            final KeyStore keyStore = this.getKeyStore();
            try {
                if (null != this.getKeyStoreParam().getKeyPwd() != keyStore.isKeyEntry(alias)) {
                    throw new LicenseNotaryException(LicenseNotary.EXC_PRIVATE_KEY_OR_PWD_IS_NOT_ALLOWED, alias);
                }
                final Certificate certificate = keyStore.getCertificate(alias);
                if (null == certificate) {
                    throw new LicenseNotaryException(LicenseNotary.EXC_NO_CERTIFICATE_ENTRY, alias);
                }
                this.publicKey = certificate.getPublicKey();
            }
            catch (KeyStoreException ex) {
                throw new AssertionError((Object)ex);
            }
        }
        return this.publicKey;
    }
    
    protected Signature getSignatureEngine() {
        try {
            return Signature.getInstance(LicenseNotary.SHA1_WITH_DSA);
        }
        catch (NoSuchAlgorithmException ex) {
            throw new AssertionError((Object)ex);
        }
    }
    
    protected KeyStore getKeyStore() throws IOException, CertificateException, NoSuchAlgorithmException {
        if (null != this.keyStore) {
            return this.keyStore;
        }
        InputStream inputStream = null;
        try {
            this.keyStore = KeyStore.getInstance(LicenseNotary.JKS);
            inputStream = new BufferedInputStream(this.param.getStream(), 5120);
            this.keyStore.load(inputStream, this.getKeyStoreParam().getStorePwd().toCharArray());
        }
        catch (KeyStoreException ex) {
            throw new AssertionError((Object)ex);
        }
        finally {
            if (null != inputStream) {
                inputStream.close();
            }
        }
        return this.keyStore;
    }
    
    static {
        PARAM = new ObfuscatedString(new long[] { 668274362144012114L, -2115765889337599212L }).toString();
        ALIAS = new ObfuscatedString(new long[] { 1112708769776922148L, 6703392504509681290L }).toString();
        EXC_NO_KEY_PWD = new ObfuscatedString(new long[] { -7210613020960449599L, 222075784786550139L, 9025728610804768010L }).toString();
        EXC_NO_KEY_ENTRY = new ObfuscatedString(new long[] { -1386002024146642540L, 4133952825992554401L, -8020387964636761861L }).toString();
        EXC_PRIVATE_KEY_OR_PWD_IS_NOT_ALLOWED = new ObfuscatedString(new long[] { -2960555953270849419L, 3827258740935670554L, -3005417608224527600L, 1939660993088349256L, 4750831951568910874L }).toString();
        EXC_NO_CERTIFICATE_ENTRY = new ObfuscatedString(new long[] { -3872127676557769698L, -2469202953083814859L, 6713970776812571709L, -482260351456063412L }).toString();
        SHA1_WITH_DSA = new ObfuscatedString(new long[] { -1509550478491572167L, 1688274905166048601L, -4620167493569680976L }).toString();
        JKS = new ObfuscatedString(new long[] { -6234396975553918200L, 2370155821952859770L }).toString();
    }
}
