示例#1
0
  private byte[] ProcessNode(XmlPullParser xpp) throws XmlPullParserException, IOException {
    assert (xpp.getEventType() == XmlPullParser.START_TAG);

    byte[] buf = null;

    if (xpp.getAttributeCount() > 0) {
      String protect = xpp.getAttributeValue(null, AttrProtected);
      if (protect != null && protect.equalsIgnoreCase(ValTrue)) {
        String encrypted = ReadStringRaw(xpp);

        if (encrypted.length() > 0) {
          buf = Base64Coder.decode(encrypted);
          byte[] plainText = new byte[buf.length];

          randomStream.processBytes(buf, 0, buf.length, plainText, 0);

          return plainText;
        } else {
          buf = new byte[0];
        }
      }
    }

    return buf;
  }
示例#2
0
  private ProtectedBinary ReadProtectedBinary(XmlPullParser xpp)
      throws XmlPullParserException, IOException {
    String ref = xpp.getAttributeValue(null, AttrRef);
    if (ref != null) {
      xpp.next(); // Consume end tag

      return binPool.get(ref);
    }

    boolean compressed = false;
    String comp = xpp.getAttributeValue(null, AttrCompressed);
    if (comp != null) {
      compressed = comp.equalsIgnoreCase(ValTrue);
    }

    byte[] buf = ProcessNode(xpp);

    if (buf != null) return new ProtectedBinary(true, buf);

    String base64 = ReadString(xpp);
    if (base64.length() == 0) return ProtectedBinary.EMPTY;

    byte[] data = Base64Coder.decode(base64);

    if (compressed) {
      data = MemUtil.decompress(data);
    }

    return new ProtectedBinary(false, data);
  }
示例#3
0
  private UUID ReadUuid(XmlPullParser xpp) throws IOException, XmlPullParserException {
    String encoded = ReadString(xpp);

    if (encoded == null || encoded.length() == 0) {
      return PwDatabaseV4.UUID_ZERO;
    }

    // TODO: Switch to framework Base64 once API level 8 is the minimum
    byte[] buf = Base64Coder.decode(encoded);

    return Types.bytestoUUID(buf);
  }
示例#4
0
  /**
   * Takes a single String as an argument and returns an Encrypted version of that String.
   *
   * @param str String to be encrypted
   * @return <code>String</code> Encrypted version of the provided String
   */
  public String encrypt(String str) {
    try {
      // Encode the string into bytes using utf-8
      byte[] utf8 = str.getBytes("UTF8");

      // Encrypt
      byte[] enc = ecipher.doFinal(utf8);

      // Encode bytes to base64 to get a string
      // return new sun.misc.BASE64Encoder().encode(enc);
      return new String(Base64Coder.encode(enc));

    } catch (Exception e) {
      System.out.println("Exception - " + e);
    }
    return null;
  }
示例#5
0
  /**
   * Takes a encrypted String as an argument, decrypts and returns the decrypted String.
   *
   * @param str Encrypted String to be decrypted
   * @return <code>String</code> Decrypted version of the provided String
   */
  public String decrypt(String str) {

    try {

      // Decode base64 to get bytes
      // byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
      byte[] dec = Base64Coder.decode(str);

      // Decrypt
      byte[] utf8 = dcipher.doFinal(dec);

      // Decode using utf-8
      return new String(utf8, "UTF8");

    } catch (Exception e) {
      System.out.println("Exception - " + e);
    }
    return null;
  }
示例#6
0
  private KdbContext ReadXmlElement(KdbContext ctx, XmlPullParser xpp)
      throws XmlPullParserException, IOException, InvalidDBException {
    String name = xpp.getName();
    switch (ctx) {
      case Null:
        if (name.equalsIgnoreCase(ElemDocNode)) {
          return SwitchContext(ctx, KdbContext.KeePassFile, xpp);
        } else ReadUnknown(xpp);
        break;

      case KeePassFile:
        if (name.equalsIgnoreCase(ElemMeta)) {
          return SwitchContext(ctx, KdbContext.Meta, xpp);
        } else if (name.equalsIgnoreCase(ElemRoot)) {
          return SwitchContext(ctx, KdbContext.Root, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case Meta:
        if (name.equalsIgnoreCase(ElemGenerator)) {
          ReadString(xpp); // Ignore
        } else if (name.equalsIgnoreCase(ElemHeaderHash)) {
          String encodedHash = ReadString(xpp);
          if (!EmptyUtils.isNullOrEmpty(encodedHash) && (hashOfHeader != null)) {
            byte[] hash = Base64Coder.decode(encodedHash);
            if (!Arrays.equals(hash, hashOfHeader)) {
              throw new InvalidDBException();
            }
          }
        } else if (name.equalsIgnoreCase(ElemDbName)) {
          db.name = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemDbNameChanged)) {
          db.nameChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemDbDesc)) {
          db.description = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemDbDescChanged)) {
          db.descriptionChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemDbDefaultUser)) {
          db.defaultUserName = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemDbDefaultUserChanged)) {
          db.defaultUserNameChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemDbColor)) {
          // TODO: Add support to interpret the color if we want to allow changing the database
          // color
          db.color = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemDbMntncHistoryDays)) {
          db.maintenanceHistoryDays = ReadUInt(xpp, DEFAULT_HISTORY_DAYS);
        } else if (name.equalsIgnoreCase(ElemDbKeyChanged)) {
          db.keyLastChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemDbKeyChangeRec)) {
          db.keyChangeRecDays = ReadLong(xpp, -1);
        } else if (name.equalsIgnoreCase(ElemDbKeyChangeForce)) {
          db.keyChangeForceDays = ReadLong(xpp, -1);
        } else if (name.equalsIgnoreCase(ElemMemoryProt)) {
          return SwitchContext(ctx, KdbContext.MemoryProtection, xpp);
        } else if (name.equalsIgnoreCase(ElemCustomIcons)) {
          return SwitchContext(ctx, KdbContext.CustomIcons, xpp);
        } else if (name.equalsIgnoreCase(ElemRecycleBinEnabled)) {
          db.recycleBinEnabled = ReadBool(xpp, true);
        } else if (name.equalsIgnoreCase(ElemRecycleBinUuid)) {
          db.recycleBinUUID = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemRecycleBinChanged)) {
          db.recycleBinChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemEntryTemplatesGroup)) {
          db.entryTemplatesGroup = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemEntryTemplatesGroupChanged)) {
          db.entryTemplatesGroupChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemHistoryMaxItems)) {
          db.historyMaxItems = ReadInt(xpp, -1);
        } else if (name.equalsIgnoreCase(ElemHistoryMaxSize)) {
          db.historyMaxSize = ReadLong(xpp, -1);
        } else if (name.equalsIgnoreCase(ElemEntryTemplatesGroupChanged)) {
          db.entryTemplatesGroupChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemLastSelectedGroup)) {
          db.lastSelectedGroup = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemLastTopVisibleGroup)) {
          db.lastTopVisibleGroup = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemBinaries)) {
          return SwitchContext(ctx, KdbContext.Binaries, xpp);
        } else if (name.equalsIgnoreCase(ElemCustomData)) {
          return SwitchContext(ctx, KdbContext.CustomData, xpp);
        }
        break;

      case MemoryProtection:
        if (name.equalsIgnoreCase(ElemProtTitle)) {
          db.memoryProtection.protectTitle = ReadBool(xpp, false);
        } else if (name.equalsIgnoreCase(ElemProtUserName)) {
          db.memoryProtection.protectUserName = ReadBool(xpp, false);
        } else if (name.equalsIgnoreCase(ElemProtPassword)) {
          db.memoryProtection.protectPassword = ReadBool(xpp, false);
        } else if (name.equalsIgnoreCase(ElemProtURL)) {
          db.memoryProtection.protectUrl = ReadBool(xpp, false);
        } else if (name.equalsIgnoreCase(ElemProtNotes)) {
          db.memoryProtection.protectNotes = ReadBool(xpp, false);
        } else if (name.equalsIgnoreCase(ElemProtAutoHide)) {
          db.memoryProtection.autoEnableVisualHiding = ReadBool(xpp, false);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case CustomIcons:
        if (name.equalsIgnoreCase(ElemCustomIconItem)) {
          return SwitchContext(ctx, KdbContext.CustomIcon, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case CustomIcon:
        if (name.equalsIgnoreCase(ElemCustomIconItemID)) {
          customIconID = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemCustomIconItemData)) {
          String strData = ReadString(xpp);
          if (strData != null && strData.length() > 0) {
            customIconData = Base64Coder.decode(strData);
          } else {
            assert (false);
          }
        } else {
          ReadUnknown(xpp);
        }
        break;

      case Binaries:
        if (name.equalsIgnoreCase(ElemBinary)) {
          String key = xpp.getAttributeValue(null, AttrId);
          if (key != null) {
            ProtectedBinary pbData = ReadProtectedBinary(xpp);
            binPool.put(key, pbData);
          } else {
            ReadUnknown(xpp);
          }
        } else {
          ReadUnknown(xpp);
        }

        break;

      case CustomData:
        if (name.equalsIgnoreCase(ElemStringDictExItem)) {
          return SwitchContext(ctx, KdbContext.CustomDataItem, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case CustomDataItem:
        if (name.equalsIgnoreCase(ElemKey)) {
          customDataKey = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemValue)) {
          customDataValue = ReadString(xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case Root:
        if (name.equalsIgnoreCase(ElemGroup)) {
          assert (ctxGroups.size() == 0);
          if (ctxGroups.size() != 0) throw new IOException("Group list should be empty.");

          db.rootGroup = new PwGroupV4();
          ctxGroups.push((PwGroupV4) db.rootGroup);
          ctxGroup = ctxGroups.peek();

          return SwitchContext(ctx, KdbContext.Group, xpp);
        } else if (name.equalsIgnoreCase(ElemDeletedObjects)) {
          return SwitchContext(ctx, KdbContext.RootDeletedObjects, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case Group:
        if (name.equalsIgnoreCase(ElemUuid)) {
          ctxGroup.uuid = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemName)) {
          ctxGroup.name = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemNotes)) {
          ctxGroup.notes = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemIcon)) {
          ctxGroup.icon = db.iconFactory.getIcon((int) ReadUInt(xpp, 0));
        } else if (name.equalsIgnoreCase(ElemCustomIconID)) {
          ctxGroup.customIcon = db.iconFactory.getIcon(ReadUuid(xpp));
        } else if (name.equalsIgnoreCase(ElemTimes)) {
          return SwitchContext(ctx, KdbContext.GroupTimes, xpp);
        } else if (name.equalsIgnoreCase(ElemIsExpanded)) {
          ctxGroup.isExpanded = ReadBool(xpp, true);
        } else if (name.equalsIgnoreCase(ElemGroupDefaultAutoTypeSeq)) {
          ctxGroup.defaultAutoTypeSequence = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemEnableAutoType)) {
          ctxGroup.enableAutoType = StringToBoolean(ReadString(xpp));
        } else if (name.equalsIgnoreCase(ElemEnableSearching)) {
          ctxGroup.enableSearching = StringToBoolean(ReadString(xpp));
        } else if (name.equalsIgnoreCase(ElemLastTopVisibleEntry)) {
          ctxGroup.lastTopVisibleEntry = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemGroup)) {
          ctxGroup = new PwGroupV4();
          ctxGroups.peek().AddGroup(ctxGroup, true);
          ctxGroups.push(ctxGroup);

          return SwitchContext(ctx, KdbContext.Group, xpp);
        } else if (name.equalsIgnoreCase(ElemEntry)) {
          ctxEntry = new PwEntryV4();
          ctxGroup.AddEntry(ctxEntry, true);

          entryInHistory = false;
          return SwitchContext(ctx, KdbContext.Entry, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case Entry:
        if (name.equalsIgnoreCase(ElemUuid)) {
          ctxEntry.setUUID(ReadUuid(xpp));
        } else if (name.equalsIgnoreCase(ElemIcon)) {
          ctxEntry.icon = db.iconFactory.getIcon((int) ReadUInt(xpp, 0));
        } else if (name.equalsIgnoreCase(ElemCustomIconID)) {
          ctxEntry.customIcon = db.iconFactory.getIcon(ReadUuid(xpp));
        } else if (name.equalsIgnoreCase(ElemFgColor)) {
          ctxEntry.foregroundColor = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemBgColor)) {
          ctxEntry.backgroupColor = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemOverrideUrl)) {
          ctxEntry.overrideURL = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemTags)) {
          ctxEntry.tags = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemTimes)) {
          return SwitchContext(ctx, KdbContext.EntryTimes, xpp);
        } else if (name.equalsIgnoreCase(ElemString)) {
          return SwitchContext(ctx, KdbContext.EntryString, xpp);
        } else if (name.equalsIgnoreCase(ElemBinary)) {
          return SwitchContext(ctx, KdbContext.EntryBinary, xpp);
        } else if (name.equalsIgnoreCase(ElemAutoType)) {
          return SwitchContext(ctx, KdbContext.EntryAutoType, xpp);
        } else if (name.equalsIgnoreCase(ElemHistory)) {
          assert (!entryInHistory);

          if (!entryInHistory) {
            ctxHistoryBase = ctxEntry;
            return SwitchContext(ctx, KdbContext.EntryHistory, xpp);
          } else {
            ReadUnknown(xpp);
          }
        } else {
          ReadUnknown(xpp);
        }
        break;

      case GroupTimes:
      case EntryTimes:
        ITimeLogger tl;
        if (ctx == KdbContext.GroupTimes) {
          tl = ctxGroup;
        } else {
          tl = ctxEntry;
        }

        if (name.equalsIgnoreCase(ElemLastModTime)) {
          tl.setLastModificationTime(ReadTime(xpp));
        } else if (name.equalsIgnoreCase(ElemCreationTime)) {
          tl.setCreationTime(ReadTime(xpp));
        } else if (name.equalsIgnoreCase(ElemLastAccessTime)) {
          tl.setLastAccessTime(ReadTime(xpp));
        } else if (name.equalsIgnoreCase(ElemExpiryTime)) {
          tl.setExpiryTime(ReadTime(xpp));
        } else if (name.equalsIgnoreCase(ElemExpires)) {
          tl.setExpires(ReadBool(xpp, false));
        } else if (name.equalsIgnoreCase(ElemUsageCount)) {
          tl.setUsageCount(ReadULong(xpp, 0));
        } else if (name.equalsIgnoreCase(ElemLocationChanged)) {
          tl.setLocationChanged(ReadTime(xpp));
        } else {
          ReadUnknown(xpp);
        }
        break;

      case EntryString:
        if (name.equalsIgnoreCase(ElemKey)) {
          ctxStringName = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemValue)) {
          ctxStringValue = ReadProtectedString(xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case EntryBinary:
        if (name.equalsIgnoreCase(ElemKey)) {
          ctxBinaryName = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemValue)) {
          ctxBinaryValue = ReadProtectedBinary(xpp);
        }
        break;

      case EntryAutoType:
        if (name.equalsIgnoreCase(ElemAutoTypeEnabled)) {
          ctxEntry.autoType.enabled = ReadBool(xpp, true);
        } else if (name.equalsIgnoreCase(ElemAutoTypeObfuscation)) {
          ctxEntry.autoType.obfuscationOptions = ReadUInt(xpp, 0);
        } else if (name.equalsIgnoreCase(ElemAutoTypeDefaultSeq)) {
          ctxEntry.autoType.defaultSequence = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemAutoTypeItem)) {
          return SwitchContext(ctx, KdbContext.EntryAutoTypeItem, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case EntryAutoTypeItem:
        if (name.equalsIgnoreCase(ElemWindow)) {
          ctxATName = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemKeystrokeSequence)) {
          ctxATSeq = ReadString(xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case EntryHistory:
        if (name.equalsIgnoreCase(ElemEntry)) {
          ctxEntry = new PwEntryV4();
          ctxHistoryBase.history.add(ctxEntry);

          entryInHistory = true;
          return SwitchContext(ctx, KdbContext.Entry, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case RootDeletedObjects:
        if (name.equalsIgnoreCase(ElemDeletedObject)) {
          ctxDeletedObject = new PwDeletedObject();
          db.deletedObjects.add(ctxDeletedObject);

          return SwitchContext(ctx, KdbContext.DeletedObject, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case DeletedObject:
        if (name.equalsIgnoreCase(ElemUuid)) {
          ctxDeletedObject.uuid = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemDeletionTime)) {
          ctxDeletedObject.setDeletionTime(ReadTime(xpp));
        } else {
          ReadUnknown(xpp);
        }
        break;

      default:
        ReadUnknown(xpp);
        break;
    }

    return ctx;
  }