예제 #1
0
파일: Volume.java 프로젝트: skakw/PanBox
  @Override
  public void inviteUser(
      String ownerAlias,
      PrivateKey ownerPrivSigKey,
      PublicKey ownerPubEncKey,
      PrivateKey ownerPrivEncKey,
      String alias,
      PublicKey userPubEncKey,
      PublicKey userPubSigKey)
      throws ShareMetaDataException {

    // Check if called by owner
    if (!Utils.keysMatch(shareMetaData.ownerPubSigKey, ownerPrivSigKey)) {
      throw new ShareMetaDataException("This method can only be called by the share owner!");
    }

    SharePartList spl = shareMetaData.getSharePartList();
    // Check if user alias already exists
    if (spl.getPublicKey(alias) == null) {
      spl.add(userPubSigKey, alias);
    }

    // Create deviceList and sign for user
    HashMap<String, PublicKey> dkList = new HashMap<String, PublicKey>();
    dkList.put(IVolume.MASTER_KEY, userPubEncKey);
    DeviceList devices = shareMetaData.createDeviceList(userPubSigKey, dkList);

    try {
      shareMetaData.addObfuscationKey(ownerPubEncKey, ownerPrivEncKey, userPubEncKey);
    } catch (SymmetricKeyEncryptionException | SymmetricKeyDecryptionException e) {
      throw new ShareMetaDataException("Could not add encrypted obfuscation key for new user", e);
    }

    // add encrypted sharekey for device
    try {
      this.shareMetaData.shareKeys.addDevice(ownerPubEncKey, ownerPrivEncKey, userPubEncKey);
    } catch (Exception e) {
      throw new ShareMetaDataException("Could not add encrypted share keys for new user", e);
    }

    // Sign everything
    try {
      spl.sign(ownerPrivSigKey);
    } catch (SignatureException e) {
      throw new ShareMetaDataException("Could not add new user to ShareParticipantList.", e);
    }

    try {
      devices.sign(ownerPrivSigKey, shareMetaData.shareKeys, shareMetaData.obfuscationKeys);
    } catch (SignatureException e) {
      throw new ShareMetaDataException("Could not sign devicelist", e);
    }

    this.shareMetaData.persist();
    this.shareMetaData.persist(devices);
  }
예제 #2
0
  private synchronized void createIVFile(byte[] iv, String encryptedName, SecretKey key)
      throws ObfuscationException {
    // store IV in pool
    String ivhex = Utils.bytesToHex(iv);
    byte[] lookupHashBytes = createLookupHash(encryptedName, key);
    String lookupHashStr = Utils.bytesToHex(lookupHashBytes);

    char firstChar = lookupHashStr.toUpperCase().charAt(0);

    File dirs = getIVPoolSubDir(firstChar);

    // java based file creation
    File ivFile = new File(dirs.getAbsolutePath() + File.separator + lookupHashStr + ivhex);
    try {
      ivFile.createNewFile();
    } catch (IOException e) {
      logger.error("Unable to create IV sidecar file!", e);
      throw new ObfuscationException("Unable to create IV sidecar file!", e);
    }
  }
