Example usage for java.security UnrecoverableKeyException getCause

List of usage examples for java.security UnrecoverableKeyException getCause

Introduction

In this page you can find the example usage for java.security UnrecoverableKeyException getCause.

Prototype

public synchronized Throwable getCause() 

Source Link

Document

Returns the cause of this throwable or null if the cause is nonexistent or unknown.

Usage

From source file:org.panbox.desktop.common.sharemgmt.ShareManagerImpl.java

private PanboxShare nameTypeUrlToVolumeData(String shareName, String sharePath, StorageBackendType type,
        UUID uuid, char[] password)
        throws IOException, ShareManagerException, ShareMetaDataException, UnrecoverableKeyException {

    if (!new File(sharePath).exists()) {
        throw new ShareManagerException(
                "The specified share path (" + sharePath + ") does not exist or is inaccessible!");
    }/*from w ww  . j  a va2s.com*/

    String metaDataDir = sharePath + File.separator + PanboxConstants.PANBOX_SHARE_METADATA_DIRECTORY
            + File.separator;
    File metaDataFile = new File(metaDataDir);
    File ownerFile = new File(metaDataDir + PanboxConstants.PANBOX_SHARE_OWNER_FILE);

    String deviceName = Settings.getInstance().getDeviceName();

    PanboxShare pbShare = null;

    // create new share
    if (!metaDataFile.exists()) {
        if (password != null) {
            pbShare = createNewShare(shareName, sharePath, type, password, metaDataFile, ownerFile, deviceName);
        } else {
            // empty password field indicates we were trying to load a share
            // from the DB, but the metadata file was missing
            throw new ShareInaccessibleException(
                    "Metadatafile for share " + shareName + " could not be found!");
        }
    } else {

        if (!ownerFile.exists() || !ownerFile.canRead()) {
            throw new ShareManagerException("Can't access owner file at " + metaDataFile.getAbsolutePath());
        }

        MessageDigest md = getMessageDigestForOwnerFile();
        byte[] ownerFp = getOwnerFpFromMessageDigest(ownerFile, md);
        byte[] me = md.digest(identity.getPublicKeySign().getEncoded());
        md.reset();

        if (Settings.getInstance().isProtectedDeviceKey()) {
            password = PasswordEnterDialog.invoke(PasswordEnterDialog.PermissionType.SHARE);
        }

        VolumeParams p = paramsFactory.createVolumeParams().setPublicSignatureKey(identity.getPublicKeySign())
                .setDeviceAlias(deviceName).setPublicDeviceKey(identity.getPublicKeyForDevice(deviceName))
                .setShareName(shareName).setPath(sharePath).setType(type);

        if (password != null) {
            // password was entered
            try {
                p = p.setPrivateDeviceKey(identity.getPrivateKeyForDevice(password, deviceName));
            } catch (UnrecoverableKeyException e) {
                p = p.setPrivateDeviceKey(
                        identity.getPrivateKeyForDevice(KeyConstants.OPEN_KEYSTORE_PASSWORD, deviceName));
            }
        } else {
            // password was not entered! Try default one!
            try {
                p = p.setPrivateDeviceKey(
                        identity.getPrivateKeyForDevice(KeyConstants.OPEN_KEYSTORE_PASSWORD, deviceName));
                // Looks like the configuration of deviceKeyProtection
                // has been changed! We need to set this option to true
                // for next startup!
                Settings.getInstance().setProtectedDeviceKey(false);
            } catch (UnrecoverableKeyException e) {
                logger.warn(
                        "Could not get device key with standard password, but standard password was configured.");

                password = PasswordEnterDialog.invoke(PasswordEnterDialog.PermissionType.SHARE);
                try {
                    p = p.setPrivateDeviceKey(
                            identity.getPrivateKeyForDevice(KeyConstants.OPEN_KEYSTORE_PASSWORD, deviceName));
                    // Looks like the configuration of deviceKeyProtection
                    // has been changed! We need to set this option to true
                    // for next startup!
                    Settings.getInstance().setProtectedDeviceKey(true);
                } catch (UnrecoverableKeyException ex) {
                    logger.error("Entered Password was wrong!");
                    throw ex;
                }
            }
        }

        if (Arrays.equals(me, ownerFp)) {
            // I am the owner
            try {
                logger.debug("I am the owner of this preinitialized share, loading...");
                pbShare = service.loadShare(
                        p.setOwnerAlias(identity.getEmail()).setOwnerSignatureKey(identity.getPublicKeySign()));
            } catch (ShareMetaDataException e) {
                boolean success = false;
                if (e.getCause() instanceof DeviceKeyException) {
                    // the sharemetadata is ok, but the user's current
                    // device has no keys, possibly because the metadata
                    // state has been reverted due to a file conflict. try
                    // if re-adding the device works, otherwise show error
                    try {
                        logger.warn(
                                "Detected missing device key. This may be because of the metadata state having been reverted due to a file conflict. Will try re-adding the device ...",
                                e);
                        if (password == null) {
                            password = PasswordEnterDialog.invoke(PermissionType.SHARE);
                        }
                        VolumeParams ptmp = paramsFactory.createVolumeParams().setKeys(identity, password)
                                .setUserAlias(identity.getEmail()).setDeviceAlias(deviceName)
                                .setPublicDeviceKey(identity.getPublicKeyForDevice(deviceName))
                                .setShareName(shareName).setPath(sharePath).setType(type);
                        pbShare = service.addDevice(ptmp);
                        logger.warn("Successfully re-added device key. Trying to re-run loadShare...");
                        pbShare = service.loadShare(p.setOwnerAlias(identity.getEmail())
                                .setOwnerSignatureKey(identity.getPublicKeySign()));
                        success = true;
                    } catch (Exception e2) {
                        logger.error("Re-addeding device key failed.", e2);
                    }
                }
                // else if (e.getCause() instanceof DeviceListException) {
                // try {
                // logger.warn(
                // "Detected corrupt device list. Will try to reset device list by re-inviting user...",
                // e);
                // if (password == null) {
                // password = PasswordEnterDialog
                // .invoke(PermissionType.SHARE);
                // }
                //
                // PublicKey pk = ((DeviceListException) e.getCause())
                // .getUserKey();
                // PanboxContact c = identity.getAddressbook()
                // .getContactBySignaturePubKey(pk);
                //
                // if (c != null) {
                // logger.warn("DeviceListException associated caused by contact list of contact \""
                // + c.getEmail() + "\" ");
                //
                //
                //
                // VolumeParams pinv = paramsFactory.createVolumeParams()
                // .setKeys(identity, password)
                // .setOwnerAlias(identity.getEmail())
                // .setOtherSignatureKey(c.getPublicKeySign())
                // .setOtherEncryptionKey(c.getPublicKeyEnc())
                // .setUserAlias(c.getEmail())
                // .setShareName(shareName).setPath(sharePath)
                // .setType(type);
                //
                // // Add Invitation fingerPrint so invited user can detect
                // // invitation
                // File invitationFolder = new File(sharePath +
                // File.separator
                // + PanboxConstants.PANBOX_SHARE_METADATA_DIRECTORY
                // + File.separator
                // + PanboxConstants.PANBOX_SHARE_INVITATION_DIRECTORY);
                // if (invitationFolder.isFile()) {
                // // invitationFolder is not a folder
                // throw new RuntimeException(
                // "invitation folder is a file, not a folder!");
                // }
                // if (!invitationFolder.exists()) {
                // invitationFolder.mkdir();
                // }
                // String fingerPrint = DigestUtils.md5Hex(c.getCertSign()
                // .getPublicKey().getEncoded());
                // File fpFile = new File(invitationFolder.getAbsolutePath()
                // + File.separator + fingerPrint);
                // fpFile.createNewFile();
                //
                // pbShare = service.inviteUser(p);
                // pbShare.generatePermissionsModel(identity);
                // pbShare = pbShare = service.loadShare(p.setOwnerAlias(
                // identity.getEmail()).setOwnerSignatureKey(
                // identity.getPublicKeySign()));
                //
                // success = true;
                // } else {
                // logger.warn("DeviceListException could not be attributed to any existing contact. Publiy Key fingerprint: \""
                // + Utils.getPubKeyFingerprint(pk)
                // + "\" ");
                // }
                //
                // } catch (Exception e2) {
                // logger.error("Re-inviting user failed.", e2);
                // }
                // }
                if (!success) {
                    logger.error("Unable to load preinitialized share!", e);
                    throw e;
                }
            }
        } else {
            // I am not the owner
            IPerson owner = getOwnerForShare(md, ownerFp, p);
            if (owner != null) {
                // Found the owner, could be previously initialized share or
                // a new share that i'm invited to

                // Is there an invitation for me?
                File invitationFolder = new File(
                        metaDataDir + PanboxConstants.PANBOX_SHARE_INVITATION_DIRECTORY);
                String fingerPrint = DigestUtils.md5Hex(identity.getPublicKeySign().getEncoded());
                File fpFile = new File(invitationFolder.getAbsolutePath() + File.separator + fingerPrint);
                if (invitationFolder.isDirectory() && fpFile.isFile()) {
                    // I have been invited to this share
                    // accept invitation and delete invitational
                    // fingerprint
                    pbShare = acceptInvitation(password, deviceName, p);

                    logger.debug("Accepted invitation, deleting invitational fingerprint...");
                    if (!fpFile.delete()) {
                        logger.warn("Could not delete invitational fingerprint file from invitations folder: "
                                + fpFile.getAbsolutePath());
                        logger.warn(
                                "If this share is added again it will try to accept an invitation that has already been accepted.");
                    }
                } else {
                    // There is no invitation for me lying around, so
                    // i'll just assume that this is a previously
                    // existing and correctly initialized share
                    logger.debug("Found owner, assuming preinitialized Share...");
                    try {
                        pbShare = service.loadShare(p);
                    } catch (ShareMetaDataException e) {
                        boolean success = false;
                        if (e.getCause() instanceof DeviceKeyException) {
                            // the sharemetadata is ok, but the user's
                            // current device has no keys, possibly because
                            // the metadata state has been reverted due to a
                            // file conflict. try if re-adding the device
                            // works, otherwise show error
                            try {
                                logger.warn(
                                        "Detected missing device key. This may be because of the metadata state having been reverted due to a file conflict. Will try re-adding the device ...",
                                        e);
                                if (password == null)
                                    password = PasswordEnterDialog.invoke(PermissionType.SHARE);
                                VolumeParams ptmp = paramsFactory.createVolumeParams()
                                        .setKeys(identity, password).setUserAlias(identity.getEmail())
                                        .setDeviceAlias(deviceName)
                                        .setPublicDeviceKey(identity.getPublicKeyForDevice(deviceName))
                                        .setShareName(shareName).setPath(sharePath).setType(type);
                                pbShare = service.addDevice(ptmp);
                                logger.warn("Successfully re-added device key. Trying to re-run loadShare...");
                                pbShare = service.loadShare(p);
                                success = true;
                            } catch (Exception e2) {
                                logger.error("Re-addeding device key failed.", e);
                            }
                        }
                        if (!success) {
                            logger.error("Unable to load preinitialized share!", e);
                            throw e;
                        }
                    }
                }
            } else {
                // The Owner Fingerprint in the share did not match
                // any of my contacts or myself. Either the real owner is
                // not in my addressbook, or somebody manipulated the
                // fingerprint in the share

                // TODO: if somebody messed with the owner fingerprint
                // in the share, i could just try to load the share with all
                // my available contacts and myself as owner and see which
                // initialization actually runs through

                throw new UnknownOwnerException("The Owner Fingerprint in the share did not match "
                        + "any of my contacts or myself. Either the real owner is "
                        + "not in my addressbook, or somebody manipulated the " + "fingerprint in the share");
            }
        }

        // share was loaded successfully - now, we still need to check if
        // the current users device list has been marked as corrupted.
        // in this case, accessing the share will fail as no keys will be
        // available. Thus, an exception needs to be thrown at this point
        Exception e = null;
        if ((e = pbShare.getException()) != null) {
            logger.warn("One or more device lists in share " + pbShare.getName() + " seem to be corrupt... ");
            if (e instanceof DeviceListException) {
                DeviceListException ex = (DeviceListException) e;
                Collection<PublicKey> coll = ex.getUserKeys();
                for (Iterator<PublicKey> it = coll.iterator(); it.hasNext();) {
                    PublicKey publicKey = (PublicKey) it.next();
                    if (Utils.keysEqual(identity.getPublicKeySign(), publicKey)) {
                        // exception was thrown because our own devicelist
                        // was corrupt. this means no sharekey or
                        // obfuscationkeys will be available.
                        logger.fatal("Own device list " + Utils.getPubKeyFingerprint(publicKey)
                                + ".db in share " + pbShare.getName()
                                + " seems to be corrupt. Share will not be available.");
                        throw new ShareMetaDataException("Could not verify signature of device list", ex);
                    }
                    logger.warn("Device list " + Utils.getPubKeyFingerprint(publicKey) + ".db in share "
                            + pbShare.getName() + " seems to be corrupt.");
                }
            }
        }
    }
    pbShare.generatePermissionsModel(identity);
    return pbShare;
}