Implement validate-userid command

This commit is contained in:
Paul Schaub 2024-09-19 16:56:25 +02:00
parent 122cd016a1
commit 4ed326a142
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
8 changed files with 216 additions and 17 deletions

View file

@ -60,18 +60,15 @@ interface SOP : SOPV {
/** Update a key's password. */
fun changeKeyPassword(): ChangeKeyPassword
/**
* Keep a secret key up-to-date.
*/
/** Keep a secret key up-to-date. */
fun updateKey(): UpdateKey
/**
* Merge OpenPGP certificates.
*/
/** Merge OpenPGP certificates. */
fun mergeCerts(): MergeCerts
/**
* Certify OpenPGP Certificate User-IDs.
*/
/** Certify OpenPGP Certificate User-IDs. */
fun certifyUserId(): CertifyUserId
/** Validate a UserID in an OpenPGP certificate. */
fun validateUserId(): ValidateUserId
}

View file

@ -338,9 +338,7 @@ abstract class SOPGPException : RuntimeException {
}
}
/**
* The primary key of a KEYS object is too weak or revoked.
*/
/** The primary key of a KEYS object is too weak or revoked. */
class PrimaryKeyBad : SOPGPException {
constructor() : super()
@ -353,13 +351,26 @@ abstract class SOPGPException : RuntimeException {
}
}
/**
* The CERTS object has no matching User ID.
*/
/** The CERTS object has no matching User ID. */
class CertUserIdNoMatch : SOPGPException {
constructor() : super()
constructor(errorMsg: String) : super(errorMsg)
val fingerprint: ByteArray?
constructor() : super() {
fingerprint = null
}
constructor(fingerprint: ByteArray) : super() {
this.fingerprint = fingerprint
}
constructor(errorMsg: String) : super(errorMsg) {
fingerprint = null
}
constructor(errorMsg: String, cause: Throwable) : super(errorMsg, cause) {
fingerprint = null
}
override fun getExitCode(): Int = EXIT_CODE

View file

@ -0,0 +1,78 @@
// SPDX-FileCopyrightText: 2024 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package sop.operation
import java.io.IOException
import java.io.InputStream
import sop.exception.SOPGPException
/** Subcommand to validate UserIDs on certificates. */
interface ValidateUserId {
/**
* If this is set, then the USERID is treated as an e-mail address, and matched only against the
* e-mail address part of each correctly bound User ID. The rest of each correctly bound User ID
* is ignored.
*
* @return this
*/
@Throws(SOPGPException.UnsupportedOption::class) fun addrSpecOnly(): ValidateUserId
/**
* Set the UserID to validate. To match only the email address, call [addrSpecOnly].
*
* @param userId UserID or email address
* @return this
*/
fun userId(userId: String): ValidateUserId
/**
* Add certificates, which act as authorities. The [userId] is only considered correctly bound,
* if it was bound by an authoritative certificate.
*
* @param certs authoritative certificates
* @return this
*/
@Throws(SOPGPException.BadData::class, IOException::class)
fun authorities(certs: InputStream): ValidateUserId
/**
* Add certificates, which act as authorities. The [userId] is only considered correctly bound,
* if it was bound by an authoritative certificate.
*
* @param certs authoritative certificates
* @return this
*/
@Throws(SOPGPException.BadData::class, IOException::class)
fun authorities(certs: ByteArray): ValidateUserId = authorities(certs.inputStream())
/**
* Add subject certificates, on which UserID bindings are validated.
*
* @param certs subject certificates
* @return true if all subject certificates have a correct binding to the UserID.
* @throws SOPGPException.BadData if the subject certificates are malformed
* @throws IOException if a parser exception happens
* @throws SOPGPException.CertUserIdNoMatch if any subject certificate does not have a correctly
* bound UserID that matches [userId].
*/
@Throws(
SOPGPException.BadData::class, IOException::class, SOPGPException.CertUserIdNoMatch::class)
fun subjects(certs: InputStream): Boolean
/**
* Add subject certificates, on which UserID bindings are validated.
*
* @param certs subject certificates
* @return true if all subject certificates have a correct binding to the UserID.
* @throws SOPGPException.BadData if the subject certificates are malformed
* @throws IOException if a parser exception happens
* @throws SOPGPException.CertUserIdNoMatch if any subject certificate does not have a correctly
* bound UserID that matches [userId].
*/
@Throws(
SOPGPException.BadData::class, IOException::class, SOPGPException.CertUserIdNoMatch::class)
fun subjects(certs: ByteArray): Boolean = subjects(certs.inputStream())
}