NekoX/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java

276 lines
10 KiB
Java

/*
* Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openintents.openpgp;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import android.os.Parcel;
import android.os.Parcelable;
import org.openintents.openpgp.util.OpenPgpUtils;
@SuppressWarnings("unused")
public class OpenPgpSignatureResult implements Parcelable {
/**
* Since there might be a case where new versions of the client using the library getting
* old versions of the protocol (and thus old versions of this class), we need a versioning
* system for the parcels sent between the clients and the providers.
*/
private static final int PARCELABLE_VERSION = 5;
// content not signed
public static final int RESULT_NO_SIGNATURE = -1;
// invalid signature!
public static final int RESULT_INVALID_SIGNATURE = 0;
// successfully verified signature, with confirmed key
public static final int RESULT_VALID_KEY_CONFIRMED = 1;
// no key was found for this signature verification
public static final int RESULT_KEY_MISSING = 2;
// successfully verified signature, but with unconfirmed key
public static final int RESULT_VALID_KEY_UNCONFIRMED = 3;
// key has been revoked -> invalid signature!
public static final int RESULT_INVALID_KEY_REVOKED = 4;
// key is expired -> invalid signature!
public static final int RESULT_INVALID_KEY_EXPIRED = 5;
// insecure cryptographic algorithms/protocol -> invalid signature!
public static final int RESULT_INVALID_KEY_INSECURE = 6;
// data wasn't encrypted to recipient intended in signature
public static final int RESULT_INVALID_NOT_INTENDED_RECIPIENT = 7;
private final int result;
private final long keyId;
private final String primaryUserId;
private final List<String> userIds;
private final List<String> confirmedUserIds;
private final SenderStatusResult senderStatusResult;
private final Date signatureTimestamp;
private final AutocryptPeerResult autocryptPeerentityResult;
private OpenPgpSignatureResult(int signatureStatus, String signatureUserId, long keyId,
List<String> userIds, List<String> confirmedUserIds, SenderStatusResult senderStatusResult,
Boolean signatureOnly, Date signatureTimestamp, AutocryptPeerResult autocryptPeerentityResult) {
this.result = signatureStatus;
this.primaryUserId = signatureUserId;
this.keyId = keyId;
this.userIds = userIds;
this.confirmedUserIds = confirmedUserIds;
this.senderStatusResult = senderStatusResult;
this.signatureTimestamp = signatureTimestamp;
this.autocryptPeerentityResult = autocryptPeerentityResult;
}
private OpenPgpSignatureResult(Parcel source, int version) {
this.result = source.readInt();
// we dropped support for signatureOnly, but need to skip the value for compatibility
source.readByte();
this.primaryUserId = source.readString();
this.keyId = source.readLong();
if (version > 1) {
this.userIds = source.createStringArrayList();
} else {
this.userIds = null;
}
// backward compatibility for this exact version
if (version > 2) {
this.senderStatusResult = readEnumWithNullAndFallback(
source, SenderStatusResult.values, SenderStatusResult.UNKNOWN);
this.confirmedUserIds = source.createStringArrayList();
} else {
this.senderStatusResult = SenderStatusResult.UNKNOWN;
this.confirmedUserIds = null;
}
if (version > 3) {
this.signatureTimestamp = source.readInt() > 0 ? new Date(source.readLong()) : null;
} else {
this.signatureTimestamp = null;
}
if (version > 4) {
this.autocryptPeerentityResult = readEnumWithNullAndFallback(source, AutocryptPeerResult.values, null);
} else {
this.autocryptPeerentityResult = null;
}
}
public int getResult() {
return result;
}
public SenderStatusResult getSenderStatusResult() {
return senderStatusResult;
}
public String getPrimaryUserId() {
return primaryUserId;
}
public List<String> getUserIds() {
return Collections.unmodifiableList(userIds);
}
public List<String> getConfirmedUserIds() {
return Collections.unmodifiableList(confirmedUserIds);
}
public long getKeyId() {
return keyId;
}
public Date getSignatureTimestamp() {
return signatureTimestamp;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
/*
NOTE: When adding fields in the process of updating this API, make sure to bump
{@link #PARCELABLE_VERSION}.
*/
dest.writeInt(PARCELABLE_VERSION);
// Inject a placeholder that will store the parcel size from this point on
// (not including the size itself).
int sizePosition = dest.dataPosition();
dest.writeInt(0);
int startPosition = dest.dataPosition();
// version 1
dest.writeInt(result);
// signatureOnly is deprecated since version 3. we pass a dummy value for compatibility
dest.writeByte((byte) 0);
dest.writeString(primaryUserId);
dest.writeLong(keyId);
// version 2
dest.writeStringList(userIds);
// version 3
writeEnumWithNull(dest, senderStatusResult);
dest.writeStringList(confirmedUserIds);
// version 4
if (signatureTimestamp != null) {
dest.writeInt(1);
dest.writeLong(signatureTimestamp.getTime());
} else {
dest.writeInt(0);
}
// version 5
writeEnumWithNull(dest, autocryptPeerentityResult);
// Go back and write the size
int parcelableSize = dest.dataPosition() - startPosition;
dest.setDataPosition(sizePosition);
dest.writeInt(parcelableSize);
dest.setDataPosition(startPosition + parcelableSize);
}
public static final Creator<OpenPgpSignatureResult> CREATOR = new Creator<OpenPgpSignatureResult>() {
public OpenPgpSignatureResult createFromParcel(final Parcel source) {
int version = source.readInt(); // parcelableVersion
int parcelableSize = source.readInt();
int startPosition = source.dataPosition();
OpenPgpSignatureResult vr = new OpenPgpSignatureResult(source, version);
// skip over all fields added in future versions of this parcel
source.setDataPosition(startPosition + parcelableSize);
return vr;
}
public OpenPgpSignatureResult[] newArray(final int size) {
return new OpenPgpSignatureResult[size];
}
};
@Override
public String toString() {
String out = "\nresult: " + result;
out += "\nprimaryUserId: " + primaryUserId;
out += "\nuserIds: " + userIds;
out += "\nkeyId: " + OpenPgpUtils.convertKeyIdToHex(keyId);
return out;
}
public static OpenPgpSignatureResult createWithValidSignature(int signatureStatus, String primaryUserId,
long keyId, List<String> userIds, List<String> confirmedUserIds,
SenderStatusResult senderStatusResult, Date signatureTimestamp) {
if (signatureStatus == RESULT_NO_SIGNATURE || signatureStatus == RESULT_KEY_MISSING ||
signatureStatus == RESULT_INVALID_SIGNATURE) {
throw new IllegalArgumentException("can only use this method for valid types of signatures");
}
return new OpenPgpSignatureResult(signatureStatus, primaryUserId, keyId, userIds, confirmedUserIds,
senderStatusResult, null, signatureTimestamp, null);
}
public static OpenPgpSignatureResult createWithNoSignature() {
return new OpenPgpSignatureResult(RESULT_NO_SIGNATURE, null, 0L, null, null, null, null, null, null);
}
public static OpenPgpSignatureResult createWithKeyMissing(long keyId, Date signatureTimestamp) {
return new OpenPgpSignatureResult(RESULT_KEY_MISSING, null, keyId, null, null, null, null, signatureTimestamp, null);
}
public static OpenPgpSignatureResult createWithInvalidSignature() {
return new OpenPgpSignatureResult(RESULT_INVALID_SIGNATURE, null, 0L, null, null, null, null, null, null);
}
@Deprecated
public OpenPgpSignatureResult withSignatureOnlyFlag(boolean signatureOnly) {
return new OpenPgpSignatureResult(result, primaryUserId, keyId, userIds, confirmedUserIds,
senderStatusResult, signatureOnly, signatureTimestamp, autocryptPeerentityResult);
}
public OpenPgpSignatureResult withAutocryptPeerResult(AutocryptPeerResult autocryptPeerentityResult) {
return new OpenPgpSignatureResult(
result, primaryUserId, keyId, userIds, confirmedUserIds,
senderStatusResult, null, signatureTimestamp, autocryptPeerentityResult);
}
private static <T extends Enum<T>> T readEnumWithNullAndFallback(Parcel source, T[] enumValues, T fallback) {
int valueOrdinal = source.readInt();
if (valueOrdinal == -1) {
return null;
}
if (valueOrdinal >= enumValues.length) {
return fallback;
}
return enumValues[valueOrdinal];
}
private static void writeEnumWithNull(Parcel dest, Enum<?> enumValue) {
if (enumValue == null) {
dest.writeInt(-1);
return;
}
dest.writeInt(enumValue.ordinal());
}
public enum SenderStatusResult {
UNKNOWN, USER_ID_CONFIRMED, USER_ID_UNCONFIRMED, USER_ID_MISSING;
public static final SenderStatusResult[] values = values();
}
public enum AutocryptPeerResult {
OK, NEW, MISMATCH;
public static final AutocryptPeerResult[] values = values();
}
}