mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-25 12:27:58 +01:00
Port CertificationFactory to kotlin
This commit is contained in:
parent
d9b5783e5e
commit
58c5fa4dd8
3 changed files with 74 additions and 126 deletions
|
@ -1,125 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package org.pgpainless.wot;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.bouncycastle.bcpg.sig.RegularExpression;
|
|
||||||
import org.bouncycastle.bcpg.sig.TrustSignature;
|
|
||||||
import org.bouncycastle.openpgp.PGPSignature;
|
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil;
|
|
||||||
import org.pgpainless.wot.dijkstra.sq.CertSynopsis;
|
|
||||||
import org.pgpainless.wot.dijkstra.sq.Certification;
|
|
||||||
import org.pgpainless.wot.dijkstra.sq.Depth;
|
|
||||||
import org.pgpainless.wot.dijkstra.sq.RegexSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory class for creating {@link Certification} objects from {@link PGPSignature PGPSignatures}.
|
|
||||||
* The purpose of this class is to minimize the number of PGPainless / Bouncycastle class dependencies in wot-dijkstra.
|
|
||||||
*/
|
|
||||||
public class CertificationFactory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a {@link Certification} object from a delegation signature.
|
|
||||||
*
|
|
||||||
* @param issuer signature issuer certificate
|
|
||||||
* @param target signature target certificate
|
|
||||||
* @param signature signature
|
|
||||||
* @return certification
|
|
||||||
*/
|
|
||||||
public static Certification fromDelegation(CertSynopsis issuer,
|
|
||||||
CertSynopsis target,
|
|
||||||
PGPSignature signature) {
|
|
||||||
return fromSignature(issuer, null, target, signature);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a {@link Certification} object from a certification signature.
|
|
||||||
*
|
|
||||||
* @param issuer signature issuer certificate
|
|
||||||
* @param targetUserId signature target user ID
|
|
||||||
* @param target signature target certificate
|
|
||||||
* @param signature signature
|
|
||||||
* @return certification
|
|
||||||
*/
|
|
||||||
public static Certification fromCertification(CertSynopsis issuer,
|
|
||||||
String targetUserId,
|
|
||||||
CertSynopsis target,
|
|
||||||
PGPSignature signature) {
|
|
||||||
return fromSignature(issuer, targetUserId, target, signature);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a {@link Certification} object from a signature.
|
|
||||||
*
|
|
||||||
* @param issuer signature issuer certificate
|
|
||||||
* @param targetUserId optional signature target user ID
|
|
||||||
* @param target signature target certificate
|
|
||||||
* @param signature signature
|
|
||||||
* @return certification
|
|
||||||
*/
|
|
||||||
public static Certification fromSignature(CertSynopsis issuer,
|
|
||||||
String targetUserId,
|
|
||||||
CertSynopsis target,
|
|
||||||
PGPSignature signature) {
|
|
||||||
return new Certification(
|
|
||||||
issuer,
|
|
||||||
target,
|
|
||||||
targetUserId,
|
|
||||||
SignatureSubpacketsUtil.getSignatureCreationTime(signature).getTime(),
|
|
||||||
SignatureSubpacketsUtil.getSignatureExpirationTimeAsDate(signature),
|
|
||||||
SignatureSubpacketsUtil.isExportable(signature),
|
|
||||||
getTrustAmountFrom(signature),
|
|
||||||
getTrustDepthFrom(signature),
|
|
||||||
regexSetFrom(signature));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract the trust amount from the signature.
|
|
||||||
* If the signature has no {@link TrustSignature} subpacket, return a default value of 120.
|
|
||||||
*
|
|
||||||
* @param signature signature
|
|
||||||
* @return trust amount
|
|
||||||
*/
|
|
||||||
private static int getTrustAmountFrom(PGPSignature signature) {
|
|
||||||
TrustSignature packet = SignatureSubpacketsUtil.getTrustSignature(signature);
|
|
||||||
if (packet != null) {
|
|
||||||
return packet.getTrustAmount();
|
|
||||||
}
|
|
||||||
return 120; // default value
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract the trust depth from the signature.
|
|
||||||
* If the signature has no {@link TrustSignature} subpacket, return a default value of 0.
|
|
||||||
*
|
|
||||||
* @param signature signature
|
|
||||||
* @return trust depth
|
|
||||||
*/
|
|
||||||
private static Depth getTrustDepthFrom(PGPSignature signature) {
|
|
||||||
TrustSignature packet = SignatureSubpacketsUtil.getTrustSignature(signature);
|
|
||||||
if (packet != null) {
|
|
||||||
return Depth.auto(packet.getDepth());
|
|
||||||
}
|
|
||||||
return Depth.limited(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract a {@link RegexSet} from the signature.
|
|
||||||
* If the signature has no {@link RegularExpression} subpacket, the result will equate to a wildcard.
|
|
||||||
*
|
|
||||||
* @param signature signature
|
|
||||||
* @return regex set
|
|
||||||
*/
|
|
||||||
private static RegexSet regexSetFrom(PGPSignature signature) {
|
|
||||||
List<RegularExpression> regexList = SignatureSubpacketsUtil.getRegularExpressions(signature);
|
|
||||||
List<String> stringList = new ArrayList<>();
|
|
||||||
for (RegularExpression regex : regexList) {
|
|
||||||
stringList.add(regex.getRegex());
|
|
||||||
}
|
|
||||||
return RegexSet.fromExpressionList(stringList);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -37,6 +37,7 @@ import org.pgpainless.wot.dijkstra.sq.ReferenceTime;
|
||||||
import org.pgpainless.wot.sugar.IterableIterator;
|
import org.pgpainless.wot.sugar.IterableIterator;
|
||||||
import org.pgpainless.wot.sugar.PrefixedIterator;
|
import org.pgpainless.wot.sugar.PrefixedIterator;
|
||||||
import org.pgpainless.wot.sugar.Supplier;
|
import org.pgpainless.wot.sugar.Supplier;
|
||||||
|
import org.pgpainless.wot.util.CertificationFactory;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import pgp.cert_d.PGPCertificateDirectory;
|
import pgp.cert_d.PGPCertificateDirectory;
|
||||||
|
@ -301,7 +302,7 @@ public class WebOfTrust {
|
||||||
boolean valid = SignatureVerifier.verifySignatureOverUserId(userId, certification,
|
boolean valid = SignatureVerifier.verifySignatureOverUserId(userId, certification,
|
||||||
issuerSigningKey, targetPrimaryKey, policy, referenceTime.getTimestamp());
|
issuerSigningKey, targetPrimaryKey, policy, referenceTime.getTimestamp());
|
||||||
if (valid) {
|
if (valid) {
|
||||||
indexEdge(CertificationFactory.fromCertification(issuer, userId, target, certification));
|
indexEdge(CertificationFactory.fromCertification(issuer, target, userId, certification));
|
||||||
}
|
}
|
||||||
} catch (SignatureValidationException e) {
|
} catch (SignatureValidationException e) {
|
||||||
LOGGER.warn("Cannot verify signature for '" + userId + "' by " + issuerFingerprint + " on cert of " + target.getFingerprint(), e);
|
LOGGER.warn("Cannot verify signature for '" + userId + "' by " + issuerFingerprint + " on cert of " + target.getFingerprint(), e);
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package org.pgpainless.wot.util
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPSignature
|
||||||
|
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.CertSynopsis
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.Certification
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.Depth
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.RegexSet
|
||||||
|
import org.pgpainless.wot.dijkstra.sq.RegexSet.Companion.fromExpressionList
|
||||||
|
|
||||||
|
class CertificationFactory {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun fromDelegation(issuer: CertSynopsis,
|
||||||
|
target: CertSynopsis,
|
||||||
|
signature: PGPSignature): Certification {
|
||||||
|
return fromSignature(issuer, target, null, signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun fromCertification(issuer: CertSynopsis,
|
||||||
|
target: CertSynopsis,
|
||||||
|
targetUserId: String,
|
||||||
|
signature: PGPSignature): Certification {
|
||||||
|
return fromSignature(issuer, target, targetUserId, signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun fromSignature(issuer: CertSynopsis,
|
||||||
|
target: CertSynopsis,
|
||||||
|
targetUserId: String?,
|
||||||
|
signature: PGPSignature): Certification {
|
||||||
|
return Certification(
|
||||||
|
issuer,
|
||||||
|
target,
|
||||||
|
targetUserId,
|
||||||
|
SignatureSubpacketsUtil.getSignatureCreationTime(signature)!!.time,
|
||||||
|
SignatureSubpacketsUtil.getSignatureExpirationTimeAsDate(signature),
|
||||||
|
SignatureSubpacketsUtil.isExportable(signature),
|
||||||
|
getTrustAmountFrom(signature),
|
||||||
|
getTrustDepthFrom(signature),
|
||||||
|
regexSetFrom(signature))
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
private fun getTrustAmountFrom(signature: PGPSignature): Int {
|
||||||
|
val packet = SignatureSubpacketsUtil.getTrustSignature(signature)
|
||||||
|
return packet?.trustAmount ?: 120
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
private fun getTrustDepthFrom(signature: PGPSignature): Depth {
|
||||||
|
val packet = SignatureSubpacketsUtil.getTrustSignature(signature)
|
||||||
|
return if (packet != null) {
|
||||||
|
Depth.auto(packet.depth)
|
||||||
|
} else Depth.limited(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
private fun regexSetFrom(signature: PGPSignature): RegexSet {
|
||||||
|
val regexList = SignatureSubpacketsUtil.getRegularExpressions(signature)
|
||||||
|
val stringList: MutableList<String> = mutableListOf()
|
||||||
|
regexList.mapTo(stringList) { it.regex }
|
||||||
|
return fromExpressionList(stringList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue