Kotlin conversion: Verification

This commit is contained in:
Paul Schaub 2023-10-31 12:25:54 +01:00
parent 567571cf6c
commit 6c5c4b3d98
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
2 changed files with 76 additions and 222 deletions

View File

@ -1,222 +0,0 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package sop;
import sop.enums.SignatureMode;
import sop.util.Optional;
import sop.util.UTCUtil;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.text.ParseException;
import java.util.Date;
/**
* Class bundling information about a verified signature.
*/
public class Verification {
private final Date creationTime;
private final String signingKeyFingerprint;
private final String signingCertFingerprint;
private final Optional<SignatureMode> signatureMode;
private final Optional<String> description;
private static final String MODE = "mode:";
/**
* Create a new {@link Verification} without mode and description.
*
* @param creationTime signature creation time
* @param signingKeyFingerprint fingerprint of the signing (sub-) key
* @param signingCertFingerprint fingerprint of the certificate
*/
public Verification(@Nonnull Date creationTime,
@Nonnull String signingKeyFingerprint,
@Nonnull String signingCertFingerprint) {
this(creationTime, signingKeyFingerprint, signingCertFingerprint, Optional.ofEmpty(), Optional.ofEmpty());
}
/**
* Create a new {@link Verification}.
*
* @param creationTime signature creation time
* @param signingKeyFingerprint fingerprint of the signing (sub-) key
* @param signingCertFingerprint fingerprint of the certificate
* @param signatureMode signature mode (optional, may be <pre>null</pre>)
* @param description free-form description, e.g. <pre>certificate from dkg.asc</pre> (optional, may be <pre>null</pre>)
*/
public Verification(@Nonnull Date creationTime,
@Nonnull String signingKeyFingerprint,
@Nonnull String signingCertFingerprint,
@Nullable SignatureMode signatureMode,
@Nullable String description) {
this(
creationTime,
signingKeyFingerprint,
signingCertFingerprint,
Optional.ofNullable(signatureMode),
Optional.ofNullable(nullSafeTrim(description))
);
}
private Verification(@Nonnull Date creationTime,
@Nonnull String signingKeyFingerprint,
@Nonnull String signingCertFingerprint,
@Nonnull Optional<SignatureMode> signatureMode,
@Nonnull Optional<String> description) {
this.creationTime = creationTime;
this.signingKeyFingerprint = signingKeyFingerprint;
this.signingCertFingerprint = signingCertFingerprint;
this.signatureMode = signatureMode;
this.description = description;
}
private static String nullSafeTrim(@Nullable String string) {
if (string == null) {
return null;
}
return string.trim();
}
@Nonnull
public static Verification fromString(@Nonnull String toString) {
String[] split = toString.trim().split(" ");
if (split.length < 3) {
throw new IllegalArgumentException("Verification must be of the format 'UTC-DATE OpenPGPFingerprint OpenPGPFingerprint [mode] [info]'");
}
if (split.length == 3) {
return new Verification(
parseUTCDate(split[0]), // timestamp
split[1], // key FP
split[2] // cert FP
);
}
SignatureMode mode = null;
int index = 3;
if (split[index].startsWith(MODE)) {
mode = SignatureMode.valueOf(split[3].substring(MODE.length()));
index++;
}
StringBuilder sb = new StringBuilder();
for (int i = index; i < split.length; i++) {
if (sb.length() != 0) {
sb.append(' ');
}
sb.append(split[i]);
}
return new Verification(
parseUTCDate(split[0]), // timestamp
split[1], // key FP
split[2], // cert FP
mode, // signature mode
sb.length() != 0 ? sb.toString() : null // description
);
}
private static Date parseUTCDate(String utcFormatted) {
try {
return UTCUtil.parseUTCDate(utcFormatted);
} catch (ParseException e) {
throw new IllegalArgumentException("Malformed UTC timestamp.", e);
}
}
/**
* Return the signatures' creation time.
*
* @return signature creation time
*/
@Nonnull
public Date getCreationTime() {
return creationTime;
}
/**
* Return the fingerprint of the signing (sub)key.
*
* @return signing key fingerprint
*/
@Nonnull
public String getSigningKeyFingerprint() {
return signingKeyFingerprint;
}
/**
* Return the fingerprint fo the signing certificate.
*
* @return signing certificate fingerprint
*/
@Nonnull
public String getSigningCertFingerprint() {
return signingCertFingerprint;
}
/**
* Return the mode of the signature.
* Optional, may return <pre>null</pre>.
*
* @return signature mode
*/
@Nonnull
public Optional<SignatureMode> getSignatureMode() {
return signatureMode;
}
/**
* Return an optional description.
* Optional, may return <pre>null</pre>.
*
* @return description
*/
@Nonnull
public Optional<String> getDescription() {
return description;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder()
.append(UTCUtil.formatUTCDate(getCreationTime()))
.append(' ')
.append(getSigningKeyFingerprint())
.append(' ')
.append(getSigningCertFingerprint());
if (signatureMode.isPresent()) {
sb.append(' ').append(MODE).append(signatureMode.get());
}
if (description.isPresent()) {
sb.append(' ').append(description.get());
}
return sb.toString();
}
@Override
public int hashCode() {
return toString().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (!(obj instanceof Verification)) {
return false;
}
Verification other = (Verification) obj;
return toString().equals(other.toString());
}
}

View File

@ -0,0 +1,76 @@
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package sop
import java.text.ParseException
import java.util.Date
import sop.enums.SignatureMode
import sop.util.Optional
import sop.util.UTCUtil
data class Verification(
val creationTime: Date,
val signingKeyFingerprint: String,
val signingCertFingerprint: String,
val signatureMode: Optional<SignatureMode>,
val description: Optional<String>
) {
@JvmOverloads
constructor(
creationTime: Date,
signingKeyFingerprint: String,
signingCertFingerprint: String,
signatureMode: SignatureMode? = null,
description: String? = null
) : this(
creationTime,
signingKeyFingerprint,
signingCertFingerprint,
Optional.ofNullable(signatureMode),
Optional.ofNullable(description?.trim()))
override fun toString(): String =
"${UTCUtil.formatUTCDate(creationTime)} $signingKeyFingerprint $signingCertFingerprint" +
(if (signatureMode.isPresent) " mode:${signatureMode.get()}" else "") +
(if (description.isPresent) " ${description.get()}" else "")
companion object {
@JvmStatic
fun fromString(string: String): Verification {
val split = string.trim().split(" ")
require(split.size >= 3) {
"Verification must be of the format 'UTC-DATE OpenPGPFingerprint OpenPGPFingerprint [mode] [info]'."
}
if (split.size == 3) {
return Verification(parseUTCDate(split[0]), split[1], split[2])
}
var index = 3
val mode =
if (split[3].startsWith("mode:")) {
index += 1
SignatureMode.valueOf(split[3].substring("mode:".length))
} else null
val description = split.subList(index, split.size).joinToString(" ").ifBlank { null }
return Verification(
parseUTCDate(split[0]),
split[1],
split[2],
Optional.ofNullable(mode),
Optional.ofNullable(description))
}
@JvmStatic
private fun parseUTCDate(string: String): Date {
return try {
UTCUtil.parseUTCDate(string)
} catch (e: ParseException) {
throw IllegalArgumentException("Malformed UTC timestamp.", e)
}
}
}
}