// Path: src/main/java/org/kontalk/misc/KonException.java
// public final class KonException extends Exception {
// 
//     public enum Error {
//         DB,
//         IMPORT_ARCHIVE,
//         IMPORT_READ_FILE,
//         IMPORT_KEY,
//         CHANGE_PASS,
//         CHANGE_PASS_COPY,
//         WRITE_FILE,
//         READ_FILE,
//         LOAD_KEY,
//         LOAD_KEY_DECRYPT,
//         CLIENT_CONNECT,
//         CLIENT_LOGIN,
//         CLIENT_ERROR,
//         DOWNLOAD_CREATE,
//         DOWNLOAD_RESPONSE,
//         DOWNLOAD_EXECUTE,
//         DOWNLOAD_WRITE,
//         UPLOAD_CREATE,
//         UPLOAD_RESPONSE,
//         UPLOAD_EXECUTE,
//     }
// 
//     private final Error mError;
// 
//     public KonException(Error error, Exception ex) {
//         super(ex);
//         mError = error;
//     }
// 
//     public KonException(Error error) {
//         super();
//         mError = error;
//     }
// 
//     public Class<?> getCauseClass() {
//         Throwable cause = this.getCause();
//         return cause == null ? this.getClass() : cause.getClass();
//     }
// 
//     public Error getError() {
//         return mError;
//     }
// }


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.bc.BcPGPPublicKeyRing;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.util.encoders.Hex;
import org.kontalk.misc.KonException;
/*
 * Kontalk Java client
 * Copyright (C) 2016 Kontalk Devteam <devteam@kontalk.org>

 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.kontalk.crypto;


/**
 * Personal PGP key(s).
 */
public final class PersonalKey {
    private static final Logger LOGGER = Logger.getLogger(PersonalKey.class.getName());

    /** (Server) Authentication key. */
    private final PGPPublicKey mAuthKey;
    /** (Server) Login key. */
    private final PrivateKey mLoginKey;
    /** Signing key. */
    private final PGPKeyPair mSignKey;
    /** En-/decryption key. */
    private final PGPKeyPair mEncryptKey;
    /** X.509 bridge certificate. */
    private final X509Certificate mBridgeCert;
    /** Primary user ID. */
    private final String mUID;

    private PersonalKey(PGPKeyPair authKP,
            PGPKeyPair signKP,
            PGPKeyPair encryptKP,
            X509Certificate bridgeCert,
            String uid) throws PGPException {
        mAuthKey = authKP.getPublicKey();
        mLoginKey = PGPUtils.convertPrivateKey(authKP.getPrivateKey());
        mSignKey = signKP;
        mEncryptKey = encryptKP;
        mBridgeCert = bridgeCert;
        mUID = uid;
    }

    PGPPrivateKey getPrivateEncryptionKey() {
        return mEncryptKey.getPrivateKey();
    }

    PGPPrivateKey getPrivateSigningKey() {
        return mSignKey.getPrivateKey();
    }

    int getSigningAlgorithm() {
        return mSignKey.getPublicKey().getAlgorithm();
    }

    public X509Certificate getBridgeCertificate() {
        return mBridgeCert;
    }

    public PrivateKey getServerLoginKey() {
        return mLoginKey;
    }

    /** Returns the first user ID in the key. */
    public String getUserId() {
        return mUID;
    }

    public String getFingerprint() {
        return Hex.toHexString(mAuthKey.getFingerprint());
    }

    /** Creates a {@link PersonalKey} from private keyring data.
     * X.509 bridge certificate is created from key data.
     */
    public static PersonalKey load(byte[] privateKeyData,
            char[] passphrase)
// Path: src/main/java/org/kontalk/misc/KonException.java
// public final class KonException extends Exception {
// 
//     public enum Error {
//         DB,
//         IMPORT_ARCHIVE,
//         IMPORT_READ_FILE,
//         IMPORT_KEY,
//         CHANGE_PASS,
//         CHANGE_PASS_COPY,
//         WRITE_FILE,
//         READ_FILE,
//         LOAD_KEY,
//         LOAD_KEY_DECRYPT,
//         CLIENT_CONNECT,
//         CLIENT_LOGIN,
//         CLIENT_ERROR,
//         DOWNLOAD_CREATE,
//         DOWNLOAD_RESPONSE,
//         DOWNLOAD_EXECUTE,
//         DOWNLOAD_WRITE,
//         UPLOAD_CREATE,
//         UPLOAD_RESPONSE,
//         UPLOAD_EXECUTE,
//     }
// 
//     private final Error mError;
// 
//     public KonException(Error error, Exception ex) {
//         super(ex);
//         mError = error;
//     }
// 
//     public KonException(Error error) {
//         super();
//         mError = error;
//     }
// 
//     public Class<?> getCauseClass() {
//         Throwable cause = this.getCause();
//         return cause == null ? this.getClass() : cause.getClass();
//     }
// 
//     public Error getError() {
//         return mError;
//     }
// }


// Path: src/main/java/org/kontalk/crypto/PersonalKey.java
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.bc.BcPGPPublicKeyRing;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.util.encoders.Hex;
import org.kontalk.misc.KonException;

/*
 * Kontalk Java client
 * Copyright (C) 2016 Kontalk Devteam <devteam@kontalk.org>

 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.kontalk.crypto;


/**
 * Personal PGP key(s).
 */
public final class PersonalKey {
    private static final Logger LOGGER = Logger.getLogger(PersonalKey.class.getName());

    /** (Server) Authentication key. */
    private final PGPPublicKey mAuthKey;
    /** (Server) Login key. */
    private final PrivateKey mLoginKey;
    /** Signing key. */
    private final PGPKeyPair mSignKey;
    /** En-/decryption key. */
    private final PGPKeyPair mEncryptKey;
    /** X.509 bridge certificate. */
    private final X509Certificate mBridgeCert;
    /** Primary user ID. */
    private final String mUID;

    private PersonalKey(PGPKeyPair authKP,
            PGPKeyPair signKP,
            PGPKeyPair encryptKP,
            X509Certificate bridgeCert,
            String uid) throws PGPException {
        mAuthKey = authKP.getPublicKey();
        mLoginKey = PGPUtils.convertPrivateKey(authKP.getPrivateKey());
        mSignKey = signKP;
        mEncryptKey = encryptKP;
        mBridgeCert = bridgeCert;
        mUID = uid;
    }

    PGPPrivateKey getPrivateEncryptionKey() {
        return mEncryptKey.getPrivateKey();
    }

    PGPPrivateKey getPrivateSigningKey() {
        return mSignKey.getPrivateKey();
    }

    int getSigningAlgorithm() {
        return mSignKey.getPublicKey().getAlgorithm();
    }

    public X509Certificate getBridgeCertificate() {
        return mBridgeCert;
    }

    public PrivateKey getServerLoginKey() {
        return mLoginKey;
    }

    /** Returns the first user ID in the key. */
    public String getUserId() {
        return mUID;
    }

    public String getFingerprint() {
        return Hex.toHexString(mAuthKey.getFingerprint());
    }

    /** Creates a {@link PersonalKey} from private keyring data.
     * X.509 bridge certificate is created from key data.
     */
    public static PersonalKey load(byte[] privateKeyData,
            char[] passphrase)
        throws KonException, IOException, PGPException, CertificateException, NoSuchProviderException {