예제 #3
0
파일: Volume.java 프로젝트: skakw/PanBox
  @Override
  public void addDevice(
      String alias,
      PublicKey masterPubSigKey,
      PrivateKey masterPrivSigKey,
      String newDeviceAlias,
      PublicKey newDevicePubKey,
      PublicKey masterPubEncKey,
      PrivateKey masterPrivEncKey)
      throws ShareMetaDataException {

    if (IVolume.MASTER_KEY.equals(newDeviceAlias)) {
      throw new IllegalArgumentException("Illegal alias for device. Choose another alias");
    }

    // verify matching public/private keys
    if (!Utils.keysMatch(masterPubSigKey, masterPrivSigKey)) {
      throw new IllegalArgumentException(
          "User's master private and public signature keys do not match!");
    }
    if (!Utils.keysMatch(masterPubEncKey, masterPrivEncKey)) {
      throw new IllegalArgumentException(
          "User's master private and public encryption keys do not match!");
    }

    // verify integrity of ShareParticipantList
    SharePartList sharePartList = shareMetaData.getSharePartList();
    try {
      SignatureHelper.verify(
          sharePartList, sharePartList.getSignature(), shareMetaData.ownerPubSigKey);
    } catch (InvalidKeyException
        | NoSuchAlgorithmException
        | SignatureException
        | SerializationException e) {
      throw new ShareMetaDataException("Could not verify ShareParticipantsList signature", e);
    }

    // check if masterPubSigKey is in ShareParticipants
    if (!sharePartList.getPublicKey(alias).equals(masterPubSigKey)) {
      throw new ShareMetaDataException(
          "Given user singature publickey is not " + "in sharepartiticapnts list");
    }

    // Get DeviceList for user
    DeviceList deviceList = shareMetaData.getDeviceLists().get(masterPubSigKey);
    if (deviceList == null) {
      throw new ShareMetaDataException(
          "DeviceList for user " + alias + " was empty, which should never be the case.");
    }

    // add device
    deviceList.addDevice(newDeviceAlias, newDevicePubKey);

    // add encrypted Obfuscation key for new device
    try {
      shareMetaData.addObfuscationKey(masterPubEncKey, masterPrivEncKey, newDevicePubKey);
    } catch (SymmetricKeyEncryptionException | SymmetricKeyDecryptionException e) {
      throw new ShareMetaDataException("Could not add encrypted obfuscation key for new device", e);
    }

    // add encrypted sharekey for device
    try {
      this.shareMetaData.shareKeys.addDevice(masterPubEncKey, masterPrivEncKey, newDevicePubKey);
    } catch (Exception e) {
      throw new ShareMetaDataException("Could not add encrypted share keys for new device", e);
    }
    // Sign everything
    try {
      deviceList.sign(masterPrivSigKey, shareMetaData.shareKeys, shareMetaData.obfuscationKeys);
    } catch (SignatureException e) {
      throw new ShareMetaDataException("Could not sign devicelist", e);
    }

    this.shareMetaData.persist(deviceList);
  }
예제 #4
0
파일: Volume.java 프로젝트: skakw/PanBox
  @Override
  public ShareMetaData createShareMetaData(
      String ownerAlias,
      PublicKey ownerPubSigKey,
      PrivateKey ownerPrivSigKey,
      PublicKey ownerPubEncKey,
      PrivateKey ownerPrivEncKey,
      String deviceAlias,
      PublicKey devicePubKey)
      throws IllegalArgumentException, ShareMetaDataException {

    if (IVolume.MASTER_KEY.equals(deviceAlias)) {
      throw new IllegalArgumentException("Illegal alias for device. Choose another alias");
    }

    if (db.exists()) {
      throw new IllegalArgumentException(
          "Can't initialize new share metadata, because database already exists.");
    }

    // verify matching public/private keys
    if (!Utils.keysMatch(ownerPubSigKey, ownerPrivSigKey)) {
      throw new IllegalArgumentException("Owners master private and public key do not match!");
    }

    shareMetaData = new ShareMetaData(db, ownerPubSigKey);

    try {
      this.shareMetaData.load();
    } catch (InitializaionException e) {
      throw new ShareMetaDataException("Could not initialize ShareMetaData", e);
    } catch (SignatureException e) {
      throw new ShareMetaDataException("Could not verify signature", e);
    } catch (DeviceListException e) {
      throw new ShareMetaDataException("Could not verify signature", e);
    }

    // Init Participants list
    SharePartList spl = shareMetaData.initSharePartList();
    spl.add(ownerPubSigKey, ownerAlias);

    // Init DeviceList
    HashMap<String, PublicKey> dkList = new HashMap<String, PublicKey>();
    dkList.put(IVolume.MASTER_KEY, ownerPubEncKey);
    dkList.put(deviceAlias, devicePubKey);
    DeviceList devices = shareMetaData.createDeviceList(ownerPubSigKey, dkList);

    // Create ObfuscationKey
    try {
      shareMetaData.addObfuscationKey(ownerPubEncKey, null, null);
      shareMetaData.addObfuscationKey(ownerPubEncKey, ownerPrivEncKey, devicePubKey);
    } catch (SymmetricKeyEncryptionException | SymmetricKeyDecryptionException e) {
      throw new ShareMetaDataException("Could not initialize obfuscation key", e);
    }

    // Create initial ShareKey
    ShareKeyDB shareKeys = shareMetaData.getShareKeys();
    SecretKey shareKey = CryptCore.generateSymmetricKey();
    try {
      shareKeys.add(shareKey, dkList.values());
    } catch (SymmetricKeyEncryptionException e1) {
      throw new ShareMetaDataException("Could not encrypt sharekey for device", e1);
    }
    try {
      spl.sign(ownerPrivSigKey);
    } catch (SignatureException e2) {
      throw new ShareMetaDataException("Could not sign SharePartList", e2);
    }

    try {
      devices.sign(ownerPrivSigKey, shareKeys, shareMetaData.obfuscationKeys);
    } catch (SignatureException e2) {
      throw new ShareMetaDataException("Could not sign DeviceList", e2);
    }

    shareMetaData.persist();
    shareMetaData.persist(devices);
    return shareMetaData;
  }
예제 #5
0
  /**
   * Deobfuscates a string with the given key and encodes it with Base64
   *
   * @param str - string to deobfuscate
   * @param key - symmetric key used to decrypt the string
   * @return - deobfuscated string
   * @throws MissingIVException if for a given filename, no IV sidecar file could be found.
   *     base64LookupHash will be set in this exception
   * @throws ObfuscationException
   */
  public synchronized String deObfuscate(String str, SecretKey key)
      throws MissingIVException, ObfuscationException {

    logger.debug("Obfuscator(" + this.shareName + ") DeObfuscate(String, key): " + str);

    // lookup in cache
    if (cachedDeObfuscatedNames.containsKey(str)) {
      logger.debug("DeObfuscate(String, key) - return cached value for: " + str);
      return cachedDeObfuscatedNames.get(str);
    }

    // if not in cache, do processing
    byte[] lookupHash = createLookupHash(str, key);
    String sLookupHash = Utils.bytesToHex(lookupHash);

    byte[] iv = ivPoolImpl.getCachedIV(sLookupHash, this.shareName);

    if (null == iv) {
      // re-read IVs from file-system or server
      logger.debug("Obfuscator: RE-fetch IV Pool");
      ivPoolImpl.fetchIVPool(this.sharePath, this.shareName);
      iv = ivPoolImpl.getCachedIV(sLookupHash, this.shareName);

      // // "direct" IV lookup
      // char firstChar = base64LookupHash.toUpperCase().charAt(0);
      // File path = getIVPoolSubDir(firstChar);
      // File[] res = path.listFiles((FileFilter) new PrefixFileFilter(
      // base64LookupHash));
      // iv = Utils.hexToBytes(res[0].getName().substring(41));

    }

    if (iv == null) {
      // this may be due to the CSP trying to resolve a conflict by
      // renaming two conflicting copies of a file. in this case, the
      // obfuscator's filename conflict resolution handler need to be
      // called to try to recover this situation. however, this needs to
      // be done *outside* of this method as we need full context (i.e.
      // absolute filename etc)

      // error cannot decode
      logger.error(
          "Could not find IV for hash: " + sLookupHash + " generated from obfuscate file: " + str);
      throw new MissingIVException(
          "Could not find IV for hash: " + sLookupHash + " generated from obfuscate file: " + str,
          sLookupHash);
    }

    String originalName = null;
    try {
      originalName = decryptFileName(str, key.getEncoded(), iv, false, EncodingType.BASE64);
    } catch (InvalidKeyException
        | NoSuchAlgorithmException
        | NoSuchPaddingException
        | InvalidAlgorithmParameterException
        | IllegalBlockSizeException
        | BadPaddingException
        | DataFormatException
        | IOException e) {
      logger.error("Could not deobfuscate string: " + str, e);
      throw new ObfuscationException("Could not decrypt string: " + str, e);
    }

    // do caching
    cachedDeObfuscatedNames.put(str, originalName);

    logger.debug(
        "Obfuscator(" + this.shareName + ") DeObfuscate(String, key)-return: " + originalName);
    return originalName;
  }